cleanup phase 7
This commit is contained in:
+7
-5
@@ -2,10 +2,12 @@
|
||||
|
||||
The entry point. Start here, follow one link, stop reading.
|
||||
|
||||
> **Built by the clarify chain**, phases 0–6, 2026-07-29 → 2026-08-02. The chain's own plan — inventory,
|
||||
> **Built by the clarify chain**, phases 0–7, 2026-07-29 → 2026-08-02. The chain's own plan — inventory,
|
||||
> contradiction log, phase files, and their progress table — is now history, kept at
|
||||
> [`archive/clarify-chain/`](../archive/clarify-chain/README.md). Phase 7 (skills & guardrails) is still
|
||||
> open.
|
||||
> [`archive/clarify-chain/`](../archive/clarify-chain/README.md). Phase 7 (skills & guardrails) is done:
|
||||
> three playbooks live in [`.claude/skills/`](../.claude/skills/); the anti-drift convention below is
|
||||
> enforced by review rather than a git hook (an MVP-stage call — see
|
||||
> [decisions.md](status/decisions.md)).
|
||||
|
||||
---
|
||||
|
||||
@@ -55,5 +57,5 @@ Two documents stay outside this tree on purpose:
|
||||
it would defeat that.
|
||||
4. **English throughout**, including in files that describe Persian UI copy.
|
||||
|
||||
The full convention is in [docs/rules/documentation.md](rules/documentation.md), to be enforced by a
|
||||
pre-commit warning (phase 7).
|
||||
The full convention is in [docs/rules/documentation.md](rules/documentation.md) — enforced by review,
|
||||
not tooling (an MVP-stage call; see [git-and-gates.md](rules/shared/git-and-gates.md)).
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Every configuration key on both sides of the seam, plus docker and the OTP relay, with where it is set and
|
||||
who reads it.
|
||||
|
||||
> Last verified: 2026-07-30 against commit `d3ec723`. Built by **mechanically enumerating** every leaf key
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`. Built by **mechanically enumerating** every leaf key
|
||||
> in both `appsettings*.json`, every `environment:` entry in `docker-compose.yml`, every assignment in the
|
||||
> three `client/.env*` files and `telegram-otp-bot/.env.example`, and every `process.env.*` read under
|
||||
> `client/src/` — then diffing the sets. The gaps that diff found are in
|
||||
@@ -79,7 +79,7 @@ Every one has a working default, so nothing is broken — but none is discoverab
|
||||
| --- | --- | --- | --- |
|
||||
| `OpenTelemetry:Otlp:Endpoint` | `SetupOpenTelemetry` | **OTLP export is not wired at all.** Prometheus `/metrics` still works | Opt-in by design, so no exporter spams an absent collector |
|
||||
| `Search:Backend` | `AddPersistenceServices` | `SqlNurseSearch` | Any value other than `sql`/empty **throws at startup** — Elasticsearch is deferred and fails loudly |
|
||||
| `Seed:AdminUsername` / `:AdminPassword` / `:AdminEmail` | `SeedDataBase` | no break-glass admin is seeded | The hardcoded `admin`/`qw123321` was removed in refinement-phase-5 and the pre-commit hook blocks its return |
|
||||
| `Seed:AdminUsername` / `:AdminPassword` / `:AdminEmail` | `SeedDataBase` | no break-glass admin is seeded | The hardcoded `admin`/`qw123321` was removed in refinement-phase-5 |
|
||||
| `Seams:<rail>:Provider` (×11) | `AddCrossCuttingSeams` | **`mock`** | The seam selectors, below |
|
||||
|
||||
### The seam selectors
|
||||
@@ -252,13 +252,11 @@ places where the config is not discoverable from the config files.
|
||||
### The placeholder's name
|
||||
|
||||
`SET_VIA_USER_SECRETS_OR_ENV` names a store that no longer exists (contradiction **C-2**). The *behaviour*
|
||||
is correct — it is a sentinel that `StartupSecretsGuard` and the pre-commit hook both reject — but the name
|
||||
instructs a reader to use a removed mechanism.
|
||||
is correct — it is a sentinel that `StartupSecretsGuard` rejects — but the name instructs a reader to use a
|
||||
removed mechanism.
|
||||
|
||||
It was **not renamed in this phase**, because the string is load-bearing in seven live files:
|
||||
`appsettings.json` (×6), `StartupSecretsGuard.cs`, `.githooks/pre-commit`, `.githooks/README.md`,
|
||||
`Baya.Test.Api/StartupSecretsGuardTests.cs` (×2), `docs/rules/shared/git-and-gates.md` and
|
||||
`docs/rules/server/structure.md`. Renaming it is a server-code + git-hook + test change requiring
|
||||
`dotnet build` and `dotnet test` to prove the gate still fires — out of scope for a documentation phase.
|
||||
**This section is the authoritative statement of the mechanism**; the rename is filed for Phase 4 with that
|
||||
exact seven-file worklist.
|
||||
It was **not renamed in this phase**, because the string is load-bearing in several live files:
|
||||
`appsettings.json` (×6), `StartupSecretsGuard.cs`, `Baya.Test.Api/StartupSecretsGuardTests.cs` (×2), and
|
||||
`docs/rules/server/structure.md`. Renaming it is a server-code + test change requiring `dotnet build` and
|
||||
`dotnet test` to prove the gate still fires — out of scope for a documentation phase. **This section is the
|
||||
authoritative statement of the mechanism**; the rename is filed for Phase 4 with that worklist.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Deferred — recorded, not re-decided
|
||||
|
||||
> Last verified: 2026-08-02 against commit `cd8144e`. Populated by phase 5 of the
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`. Populated by phase 5 of the
|
||||
> [documentation clean-up chain](../../archive/clarify-chain/README.md).
|
||||
|
||||
**51 items** carry deferred status in [backlog.md](../status/backlog.md): the 43 in its dedicated
|
||||
@@ -96,7 +96,7 @@ Correct for a single instance / MVP load; each has a concrete, measurable trigge
|
||||
|
||||
| Item | Why deferred | Pull-trigger | Size | Decided |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [BL-219](../status/backlog.md#minor-115) — rename the `SET_VIA_USER_SECRETS_OR_ENV` placeholder sentinel | The name is a load-bearing sentinel `StartupSecretsGuard` and the pre-commit hook both check for; renaming touches 7 files for a cosmetic gain | None — cleanup-of-convenience | S | phase 2 (`open-contradictions.md` C-2) |
|
||||
| [BL-219](../status/backlog.md#minor-115) — rename the `SET_VIA_USER_SECRETS_OR_ENV` placeholder sentinel | The name is a load-bearing sentinel `StartupSecretsGuard` checks for; renaming touches several files for a cosmetic gain | None — cleanup-of-convenience | S | phase 2 (`open-contradictions.md` C-2) |
|
||||
| [BL-250](../status/backlog.md#deferred-43) — the ESLint unused-vars gate is a repo-wide no-op | Config patches an export path that doesn't carry the rule; fixing it is a dedicated infra task, not a drive-by | A dedicated infra task | S | frontend-phase-13 follow-up |
|
||||
| [BL-253](../status/backlog.md#deferred-43) — payment-webhook confirm path uses two DB commits instead of one transaction | Kept safe today via idempotency + a forward-only guard; a real fix needs `IUnitOfWork` to grow a transaction scope first | `IUnitOfWork` grows a transaction scope | M | backend-phase-10 follow-up |
|
||||
| [BL-255](../status/backlog.md#deferred-43) — `Bookings`/`Invoices.partner_center_id` have no DB-level FK | Only `nurse_profiles.partner_center_id` got one, per that phase's own Definition of Done | A data-integrity pass on partner-center columns | S | backend-phase 11/15 follow-ups |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
How this repository keeps its own docs from lying. Read before writing or editing any `.md`.
|
||||
|
||||
> Last verified: 2026-07-30 against commit `d3ec723`.
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`.
|
||||
|
||||
---
|
||||
|
||||
@@ -43,8 +43,8 @@ regenerate — never hand-edit the HTML. If you add or rename a `.md`, update th
|
||||
|
||||
## 2. What to update when X changes
|
||||
|
||||
This is the anti-drift contract. Each row is enforced by review, and (from phase 7) warned about by the
|
||||
pre-commit hook.
|
||||
This is the anti-drift contract. Each row is enforced by review — there is no pre-commit tooling behind
|
||||
it (a deliberate MVP-stage call; see [git-and-gates.md](shared/git-and-gates.md)).
|
||||
|
||||
| When you change… | Update, in the same change |
|
||||
| --- | --- |
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
What must never be broken, and nothing else.
|
||||
|
||||
> Last verified: 2026-07-30 against commit `d3ec723`.
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`.
|
||||
|
||||
---
|
||||
|
||||
@@ -14,7 +14,7 @@ Three tiers, and a rule lives in exactly one of them.
|
||||
| --- | --- | --- | --- |
|
||||
| **Hard rules** | [root CLAUDE.md](../../CLAUDE.md) · [client/CLAUDE.md](../../client/CLAUDE.md) · [server/CLAUDE.md](../../server/CLAUDE.md) | Constraints whose violation breaks the build, the gate, or a business invariant. Imperative, no explanation. | ≤250 lines each |
|
||||
| **Reference** | `docs/rules/{shared,client,server}/*.md` — here | The *how* and the *why*. Read on demand when you are working in that area. | ≤400 lines per file |
|
||||
| **Procedure** | `.claude/skills/` | Step-by-step playbooks for recurring tasks. The [frontend-designer](../../.claude/skills/frontend-designer/SKILL.md) skill is the design playbook. | — |
|
||||
| **Procedure** | `.claude/skills/` | Step-by-step playbooks for recurring tasks: [frontend-designer](../../.claude/skills/frontend-designer/SKILL.md) (design), [backend-feature](../../.claude/skills/backend-feature/SKILL.md) (adding a server feature), [flow-testing](../../.claude/skills/flow-testing/SKILL.md) (walking a flow end to end). | — |
|
||||
|
||||
The test: **a rule that only matters once you are already editing theme code is reference.** A rule like
|
||||
"never change `Seams:FieldEncryption:Key`" is hard — it belongs inline where nobody can miss it.
|
||||
@@ -31,7 +31,7 @@ touching. Not both trees, not every file.
|
||||
| File | Covers |
|
||||
| --- | --- |
|
||||
| [shared/naming.md](shared/naming.md) | `Baya*` vs `balinyaar-client`, the `@/*` alias, file and directory conventions |
|
||||
| [shared/git-and-gates.md](shared/git-and-gates.md) | Branches, commits, the pre-commit secret scan, what "done" means per project |
|
||||
| [shared/git-and-gates.md](shared/git-and-gates.md) | Branches, commits, what "done" means per project |
|
||||
| [shared/code-quality.md](shared/code-quality.md) | No dead code, comment the *why*, no starter scaffolding, the seam rule for mocks |
|
||||
|
||||
### Client — `client/`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Auth, JWE, sessions, field encryption, tenancy, and the two-stage clinical disclosure rule.
|
||||
|
||||
> Last verified: 2026-07-30 against commit `d3ec723`.
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`.
|
||||
|
||||
---
|
||||
|
||||
@@ -101,8 +101,8 @@ The full vocabulary is in `Domain/Entities/User/RoleNames`.
|
||||
|
||||
- **`SeedDataBase` always seeds the roles**, and seeds a **bootstrap admin only when
|
||||
`Seed:AdminUsername`/`Seed:AdminPassword` are configured** — break-glass only. There is no committed
|
||||
`admin`/`qw123321` any more (the pre-commit hook rejects that string outright). Day-to-day admins come from
|
||||
the phone-OTP demo seeds or are provisioned out-of-band.
|
||||
`admin`/`qw123321` any more. Day-to-day admins come from the phone-OTP demo seeds or are provisioned
|
||||
out-of-band.
|
||||
- **`customer` and `nurse` are self-selectable** via `POST me/select_role` — audited (`granted_by`,
|
||||
`granted_at`), idempotent, and **both can be held** by one user (a dual session moves freely between the
|
||||
family and nurse apps).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
What must pass before work is done, and what the repo refuses to let you commit.
|
||||
|
||||
> Last verified: 2026-07-30 against commit `d3ec723`.
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`.
|
||||
|
||||
---
|
||||
|
||||
@@ -63,40 +63,15 @@ A change that doesn't pass its own gate is **not done**, regardless of how compl
|
||||
|
||||
---
|
||||
|
||||
## 3. The pre-commit secret scan
|
||||
## 3. No pre-commit secret scan (for now)
|
||||
|
||||
Repo-managed hooks live in `.githooks/` (in version control, unlike `.git/hooks`). **Enable them once per
|
||||
clone:**
|
||||
|
||||
```bash
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
|
||||
`pre-commit` is a fast, dependency-free backstop against a credential leaking into a file that shouldn't
|
||||
hold one. It scans **only staged additions**, so it is quick. It rejects a commit that stages:
|
||||
|
||||
- the retired hardcoded admin password `qw123321`, anywhere;
|
||||
- private-key material or an AWS access-key id, anywhere;
|
||||
- the deployment's SQL Server host `87.107.152.16` **outside the declared config files**;
|
||||
- a **real** connection-string password in any `appsettings*.json` **outside the declared config files**
|
||||
(elsewhere only the `SET_VIA_USER_SECRETS_OR_ENV` placeholder is allowed).
|
||||
|
||||
### The declared-config allow-list
|
||||
|
||||
The pre-launch demo deployment configures itself from committed files rather than a secret store (see
|
||||
[`DEPLOY.md`](../../../DEPLOY.md)), so a short allow-list is exempt from the last two checks:
|
||||
|
||||
`appsettings.Development.json` · `docker-compose.yml` · `telegram-otp-bot/.env.example` · `DEPLOY.md`
|
||||
|
||||
It is maintained in the `declared_config` function in the hook, and it is **the honest record of where
|
||||
this repo's secrets are**. **Shrink it, never grow it.** Once real users exist, those values must be
|
||||
rotated and moved out of git.
|
||||
|
||||
### Limits
|
||||
|
||||
This is the local first line of defence, **not** a replacement for a full scanner (gitleaks, trufflehog)
|
||||
in CI. Bypass a false positive with `git commit --no-verify` — sparingly, and only when you are certain
|
||||
the flagged line is not a secret.
|
||||
There is no git hook enforcing anything in this repo — `.githooks/` was removed in phase 7 as an
|
||||
MVP-stage call: this is a pre-launch demo project and the mechanical backstop wasn't worth the overhead
|
||||
yet. The underlying rule is unchanged — **never commit a real secret** — it's just unenforced by tooling.
|
||||
Root [CLAUDE.md](../../../CLAUDE.md) §6 already documents the repo's actual trade: config lives in
|
||||
committed files, including live credentials, until real users exist (see
|
||||
[DEPLOY.md](../../../DEPLOY.md) "Going to Production" for the rotation step that unblocks that). Revisit
|
||||
adding a hook — or a CI scanner (gitleaks, trufflehog) — if that trade changes before this one does.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Backlog — every open item, triaged
|
||||
|
||||
> Last verified: 2026-08-02 against commit `b876490`.
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`.
|
||||
|
||||
Reconciled from five ledgers — [hardening/issues.md](../../archive/post-phase/hardening/issues.md) (18 items),
|
||||
[for-backend.md](../../archive/build-chain/working-context/frontend/requests/for-backend.md) (67 REQs), 53
|
||||
@@ -251,7 +251,7 @@ log is in [decisions.md](decisions.md). The business-area overlay is in [impleme
|
||||
| BL-216 | contract | No typed address/variant snapshot objects — `BookingDetailDto` still carries opaque JSON strings, forcing the client's defensive multi-key parse in three separate places. | REQ-045, ui-phase-6 follow-up 2, ui-phase-7 follow-up 2 | open | booking-lifecycle-evv, checkout-and-payment |
|
||||
| BL-217 | client | Two admin-only multi-field dialogs (`GrantRoleDialog` in `admin/roles`, `PreviewBatchDialog` in `admin/payouts`) still hold raw `useState` instead of react-hook-form — the only genuine residue of the app-wide form migration. | iteration-2 #7 | open | admin-backoffice |
|
||||
| BL-218 | client | `H-01` residue: the auth-gate root-cause fix landed, but `client/middleware.ts` was never migrated to Next 16's `src/proxy.ts` as the original fix prescribed, and `outputFileTracingRoot` was never added alongside `turbopack.root` — a production build may still warn from the stray root-level lockfile. | H-01 | open | auth-login-otp |
|
||||
| BL-219 | docs | Rename the `SET_VIA_USER_SECRETS_OR_ENV` placeholder sentinel now that `user-secrets` is confirmedly removed — filed by phase 2 with an exact 7-file worklist (`appsettings.*.json`, `StartupSecretsGuard.PlaceholderMarkers`, `.githooks/pre-commit`, `.githooks/README.md`, `StartupSecretsGuardTests.cs`, `docs/rules/shared/git-and-gates.md`, `docs/rules/server/structure.md`). Optional cleanup, not urgent — the name is a load-bearing sentinel and the mechanism is already documented correctly elsewhere. | C-2 (open-contradictions.md) | deferred (trigger: none — cleanup-of-convenience) | — |
|
||||
| BL-219 | docs | Rename the `SET_VIA_USER_SECRETS_OR_ENV` placeholder sentinel now that `user-secrets` is confirmedly removed — filed by phase 2 with a worklist (`appsettings.*.json`, `StartupSecretsGuard.PlaceholderMarkers`, `StartupSecretsGuardTests.cs`, `docs/rules/server/structure.md`); the two `.githooks/*` files in the original worklist no longer exist (phase 7 dropped the pre-commit hook — see [decisions.md](decisions.md)). Optional cleanup, not urgent — the name is a load-bearing sentinel and the mechanism is already documented correctly elsewhere. | C-2 (open-contradictions.md) | deferred (trigger: none — cleanup-of-convenience) | — |
|
||||
|
||||
## Deferred (43)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Decisions — the distilled engineering decision log
|
||||
|
||||
> Last verified: 2026-08-02 against commit `b876490`.
|
||||
> Last verified: 2026-08-02 against commit `51e86a1`.
|
||||
|
||||
Non-obvious decisions with a reason, extracted from `dev/`'s ~3MB of build history so they survive
|
||||
`dev/`'s move to `archive/` in phase 6. **`product/` wins for business rules** — this file is for
|
||||
@@ -91,10 +91,20 @@ Decided ui-phase-13, chosen specifically so `/` stays a stable, shareable, index
|
||||
## Engineering decisions
|
||||
|
||||
**Phase 2 → Phase 4 handoff, "the rename is filed."** The placeholder secret sentinel
|
||||
`SET_VIA_USER_SECRETS_OR_ENV` keeps its name — renaming it needs a server-code + git-hook + test change that
|
||||
is out of a documentation phase's scope, and the string is load-bearing across 7 live files. Filed as
|
||||
`SET_VIA_USER_SECRETS_OR_ENV` keeps its name — renaming it needs a server-code + test change that is out of
|
||||
a documentation phase's scope, and the string is load-bearing across several live files. Filed as
|
||||
[backlog.md](backlog.md) BL-219, deferred (cleanup-of-convenience, no urgency).
|
||||
|
||||
**Phase 7 dropped the pre-commit secret-scan hook — MVP stage, no need for it yet.** `.githooks/pre-commit`
|
||||
(the `qw123321`/private-key/AWS-key/SQL-host/connection-string scan) and `.githooks/README.md` were deleted
|
||||
outright, along with every doc reference to them (root `CLAUDE.md`'s repo-layout table and quick start,
|
||||
[git-and-gates.md](../rules/shared/git-and-gates.md), [documentation.md](../rules/documentation.md),
|
||||
[identity.md](../rules/server/identity.md), [config-matrix.md](../integration/config-matrix.md),
|
||||
[DEPLOY.md](../../DEPLOY.md)). The underlying trade this repo already made — committed live credentials,
|
||||
config in files not a secret store (root [CLAUDE.md](../../CLAUDE.md) §6) — is unchanged; this only removes
|
||||
the local mechanical backstop against a *new* leak. Revisit before onboarding real users, alongside the
|
||||
credential rotation already required by that trade.
|
||||
|
||||
**Hardening ledger re-verification (C-10) confirms the ledger was right to distrust its own checkboxes.**
|
||||
All 18 hardening items were re-traced against `b876490` rather than trusted as-filed: 3 were already fixed
|
||||
(client-only, landed in the "manual improvement" commits well before this doc chain started), 4 are
|
||||
|
||||
Reference in New Issue
Block a user