You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sims-hq/docs/KNOWN-ISSUES.md

6.2 KiB

Known issues & pending work — HQ Ops Console

Last updated: 2026-07-21 · after the D38 Client Detail redesign landed on main.

This is the honest list of what is not done, what is not verified, and what needs a human decision. Everything here was found by review; none of it is speculative. Ordered by consequence.


1. SECURITY — production Postgres password is in the repo and on the remote

Status: open. Owner decision parked.

The production Postgres connection string (with password) is hardcoded in apps/hq/src/db-pg.ts (HARDCODED_DATABASE_URL), and it is present on the origin remote (gitea.simssoftware.in). It was introduced in commit 45cfb83 (then in server.ts) and later moved into db-pg.ts; both states have been pushed. A duplicate copy that had been added to apps/hq/test/db-resolve.test.ts was removed in 6f50799.

Why it matters: under D31/D32 every client portal/gateway password, module secret and client DB password is stored in the clear. This one credential is therefore the key to all of them.

The only real remediation is to ROTATE the Postgres password on the box. Editing or reverting the file does not remove it from history, and history is already distributed.

Secondary (after rotation), pick one:

  • move the value to a deploy-time env var / secrets file and revert the code to a placeholder — note the AWS box currently has no .env, so this requires an ops change there first; or
  • accept the hardcoded pattern and treat repo read access as equivalent to production DB access.

2. BLOCKED — the real data has not been touched yet

Status: blocked on the local Postgres password.

The following were prepared and tested but never run against the real database, because the local PostgreSQL 17 instance's credentials are not available to this session:

  • Scrub of the "tecnostac" name from the real DB. The earlier scrub ran against data/hq.db — a near-empty leftover SQLite file (2 clients), not the live Postgres. The live database very likely still contains the old company name, owner login and audit snapshots.
  • The onboarding template migration over ~167 real projects (apps/hq/scripts/apply-onboarding-pipeline.ts).
  • Redeploy — the server currently running on :5182 predates all of this work, so the console in use does not yet reflect the redesign.

Until this runs, the redesign is code-complete but not live.


3. NOT VERIFIED — things nobody has actually observed working

  • The Postgres migrations have never been executed against a real Postgres instance. Migrations 015018 (project_milestone.payment_id, .document_id, ticket.type, client_module.created_at) are statically reviewed and mirrored from the SQLite schema, but the test suite's Postgres path is skipped without HQ_PG_TEST_URL. 5 tests are skipped for this reason.
  • The Payments tab was not screenshotted at 768px, nor at 1440px in dark theme. The rest of the redesign was verified in a real browser at 375 / 768 / 1440 × light + dark.

4. DEFERRED TO ROADMAP (owner call)

  • gmail-connect.ts and the APEX importer CLI use an unconditional openDb() and therefore can never reach Postgres — they will always target SQLite. gmail-connect.ts is a documented production runbook step. Deferred because that area is not in active use yet.

5. BEHAVIOUR CHANGES worth knowing

  • Tables now scroll inside their own box, bounded at 70vh, with a sticky header. Previously the whole page scrolled and (at desktop widths) tables silently dropped their rightmost columns. Short tables are unchanged; long tables scroll internally. This affects every table screen.
  • Adding a module no longer asks for credentials. They are captured when the "Account creation" onboarding step is ticked, and remain editable from the module's Access panel.
  • The coarse module status is now driven by the status line. Ticking Installation / Training / Go-live advances it automatically; it never downgrades.

6. MINOR BACKLOG (real, non-blocking)

From the review passes, not yet fixed:

  • bulkSetMilestone couples to a literal error string ('Milestone not found on this project'); rewording that throw would turn a skip into a whole-batch abort. Prefer a sentinel/typed error.
  • project.stall_days (the setting, as opposed to the ?days= query param) is not range-validated; an absurd value produces a 400 rather than a crash, but it should be clamped for symmetry.
  • Whitespace-only ?days= input is treated as 0 rather than rejected.
  • Two /client-modules/:id/milestones handlers await outside their try block (not reachable with attacker-controlled input, and not a regression).
  • DraftInput.source is a free-form string taken from the request body — any authenticated user can tag a document module_renewal or bulk_sms_topup. Provenance label only, no money impact; a union type would give a compile-time guard.
  • ClientDetail still calls getModules / getTicketTypes on load in some paths; only the duplicate fetch was removed.
  • Chip/button tap targets are ~23px high on mobile — below the comfortable minimum, but this is a pre-existing system-wide convention, not something this work introduced.

7. REPO HYGIENE

  • .claude-flow/ is tracked in git (6 files of agent daemon state/metrics). It is scratch and should be removed from tracking and added to .gitignore.
  • apps/hq/scripts/migrate-sqlite-to-pg.ts and migrate-pg-to-pg.ts are untracked working files.
  • apps/hq/schema.sql is a stale generated snapshot (dated 2026-07-10) that no longer matches db.ts, which is the source of truth. It does not even contain project_milestone.

How this list was produced

The redesign went through per-task reviews during the build, then a whole-branch review, a four-lens audit swarm, a real-browser responsive red-team, and a review of the fix commits themselves. Each layer found defects the previous one could not — including a payment feature that was dead code, a deploy script that would have written to a phantom database while reporting success, and a route any authenticated user could crash the server with. Those are fixed. The items above are what remains.