10 KiB
Balinyaar — Repository Guide (root)
The shared, repo-wide guide for AI coding agents. It is intentionally short. Everything specific to one
side of the stack lives in that project's own CLAUDE.md.
Read the guide for the side you are editing — and only that one. Working in
client/? Read client/CLAUDE.md. Working inserver/? Read server/CLAUDE.md. You almost never need both. A frontend change does not touch server files, and vice-versa.
Last verified: 2026-08-02 against commit
51e86a1.
What Balinyaar is
Balinyaar is a trust-first home-nursing marketplace in Iran. Independent nurses (and nursing-company employees) list configurable services; families search, book, pay, and review. The platform holds funds in an escrow-style ledger and pays nurses out weekly after a confirmed check-out.
Start at mvp/README.md for the current state of the product, in three short,
non-technical files: how to manually test any user journey, what's broken and blocking a real launch, and
what's missing that isn't clearly scheduled. That folder is the live, load-bearing answer to "what's next."
Deeper product/business knowledge — the full business-requirement write-ups, the ~54-table database model,
payments/BNPL research, market/legal research — was consolidated into archive/product/
during the 2026-08-02 documentation cleanup. It is reference material, not required reading: correct as
of that date, but not actively maintained going forward. Read it when mvp/ doesn't answer your question in
enough depth — e.g. designing a new table, or needing the full reasoning behind a business rule.
Never infer business rules from code alone — the code is young. If mvp/ and archive/product/ both go
silent on a money, auth, tenancy, or clinical-data rule, say so rather than guessing.
Repository layout
This is two independent projects in one repo, plus their documentation. There is no root-level build, package, or solution — each project is built, linted, and run on its own.
| Path | What it is | Stack | Guide |
|---|---|---|---|
client/ |
Web frontend | Next.js 16 (App Router) · React 19 · TypeScript · MUI v9 · next-intl | client/CLAUDE.md |
server/ |
Backend API | ASP.NET Core (.NET 10) · Clean Architecture · CQRS · EF Core | server/CLAUDE.md |
mvp/ |
Current truth — plain-language test flows, launch blockers, missing MVP features | Markdown | mvp/README.md |
archive/ |
Everything else: business docs, engineering rules/contracts/flow-atlas, and the executed build history. Reference/history, not instruction — nothing to build from it, and nothing here is kept current | Markdown | archive/README.md |
telegram-otp-bot/ |
OTP relay (standalone, the pre-launch demo rail) | Node 18+, zero deps | telegram-otp-bot/README.md |
deploy/ |
Reverse-proxy config | Caddyfile | DEPLOY.md |
AGENTS.md files in this repo are thin pointers to the CLAUDE.md in the same folder. CLAUDE.md is the
single source of truth at every level.
The two projects communicate over HTTP/JSON (optionally gRPC). The client reads the API base URL from
NEXT_PUBLIC_API_URL; the server listens on http://localhost:5002 by default.
Deployment is three Docker containers — one Dockerfile per project directory, orchestrated by the root
docker-compose.yml — behind an existing Caddy reverse proxy on the external caddy_net
network, serving balinyaar.ir (client) and api.balinyaar.ir (server). The database is not
containerised; it is a remote SQL Server. Full runbook: DEPLOY.md.
archive/ holds the executed build history, the former docs/ (engineering rules, API contracts, the
per-flow test atlas, status/backlog) and the former product/ (business requirements, data model, research)
— consolidated there on 2026-08-02 so the live tree stays focused on MVP work. Anything in it is a record,
not an instruction.
Where the rules live
Three tiers. Open the CLAUDE.md for the side you are editing, then one reference file for the area you
are touching.
| Tier | Where | What |
|---|---|---|
| Hard rules | this file · client/CLAUDE.md · server/CLAUDE.md | Constraints whose violation breaks the build, the gate, or a business invariant |
| Reference (archived) | archive/docs/rules/ |
The how and the why, as of 2026-08-02 — 3 shared files, 8 client, 6 server, plus the documentation convention. Not actively maintained; read it on demand, don't expect it to track later changes |
| Procedure | .claude/skills/ |
Playbooks: frontend-designer (the design contract for client/ UI), backend-feature (adding a server feature), flow-testing (walking a flow end to end) |
Start at archive/docs/rules/index.md — it maps "working on X" to the one file to open.
Precedence when two sources disagree: archive/product/ (business truth) → the relevant CLAUDE.md
(engineering truth) → archive/docs/rules/ (the reasoning behind it) → the task in front of you. Never
silently guess on money, auth, tenancy, or clinical-data rules — do the safe thing, and say so.
Working agreements (apply to both projects)
- Stay within one project per change unless the task explicitly spans both.
- Match the surrounding style. Mirror existing patterns; don't introduce new ones. Each project documents
its conventions in its own
CLAUDE.md. - Run that project's own checks before declaring work done:
- client:
cd client && npm run check(type + lint + copy), plusnpm run test:ciif you touched a tested component. - server:
cd server && dotnet build Baya.sln(zero new warnings) anddotnet test Baya.sln. - What "done" means in full: archive/docs/rules/shared/git-and-gates.md.
- client:
- Read
mvp/(andarchive/product/for depth) before changing behavior. Business rules are decisions, not guesses. - Don't reintroduce template/starter scaffolding. Both projects were derived from open-source starters;
their branding, demo/showcase pages, and
_TITLE_/_DESCRIPTION_placeholders were intentionally removed. Don't add them back. - Configuration lives in files, not a secret store.
dotnet user-secretsis not used — the<UserSecretsId>was removed fromBaya.Web.Api.csproj, so that store is not even read. Any instruction anywhere to set a value with it is stale. Server config (including keys) lives inappsettings.*.json; client config in.env.development/.env.production; the deployment's container-specific overrides indocker-compose.yml. This is a deliberate pre-launch trade for a demo deployment — the repo therefore contains live credentials. Before onboarding real users, rotate them and move the secret half out of git (see DEPLOY.md "Going to Production"). One value is load-bearing and must never change:Seams:FieldEncryption:Key/:HashKeydecrypt all existing PII and derive the phone-lookup hash. - Keep docs honest, and keep the architecture map current. If you change how something works, update the
doc that describes it in the same change. Each level documents its architecture in one canonical place —
this file's "Repository layout" (repo), client/CLAUDE.md "Project structure" (frontend),
server/CLAUDE.md "Project map" (backend). When a change alters that structure — adds, removes, or
renames a project, layer, route group, provider, or major folder, or changes a cross-project / cross-layer
boundary — update the matching section in the same change. The full anti-drift convention (what to update
when X changes, the
> Last verified:stamp, length budgets) is archive/docs/rules/documentation.md. Stale instructions are worse than none. - Write clean, self-documenting code.
- No dead code. Remove unused variables, imports/usings, parameters, and private members — don't leave
them behind and don't suppress the warning. The client enforces this with ESLint
(
@typescript-eslint/no-unused-varsas an error); on the server they are build warnings and the gate is zero new warnings. - Comment the why, not the what. Don't write verbose comments that restate what the code already says. Add a comment only where a non-obvious decision, constraint, business rule, or trade-off isn't evident from the code itself. Prefer a clearer name over a comment.
- Details and worked examples: archive/docs/rules/shared/code-quality.md.
- No dead code. Remove unused variables, imports/usings, parameters, and private members — don't leave
them behind and don't suppress the warning. The client enforces this with ESLint
(
- A mock is only sanctioned behind a DI-registered seam, selected by configuration, defaulting to the
mock, and recorded in
mvp/blockers.md(orarchive/docs/status/for the full historical ledger). Never anif (mock)branch scattered through the code.
Naming
- The server's C# namespaces, projects, and solution all use the
Baya*prefix (Baya.Web.Api,Baya.sln). Keep new server code under theBaya.*convention. - The client package is
balinyaar-client; the@/*import alias maps toclient/src/*.
The product/brand name is Balinyaar — «بالینیار» in Persian copy, with a ZWNJ, always. The server's
Baya* prefix is a legacy code namespace: do not rename it without explicit instruction. Full
conventions: archive/docs/rules/shared/naming.md.
Quick start
# Frontend
cd client && npm install && npm run dev # http://localhost:3000
# Backend
cd server && dotnet run --project src/API/Baya.Web.Api/Baya.Web.Api.csproj # http://localhost:5002/swagger