add build development phases

This commit is contained in:
hamid
2026-06-28 21:59:59 +03:30
parent 1df3cd9f64
commit 53a40dc51d
52 changed files with 12379 additions and 0 deletions
+204
View File
@@ -0,0 +1,204 @@
# Agent Operating Rules — read this before every phase
> **You are an autonomous engineer working one phase of the Balinyaar build.** This file is the
> contract for *how* you work. Every `backend-phase-N.md` / `frontend-phase-N-bM.md` links here and
> assumes you have read it. Do not skip it. Do not be lazy. Build production-quality, scalable,
> maintainable code — not a demo.
---
## 0. The golden behaviours
1. **No laziness, ever.** Implement the whole phase scope. No `// TODO: implement later`, no stubbed
handlers that return fake data *unless the phase explicitly says "mock this behind a seam"*, no
"left as an exercise". If you mock something, you mock it **behind a dependency-injected interface**
and you record it in the mock registry (§7) — that is the *only* sanctioned form of "not real yet".
2. **Read before you write.** Complete the **Required reading** list in your phase file *first*. The
business rules are decisions, not guesses — the product docs are the source of truth. Inferring a
rule from code instead of reading the doc is a defect.
3. **Don't duplicate prior work.** Each phase lists **"What already exists"** with links to the prior
phases that built it. Extend it; never re-create it. If you need to change something a prior phase
built, change it in place and note it in your report.
4. **Stay in your project.** Backend phases touch `server/` (+ `dev/contracts`, `dev/shared-working-context/backend`). Frontend phases touch `client/` (+ `dev/shared-working-context/frontend`). Do **not** edit the other side's app code — coordinate through contracts and the handoff (§6).
5. **Match the surrounding style.** Mirror existing patterns; introduce no new ones without reason.
The per-project `CLAUDE.md` (and server `CONVENTIONS.md`) are non-negotiable — follow them exactly.
6. **Leave the tree green.** Your phase is not done until the project's own quality gate passes
(§4) and the Definition of Done ([definition-of-done.md](definition-of-done.md)) is fully met.
7. **Think about the future.** Every decision should consider scalability and maintenance: indexing,
pagination, caching, idempotency, re-render cost, bundle size, the seam that lets a mock become real.
See the conventions checklists ([backend](backend-conventions-checklist.md) ·
[frontend](frontend-conventions-checklist.md)).
---
## 1. The canonical sources of truth (know where each rule lives)
| You need… | Read |
| --- | --- |
| Repo-wide rules, two-project layout | root [`CLAUDE.md`](../../../CLAUDE.md) |
| Backend engineering rules | [`server/CLAUDE.md`](../../../server/CLAUDE.md) + [`server/CONVENTIONS.md`](../../../server/CONVENTIONS.md) |
| Frontend engineering rules | [`client/CLAUDE.md`](../../../client/CLAUDE.md) |
| Frontend design/brand rules | the **frontend-designer** skill (invoke it for any UI work) |
| Product / business / data-model / payments truth | [`product/`](../../../product/) (start at `product/index.md`) |
| The whole build plan + order | [`dev/phases/README.md`](../README.md) |
| Cross-project API/flow contracts | [`dev/contracts/`](../../contracts/README.md) |
| What the other agent has handed you | [`dev/shared-working-context/`](../../shared-working-context/README.md) |
**Precedence when two sources seem to conflict:** product docs (business truth) → the relevant
`CLAUDE.md`/`CONVENTIONS.md` (engineering truth) → this file → the phase file's specifics. If a real
conflict remains, do the safe thing, implement it, and flag it in your report — never silently guess
on money, auth, tenancy, or clinical-data rules.
---
## 2. Phase lifecycle (do these in order)
1. **Orient.** Read this file, your phase file end-to-end, and the **Required reading** it lists.
Skim the prior-phase reports in `dev/shared-working-context/reports/` for what changed recently.
2. **Plan.** Restate the scope to yourself; list the entities/endpoints/screens you will build and the
order. Identify every external dependency you must mock and the seam it sits behind.
3. **Build.** Implement the full scope following the project conventions and the checklists. Wire mocks
behind DI. Keep commits/changes coherent.
4. **Self-verify.** Run the project's quality gate (§4) and the phase's **"How to test"** steps. Fix
everything. Re-read your own diff as a reviewer would.
5. **Document & hand off.** Update the project docs (§5), write the contract(s) (§6, backend), write
the phase report and update the mock registry (§7), write the handoff note (§6), and save memory (§8).
6. **Declare done** only when the Definition of Done is fully satisfied.
---
## 3. Best-practice mandate (this is graded, not optional)
**Backend** (full list in [backend-conventions-checklist.md](backend-conventions-checklist.md)):
Clean-Architecture boundaries (Domain → Application → Infrastructure → API; dependencies point inward);
CQRS via `martinothamar/Mediator` (`ISender`/`ICommand`/`IQuery`, `internal sealed` handlers,
`OperationResult` for expected failures — never throw); `AsNoTracking()` + `Select()` projection on
every read; pagination on every list; one `IEntityTypeConfiguration<T>` per entity; soft-delete query
filters; audit fields via the SaveChanges interceptor; **caching** read-heavy/config data behind the
cache seam; **idempotency + (where stated) Redis distributed locks** on the money path; **money is IRR
`BIGINT`, no floats, ever**; validate at the boundary with FluentValidation; `CancellationToken`
through every async call; zero new build warnings; no dead code; comment the *why*.
**Frontend** (full list in [frontend-conventions-checklist.md](frontend-conventions-checklist.md)):
Respect the RSC/client boundary; **fetch only through `clientFetch`/`serverFetch`** in
`services/{domain}`; use **TanStack Query with sensible `queryKey`s, `staleTime`, and cache
invalidation** so you never re-fetch data you already have; prevent needless re-renders (stable
references, `select`, colocated state, memo only where it pays); **MUI primitives stay MUI** (Button,
Avatar, Paper… — never re-implement a root component), but **compose shareable mid-level components at
the right shared level** (not buried in a page) when they'll be reused; every user-visible string is an
i18n key in **both** `en.json` and `fa.json`; colours from `tokens.css`; RTL-correct; `npm run check`
green; no dead code.
If a phase's work could be done quickly-but-wrong or properly-but-slower, **do it properly.**
---
## 4. The quality gate (run before declaring done)
- **Backend:** `dotnet build Baya.sln` (zero new warnings) **and** `dotnet test Baya.sln` (all pass).
Add the handler/integration tests your phase introduces. A reachable SQL Server is required to run.
- **Frontend:** `npm run check` (type + lint) **and** `npm run test:ci` if you touched/added a shared
component. Keep `en.json`/`fa.json` in sync.
A phase that doesn't pass its own gate is **not done**, regardless of how complete the code looks.
---
## 5. Update the project documents (in the same change)
Keep the docs honest — stale instructions are worse than none. When your phase changes how something
works or what the architecture is:
- **Architecture map:** if you add/rename/remove a project, layer, route group, provider, domain folder,
or a cross-boundary seam, update the canonical map in the **same** change — server: the *Project map*
in `server/CLAUDE.md`; client: the *Project Structure* tree in `client/CLAUDE.md`; repo-level: the
*Repository layout* in root `CLAUDE.md`.
- **Product docs:** if you discover or decide a business rule that the `product/` docs don't yet
capture (or that drifts from them), update the relevant `product/**.md` (and regenerate the HTML view
per `product/CLAUDE.md` guidance if you changed Markdown). Do not invent rules — record decisions.
- **Conventions:** if you establish a new reusable pattern (a seam, a base class, a hook family), add a
short note to the relevant `CLAUDE.md`/`CONVENTIONS.md` so the next phase reuses it.
Do **not** re-introduce removed starter/template scaffolding while editing docs.
---
## 6. Contracts & the parallel-agent handoff (how the two sides stay in sync)
Backend and frontend phases are designed to run **as two independent agents in parallel**. They never
edit the same files. They coordinate through two folders:
- **`dev/contracts/`** — *backend-owned, frontend-read.* When a backend phase ships an API, it writes
the contract: a per-domain doc under `dev/contracts/domains/<domain>.md` (request/response shapes,
routes, status codes, enums, examples) **and** ensures the server's `swagger.json` snapshot is
published per `dev/contracts/openapi/README.md`. Follow the envelope/format rules in
`dev/contracts/conventions/`. The frontend treats these as the source of truth for types — it does
**not** guess shapes.
- **`dev/shared-working-context/`** — *the running handoff.* Strict lane ownership so parallel agents
never collide:
- **Backend writes only:** `shared-working-context/backend/STATUS.md` (append your phase summary),
`shared-working-context/backend/handoff/after-backend-phase-N.md` (one new file per phase — what
the frontend can now build, which endpoints/contracts are live, what's mocked), and your report +
the mock registry in `shared-working-context/reports/`.
- **Frontend writes only:** `shared-working-context/frontend/STATUS.md`, and
`shared-working-context/frontend/requests/for-backend.md` (append contract gaps / shape requests —
the backend agent reads this, you never edit backend files), and your frontend report in
`shared-working-context/reports/`.
- **Never edit a file the other lane owns.** If the frontend needs a contract change, it *requests*
it; the backend *delivers* it in a subsequent change. This is what makes parallel runs safe.
When mock data is needed on the frontend before its backend phase is merged, build it behind the same
`services/{domain}` seam (a mock `clientApi`) and record it in your frontend report so it's swapped out
cleanly once the real endpoint lands.
---
## 7. The mock / integration report (mandatory, saved to a file — not just chat)
Every phase that mocks or defers an external service **must**:
1. Put the mock behind a **DI-registered interface** (a "seam") with a real-shaped contract, so the real
implementation is a drop-in later. Mock and real both implement the same interface; selection is by
configuration/registration, never by `if (mock)` scattered in handlers.
2. Append an entry to **`dev/shared-working-context/reports/mocks-registry.md`** with: the seam
(interface name + file), what is faked, why, the config keys it reads, and **step-by-step how to make
it real** (which provider, which package, which settings, which methods to implement, what to test).
3. Write a **per-phase report** at `dev/shared-working-context/reports/<backend|frontend>-phase-N-report.md`
covering: *what was built*, *what is now testable and exactly how*, *what is mocked / waiting on a real
service*, *contracts produced/consumed*, *follow-ups for later phases*. (See
[reports/README.md](../../shared-working-context/reports/README.md) for the template.)
Services that will be mocked across the chain and the seam each lives behind (define once, reuse):
SMS/OTP delivery (`ISmsSender`), object storage / MinIO/S3 (`IObjectStorage`), cache/Redis
(`ICacheService`), distributed locks/Redis (`IDistributedLock`), search/Elasticsearch (`INurseSearch`),
PSP card gateway (`IPaymentProvider`), settlement-sharing/تسهیم (`ISettlementSplitProvider`), BNPL
(`IBnplProvider`), bank transfer PAYA/SATNA (`IBankTransferProvider`), webhook verification
(`IWebhookVerifier`), Shahkar (`IShahkarVerifier`), identity KYC/liveness (`IIdentityKycProvider`),
credential/license check (`ICredentialVerifier`), IBAN ownership (`IBankAccountOwnershipVerifier`),
geocoding/maps (`IGeocoder`), مودیان e-invoicing (`IMoadianClient`), AI review moderation
(`IReviewModerationService`), field encryption/KMS (`IFieldEncryptor`), notification dispatch
(`INotificationDispatcher`). The exact phase that *introduces* each seam is in the roadmap; later phases
*reuse* the seam, they do not redefine it.
---
## 8. Write memory & context when done
After the work passes its gate, record what a future agent would need and could not cheaply re-derive:
- **Persistent memory** (the Claude memory dir, per the repo's memory instructions): save/update a
`project`-type memory note for any non-obvious decision, new seam, or gotcha this phase introduced,
and add a one-line pointer to `MEMORY.md`. Don't record what the code/docs already make obvious.
- **Working context:** the handoff note (§6) and the phase report (§7) — these are the durable record
the *other* agent and the *next* phase rely on.
---
## 9. When you're genuinely blocked
Some things are intentionally out of scope and must be **mocked, not invented**: real PSP/BNPL
connections, the Shahkar/MoH/INO/criminal-record vendors, MinIO/S3 credentials, the مودیان enrollment.
If you reach one, implement the seam + a faithful mock + the registry entry, and move on — do not stall
and do not fabricate a real integration. If a *business* rule is truly undecided (the product docs say
"open question"), pick the safe default, implement it config-drivenly where possible, and flag it in
your report for the human to confirm. Never block the chain on an external unknown.