Files
baya-monorepo/CLAUDE.md
T
2026-07-30 02:26:52 +03:30

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 in server/? Read server/CLAUDE.md. You almost never need both. A frontend change does not touch server files, and vice-versa.

Last verified: 2026-07-30 against commit d3ec723.


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.

Product and domain knowledge — business rules, the database model, payments/BNPL, escrow, the verification pipeline — is not in the code. It lives in product/, a structured docs tree with one topic per file.

Folder What it covers
product/overview/ What Balinyaar is, the four cross-cutting ground truths, the Persian glossary. Read first.
product/business/ The 14 functional/business requirement areas, one file each
product/data-model/ The ~54-table SQL Server schema across 13 domains, + diagrams
product/payments/ BNPL, the escrow ledger, settlement, VAT, integrations (with sources)
product/research/ Market/legal/verification research & go-to-market (EN)
product/notes/ Living notes: open questions, future ideas
product/fa/ Farsi versions (research report + verification flow)

Read the relevant product/ doc before designing any schema, API, or feature. Don't infer business rules from code — the code is young and the docs are the source of truth.

Docs format: the .md files are canonical; matching .html files are a generated, cross-linked browsing view (cd product && node build-docs.mjs). Edit the Markdown and regenerate — never hand-edit the .html. If you add or rename a .md, update the NAV manifest in product/build-docs.mjs.


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
product/ Business truth — what to build and why Markdown (+ generated HTML) the table above
docs/ Engineering truth — rules, the client↔server contract, flows, status, roadmap Markdown docs/README.md
dev/ The finished build-plan chain. History, not a project — nothing to build in it Markdown dev/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
.githooks/ Repo-managed git hooks (the pre-commit secret scan) shell docs/rules/shared/git-and-gates.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/ does not exist yet. When it does, it will hold dev/'s history — and the rule will be that anything in it is a record, not an instruction, because it is written in the imperative from having once been a prompt.


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 docs/rules/ The how and the why, read on demand — 3 shared files, 8 client, 6 server, plus the documentation convention
Procedure .claude/skills/ Playbooks. The frontend-designer skill is the design contract for client/ UI

Start at docs/rules/index.md — it maps "working on X" to the one file to open.

Precedence when two sources disagree: product/ (business truth) → the relevant CLAUDE.md (engineering truth) → 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)

  1. Stay within one project per change unless the task explicitly spans both.
  2. Match the surrounding style. Mirror existing patterns; don't introduce new ones. Each project documents its conventions in its own CLAUDE.md.
  3. Run that project's own checks before declaring work done:
    • client: cd client && npm run check (type + lint + copy), plus npm run test:ci if you touched a tested component.
    • server: cd server && dotnet build Baya.sln (zero new warnings) and dotnet test Baya.sln.
    • What "done" means in full: docs/rules/shared/git-and-gates.md.
  4. Read the product docs before changing behavior. Business rules are decisions, not guesses.
  5. 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.
  6. Configuration lives in files, not a secret store. dotnet user-secrets is not used — the <UserSecretsId> was removed from Baya.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 in appsettings.*.json; client config in .env.development / .env.production; the deployment's container-specific overrides in docker-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 / :HashKey decrypt all existing PII and derive the phone-lookup hash.
  7. 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 docs/rules/documentation.md. Stale instructions are worse than none.
  8. 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-vars as 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: docs/rules/shared/code-quality.md.
  9. A mock is only sanctioned behind a DI-registered seam, selected by configuration, defaulting to the mock, and recorded in docs/status/. Never an if (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 the Baya.* convention.
  • The client package is balinyaar-client; the @/* import alias maps to client/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: 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

# Once per clone — enable the repo's git hooks
git config core.hooksPath .githooks