Files
baya-monorepo/dev/post-phase/refinement/RUNBOOK.md
T
2026-07-12 01:09:11 +03:30

6.3 KiB
Raw Blame History

Run the whole app locally — Balinyaar bring-up runbook

The one copy-pasteable procedure for standing up both projects on one machine and watching a real, authenticated request cross the wire. Established by Refinement Phase 0 (refinement-phase-0-bring-up.md).

After this you have: the API on https://localhost:5002 (against a local SQL Server), the web client on http://localhost:3000, and a working phone-OTP login backed by the real backend. Auth is the only real domain until Refinement Phase 4 — everything else in the UI is still an in-browser mock.


Prerequisites

  • .NET 10 SDK (dotnet --version) — preview is fine.
  • Node.js 20+ and npm (node --version).
  • Docker (Desktop or engine) for the local database — or your own SQL Server on localhost:1433.

One-time setup

1. Trust the ASP.NET Core HTTPS dev certificate

Without this the browser (and fetch) rejects https://localhost:5002 and every call fails with an opaque network error.

dotnet dev-certs https --trust

Accept the OS prompt. (macOS/Windows trust the cert; on Linux see the .NET docs for the per-distro step.)

2. Start a local SQL Server

From server/:

cd server
docker compose up -d

This runs SQL Server 2022 (Developer edition) on localhost:1433 with a dev-only SA password (Balinyaar_Dev1433, defined in server/docker-compose.yml — not a secret, never used in production). Give it ~2030s on first start (docker compose ps shows healthy).

Already have a SQL Server? Skip this and point the connection string in step 3 at it instead.

3. Point the API at the local database (via user-secrets — never a committed file)

The committed appsettings*.json carry a placeholder connection string on purpose. Supply the real local one through dotnet user-secrets so no working credential ever lands in git. From the API project:

cd server/src/API/Baya.Web.Api
dotnet user-secrets set "ConnectionStrings:SqlServer" "Server=localhost,1433;Database=Baya;User Id=sa;Password=Balinyaar_Dev1433;TrustServerCertificate=True;Encrypt=False;"

The Password must match MSSQL_SA_PASSWORD in docker-compose.yml. User-secrets auto-load only in the Development environment, so this never affects a deployed build.

Env-var alternative (e.g. for CI/containers): set ConnectionStrings__SqlServer (double underscore = the : config separator) instead of using user-secrets. PowerShell: $env:ConnectionStrings__SqlServer = "Server=localhost,1433;Database=Baya;User Id=sa;Password=Balinyaar_Dev1433;TrustServerCertificate=True;Encrypt=False;" bash: export ConnectionStrings__SqlServer="Server=localhost,1433;Database=Baya;User Id=sa;Password=Balinyaar_Dev1433;TrustServerCertificate=True;Encrypt=False;"


Run it (two terminals)

Terminal 1 — backend (from server/)

dotnet run --project src/API/Baya.Web.Api/Baya.Web.Api.csproj

On boot the API applies all EF migrations and seeds roles + an admin user + a sandbox payment gateway against the (empty) local DB, then listens on https://localhost:5002 — Swagger at https://localhost:5002/swagger.

Terminal 2 — frontend (from client/)

cd client
npm install      # first time only
npm run dev

Serves http://localhost:3000. It reads the API base URL from client/.env.development (NEXT_PUBLIC_API_URL = https://localhost:5002). If you run the API on a different port/scheme, create client/.env.local with your NEXT_PUBLIC_API_URL=… (it overrides .env.development, is git-ignored).


Log in (the real round-trip)

  1. Open http://localhost:3000/fa/login.
  2. Enter an Iranian mobile number (e.g. 09120000001) and request the code.
  3. Get the 6-digit OTP one of two ways:
    • Read the server console (Terminal 1) — SMS is mocked, so the code is logged: MOCK SMS — OTP code 123456 for phone ending in 0001.
    • Or hit the Development-only helper (handy for scripts/e2e): GET https://localhost:5002/api/v1/dev/last_otp/09120000001{ "data": { "phone": "09120000001", "code": "123456" }, ... }. This endpoint returns 404 outside Development and is superseded by real SMS in Refinement Phase 8.
  4. Enter the code and submit → you land on the customer home.
  5. Verify in DevTools → Network: POST /api/v1/auth/request_otp, POST /api/v1/auth/verify_otp, and GET /api/v1/me all return 200 with the ApiResult envelope, and there is no CORS error in the console. That is the first real authenticated request between the two projects.

Good to know

  • The API speaks HTTP/2 (Kestrel Protocols: Http2, for gRPC). Browsers negotiate h2-over-TLS automatically, so fetch just works; for curl add --http2.
  • Only auth is real by default. 21 of 22 client service domains default to an in-browser mock (USE_*_MOCK = true); the home, search, bookings, etc. are fake in-memory data until Refinement Phase 4.
  • The DB self-migrates + self-seeds, so pointing at an empty local instance is enough. Rich demo data (nurses, variants, search rows) arrives in Refinement Phase 1.
  • Allowed browser origins are configuration-driven (Cors:AllowedOrigins), defaulting to http://localhost:3000 in Development. A deployed environment lists its real web origin(s).

Stopping / resetting

docker compose down          # stop the DB, keep its data
docker compose down -v       # stop the DB and wipe the volume (fresh migrate + seed next run)

Troubleshooting

Symptom Fix
Browser: net::ERR_CERT_AUTHORITY_INVALID on :5002 Run dotnet dev-certs https --trust (setup step 1).
API startup: Login failed for user 'sa' / connect timeout DB not up or wrong password — check docker compose ps and that the user-secrets password matches docker-compose.yml.
Console: ...has been blocked by CORS policy UseCors missing/mis-ordered, or the browser origin isn't in Cors:AllowedOrigins. It must sit after UseRouting and before the rate limiter.
dotnet user-secrets errors with "could not find UserSecretsId" Run it from server/src/API/Baya.Web.Api (the project with <UserSecretsId>).