making the mess clean plans added

This commit is contained in:
hamid
2026-07-29 22:46:38 +03:30
parent 96b57eb1b8
commit c99e3f4a6e
9 changed files with 1365 additions and 0 deletions
+149
View File
@@ -0,0 +1,149 @@
# Phase 2 — Integration & dependency
**Depends on:** Phase 0 · **Can run in parallel with:** Phase 1 · **Blocks:** Phase 3 · **Size:** one session
## Goal
Make the client↔server dependency a **thing you can read in one place**, and re-sync the contract
layer with the code it stopped tracking on 2026-07-13.
Right now the seam is real but scattered: envelope shape and casing in one contract doc, cookies and
refresh in `client/CLAUDE.md`, CORS in a refinement report, `NEXT_PUBLIC_API_URL` in `.env` files,
the container topology in `DEPLOY.md` and `docker-compose.yml`, and the OTP relay in its own README.
Nobody can answer "what does the client actually need from the server?" without reading six files.
---
## Inputs
- `docs/integration/openapi/swagger.v1.json` — the **fresh** snapshot from Phase 0, plus the
added/removed endpoint diff Phase 0 wrote into `docs/_plan/open-contradictions.md`.
- [dev/contracts/](../../dev/contracts/) — 18 domain files + 2 convention files + the stale snapshot.
- [dev/shared-working-context/frontend/requests/for-backend.md](../../dev/shared-working-context/frontend/requests/for-backend.md) —
67 REQs; many *are* contract amendments that were delivered but never folded back into the domain docs.
- [dev/shared-working-context/reports/mocks-registry.md](../../dev/shared-working-context/reports/mocks-registry.md) — which seams are mocked.
- [DEPLOY.md](../../DEPLOY.md) · [docker-compose.yml](../../docker-compose.yml) · [deploy/Caddyfile](../../deploy/Caddyfile)
- [telegram-otp-bot/README.md](../../telegram-otp-bot/README.md) + [INTEGRATION-PROMPT.md](../../telegram-otp-bot/INTEGRATION-PROMPT.md)
- `client/.env.development`, `client/.env.production`, `server/src/API/Baya.Web.Api/appsettings*.json`
- Code, for the seam itself: `client/src/lib/api/`, `client/src/services/*/`, the server's
`ApiResult` envelope, CORS setup, and auth middleware.
## Outputs
```
docs/integration/
index.md THE seam, one page: what crosses the wire and what each side owes the other
api-contract.md envelope, casing, pagination, errors, idempotency, auth headers/cookies
domains/ 22 files, one per service domain — refreshed against the live swagger
openapi/
swagger.v1.json (from Phase 0)
README.md how to regenerate, when it was last taken, endpoint count
config-matrix.md every env var / appsettings key, both projects + docker + the bot
topology.md the runtime dependency graph
```
Also updated: [DEPLOY.md](../../DEPLOY.md) — fix the stale `user-secrets` reference and link to
`docs/integration/topology.md`. It stays at root and stays the deploy *procedure*.
---
## Steps
### 1. Write `index.md` first — the seam on one page
Before touching the per-domain detail, answer these in one page:
- **Transport**: HTTP/JSON over `NEXT_PUBLIC_API_URL`; where gRPC exists and whether it is used.
- **The envelope**: `ApiResult``{ isSuccess, statusCode, message, requestId, data }`, payload
always under `data`, `requestId` is a W3C trace id (refinement-phase-9). Client unwraps in
`clientFetch`/`unwrap()`.
- **Casing**: JSON bodies camelCase; URL segments snake_case. (REQ-001 settled this — confirm against
the live swagger, don't trust the doc.)
- **Pagination**: `{ items, total, page, pageSize }`; the server binds `pageSize` case-insensitively
(REQ-010).
- **Errors**: status codes, machine-readable error codes (REQ-003), what the client does with 401 /
403 / 5xx / network.
- **Auth**: the cookie set, JWE opacity to the client, silent refresh, session rotation and
reuse-detection, `/me` and `me/select_role`, role hydration.
- **Idempotency**: which endpoints require `Idempotency-Key` and what the client generates.
- **Money**: IRR on the wire, Toman at the UI boundary — link to `docs/rules/shared/`.
- **What the server owes the client** and **what the client owes the server**, as two short lists.
### 2. Refresh the 22 domain contracts against the live swagger
For each domain, compare the contract doc against `swagger.v1.json` and the handler code. Mark each
endpoint: `matches` · `drifted (describe)` · `undocumented (in code, not in contract)` ·
`phantom (in contract, not in code)`.
Fold in the delivered REQs — 17+ were delivered in refinement-phase-3 and amended shapes that the
domain docs still describe the old way. **The domain doc is the thing that should be true; the REQ
ledger is a change log.** After this phase, a reader should never need to read the REQ file to know
the current shape.
Note the domain-file cleanup: there is both a `messaging.md` (851 B stub) and a
`messaging-notifications-admin.md` (10.6 KB) — merge. Align the file set with the client's 22
`services/` domains so the mapping is one-to-one where it can be.
Anything you cannot verify from swagger or code: mark `UNVERIFIED:` and add a row to Phase 4's input
list. Do not guess a shape.
### 3. Write `config-matrix.md`
One table: **key · where it's set (appsettings / .env / docker-compose / Caddyfile) · consumed by ·
required? · default · notes**. Cover at minimum:
- `NEXT_PUBLIC_API_URL`, `NEXT_PUBLIC_NESHAN_KEY`, and the rest of the client's `NEXT_PUBLIC_*`
- `IdentitySettings:SecretKey` / `:Encryptkey`
- `Seams:FieldEncryption:Key` / `:HashKey`**flag as load-bearing and immutable**
- the connection strings (app DB + log DB), and that the DB is remote and **not** containerised
- `OpenTelemetry:Otlp:Endpoint`, the health endpoints (`/healthz/live`, `/healthz/ready`)
- the seam selectors that choose real vendor adapters vs mocks (refinement-phase-8)
- the Telegram OTP bot's token/chat config
- CORS origins, and the Caddy hostnames `balinyaar.ir` / `api.balinyaar.ir`
State plainly, once, that config lives in files and `dotnet user-secrets` is not used — and that this
is a deliberate pre-launch trade with live credentials in git (link to `DEPLOY.md` "Going to
Production" and to Phase 5's `pre-launch.md`).
### 4. Write `topology.md`
The runtime dependency graph — a mermaid diagram plus a short table:
```
browser -> Caddy (caddy_net) -> client container (Next.js) -> server container (ASP.NET)
-> server container -> remote SQL Server (not containerised)
-> telegram-otp-bot (OTP relay)
-> object storage / external rails (per seam config)
```
For each edge: what flows over it, what breaks if it is down, and where it is configured. This is the
"dependency between projects, documented in a proper place" deliverable.
### 5. Point the old locations at the new one
`dev/contracts/README.md` gets a one-line "moved to `docs/integration/`" banner (Phase 6 archives the
folder; until then, don't leave two live copies competing).
---
## Verification
- [ ] Every endpoint in `swagger.v1.json` appears in exactly one `docs/integration/domains/*.md`, or
is listed in that file's "undocumented, intentionally" section with a reason.
- [ ] No `phantom` endpoints remain undeclared — each is either removed from the doc or listed as
"planned, not built" with a backlog reference for Phase 4.
- [ ] `config-matrix.md` accounts for every key in `appsettings.Production.json`,
`docker-compose.yml`, and both `.env` files — diff mechanically, don't eyeball.
- [ ] `DEPLOY.md` no longer instructs anyone to use `user-secrets`.
- [ ] `index.md` fits on one screen-and-a-half and answers the seam question without a single click.
## Definition of done
A frontend agent can build against the API by reading `docs/integration/index.md` plus one domain
file, and a deploy question is answered by `topology.md` + `config-matrix.md` without opening
`docker-compose.yml`.
## Handoff
_(filled in by the agent that runs this phase — especially: the drift list, since Phase 4 turns the
`phantom` and `drifted` rows into backlog items)_