|
|
# 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 `015`–`018` (`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.
|