docs: add comprehensive README with run instructions

Covers stack, repo layout, local dev (pnpm install, env, MySQL via
docker, prisma db push, seed admin, run api+web, login), full-stack
Docker path, common commands, auth/roles, legacy migration, and prod
notes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 17:49:35 -07:00
co-authored by Claude Opus 4.8
parent 0260b8110d
commit 9dc7f26e02
+204
View File
@@ -0,0 +1,204 @@
# Jorge Cuadros & Asociados — Platform
Internal platform for a Baja California insurance brokerage and property-services
firm: a single expedient joining each client's **properties/services**,
**insurance policies**, **account statement**, and the firm's **checkbook**.
It replaces a legacy PHP/Access app (see `RESUME.md` and `PLAN.md` for the full
history and rebuild rationale).
The UI is Spanish-first; the codebase and this document are in English.
---
## Stack
| Layer | Tech | Port |
| --------- | -------------------------------------------------------------- | ---- |
| Web | Next.js 14 (App Router, React 18) | 3000 |
| API | NestJS 10 · Passport local + `express-session` · Argon2 | 3001 |
| Database | MySQL 8 via Prisma 5 (`@jorgecuadros/database` workspace pkg) | 3306 |
| Migration | Python 3 pipeline (legacy Access → staging → transforms) | — |
Monorepo managed with **pnpm workspaces**. Node **>= 20**.
---
## Repository layout
```
apps/
web/ Next.js frontend (@jorgecuadros/web)
api/ NestJS backend (@jorgecuadros/api)
scripts/seed-user.mjs idempotent admin seeder
packages/
database/ Prisma schema + generated client (@jorgecuadros/database)
prisma/schema.prisma
migration/ One-off Python ETL from the legacy Access DB (run_all.py)
docker/ Dockerfiles for api + web
docker-compose.yml mysql + api + web
.env.example copy to .env
```
API feature modules: `auth`, `users`, `customers`, `policies`, `properties`,
`billing`, `bank`. Web routes: `/clientes`, `/polizas`, `/servicios`,
`/estado-cuenta`, `/banco` (chequera), `/catalogos`, `/usuarios`, `/login`.
---
## Prerequisites
- Node.js >= 20 and **pnpm** (`npm i -g pnpm`)
- Docker (for MySQL, or bring your own MySQL 8)
- Python 3 — only if you run the legacy data migration
---
## Run it locally (development)
### 1. Install
```bash
pnpm install
```
pnpm blocks postinstall build scripts by default; the trusted ones
(`argon2`, `prisma`, `@prisma/client`, `@prisma/engines`, `@nestjs/core`) are
allowlisted in `pnpm-workspace.yaml`, so the native builds run automatically.
### 2. Configure environment
```bash
cp .env.example .env
```
Then edit `.env`. For the Docker MySQL below the defaults already line up;
just set a real `SESSION_SECRET`:
```env
DATABASE_URL=mysql://jorgecuadros:jorgecuadros@localhost:3306/jorgecuadros
SESSION_SECRET=<any long random string>
WEB_ORIGIN=http://localhost:3000
NEXT_PUBLIC_API_ORIGIN=http://localhost:3001
```
The API loads `DATABASE_URL`, `SESSION_SECRET`, `WEB_ORIGIN`, and optional
`PORT` (default `3001`). The web app only needs `NEXT_PUBLIC_API_ORIGIN`.
### 3. Start MySQL
```bash
docker compose up -d mysql
```
(Or point `DATABASE_URL` at an existing MySQL 8 instance.)
### 4. Create the schema + generate the Prisma client
The schema is managed with `prisma db push` (no migration history committed):
```bash
pnpm --filter @jorgecuadros/database exec prisma db push
pnpm --filter @jorgecuadros/database generate
```
### 5. Seed a sign-in user
```bash
node apps/api/scripts/seed-user.mjs
```
Idempotent (upsert by email). Defaults — override with `SEED_EMAIL`,
`SEED_PASSWORD`, `SEED_NAME`:
- email: `admin@jorgecuadros.local`
- password: `ChangeMe!2026`
- role: `ADMIN`
### 6. Run the apps (two terminals)
```bash
# API → http://localhost:3001
pnpm --filter @jorgecuadros/api start:dev
# Web → http://localhost:3000
pnpm --filter @jorgecuadros/web dev
```
Root shortcuts also exist: `pnpm dev:api`, `pnpm dev:web`.
### 7. Log in
Open http://localhost:3000, sign in with the seeded credentials.
Sessions are cookie-based and last 8 hours.
---
## Run it with Docker (full stack)
Builds MySQL + API + web from `docker-compose.yml`:
```bash
export SESSION_SECRET=$(openssl rand -hex 32)
docker compose up --build
```
Web on http://localhost:3000, API on http://localhost:3001. `SESSION_SECRET`
is required (compose fails without it). After first boot, push the schema and
seed a user against the container DB:
```bash
docker compose exec api node apps/api/scripts/seed-user.mjs
```
---
## Common commands
| Task | Command |
| ------------------------ | -------------------------------------------------------------- |
| Install | `pnpm install` |
| Dev — API | `pnpm dev:api` |
| Dev — Web | `pnpm dev:web` |
| Build all | `pnpm build` |
| Generate Prisma client | `pnpm prisma:generate` |
| Push schema (dev) | `pnpm --filter @jorgecuadros/database exec prisma db push` |
| Prisma Studio | `pnpm prisma:studio` |
| API tests | `pnpm --filter @jorgecuadros/api test` |
| Lint (web / api) | `pnpm --filter @jorgecuadros/web lint` · `... /api lint` |
| Seed admin user | `node apps/api/scripts/seed-user.mjs` |
---
## Auth & roles
Session auth via Passport local strategy; passwords hashed with Argon2 (no
plaintext, unlike the legacy app). Roles gate the UI and API — e.g. managing
`/catalogos` and `/usuarios` requires the appropriate ability (`ADMIN` /
`MANAGER`). New users are created by an admin in `/usuarios`; the first admin
comes from the seed script above.
---
## Legacy data migration (optional)
`migration/` holds the one-off Python ETL that lifts data out of the old
Microsoft Access database into MySQL.
```bash
pip install -r migration/requirements.txt
python migration/run_all.py
```
> ⚠️ `run_all.py` truncates and reloads **all** downstream tables. Never run an
> individual `transform_*.py` in isolation — it orphans dependent tables. See
> `migration/RECONCILIATION.md` for details.
---
## Production notes
- Use `pnpm --filter @jorgecuadros/database exec prisma migrate deploy` if/when
a committed migration history is adopted; today dev uses `db push`.
- Set a strong `SESSION_SECRET` and a locked-down `DATABASE_URL`.
- The API expects `WEB_ORIGIN` to match the browser origin for session cookies.
- Documents are stored in MinIO in the deployed environment (see `RESUME.md`).