|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +**ph-regions** is a RESTful API serving hierarchical Philippine location data (islands → regions → provinces → municipalities → barangays). It supports testing/simulating RESTful API requests from client applications, with deployment targets for both regular Node.js and Vercel serverless. |
| 8 | + |
| 9 | +The codebase lives in `/server` — all development work happens there. |
| 10 | + |
| 11 | +## Commands |
| 12 | + |
| 13 | +Run these from the `/server` directory: |
| 14 | + |
| 15 | +```bash |
| 16 | +# Development |
| 17 | +npm run dev # Start with nodemon (tsx, no compilation needed) |
| 18 | +npm run watch # Watch TypeScript files (tsc --watch) |
| 19 | + |
| 20 | +# Type checking & linting |
| 21 | +npm run transpile:noemit # Type-check without emitting files |
| 22 | +npm run lint # Lint TypeScript files |
| 23 | +npm run lint:fix # Auto-fix lint errors |
| 24 | + |
| 25 | +# Build (full pipeline: transpile + docs) |
| 26 | +npm run build # Compile TypeScript + build all API docs |
| 27 | +npm run transpile # Compile TypeScript only (tsc-alias for path rewrites) |
| 28 | + |
| 29 | +# Database seeding |
| 30 | +npm run seed # Seed MongoDB with Philippine location data |
| 31 | + |
| 32 | +# API documentation |
| 33 | +npm run docs:gen # Generate OpenAPI YAML/JSON from Zod schemas |
| 34 | +npm run docs:build # Build Redocly HTML documentation |
| 35 | +npm run docs:swagger # Copy Swagger UI assets + generate docs |
| 36 | +``` |
| 37 | + |
| 38 | +Docker (run from repo root): |
| 39 | +```bash |
| 40 | +docker compose up # Start app + MongoDB (development mode) |
| 41 | +``` |
| 42 | + |
| 43 | +## Architecture |
| 44 | + |
| 45 | +### Request Lifecycle |
| 46 | +``` |
| 47 | +HTTP Request → CORS → Body Parser → Zod Validation Middleware → Controller → MongoCrudClass → Mongoose → MongoDB |
| 48 | +``` |
| 49 | + |
| 50 | +### Key Abstractions |
| 51 | + |
| 52 | +**`server/src/classes/mongo.class.ts`** — `MongoCrudClass` provides reusable `find`, `findOne`, `create`, `update`, `delete` methods used by all controllers. Controllers instantiate it with a Mongoose model. |
| 53 | + |
| 54 | +**`server/src/middleware/validate.ts`** — Generic validation middleware that takes a Zod schema and validates `req.query` or `req.body`. Throws `ServerError` on failure. |
| 55 | + |
| 56 | +**`server/src/middleware/connectServerless.ts`** — Wraps controllers for Vercel serverless, re-establishing MongoDB connections per request (stateless environment). |
| 57 | + |
| 58 | +**`server/src/utils/error.ts`** — `ServerError extends Error` with a `status` property. The global error handler in `app.ts` catches these and formats the error response. |
| 59 | + |
| 60 | +### Data Model (Hierarchical) |
| 61 | +``` |
| 62 | +Island (1) → Region (many) → Province (many) → Municipality (many) → Barangays (Stats collection) |
| 63 | +``` |
| 64 | +Mongoose models use virtual population for nested queries. `Stats` holds barangay counts per municipality. |
| 65 | + |
| 66 | +### Zod as Single Source of Truth |
| 67 | +Zod schemas in `server/src/schemas/` drive both: |
| 68 | +1. **Runtime validation** — query parameter and payload validation via middleware |
| 69 | +2. **OpenAPI documentation** — `@asteasolutions/zod-to-openapi` generates the spec from the same schemas |
| 70 | + |
| 71 | +When adding or modifying endpoints, update the corresponding Zod schema, the OpenAPI doc file in `server/src/scripts/openapi/docs/`, and run `npm run docs:gen`. |
| 72 | + |
| 73 | +### API Response Shape |
| 74 | +All successful responses follow this structure: |
| 75 | +```json |
| 76 | +{ |
| 77 | + "success": true, |
| 78 | + "total": 17, |
| 79 | + "metadata": { "version": "...", "author": "...", "url": "...", "description": "..." }, |
| 80 | + "data": [] |
| 81 | +} |
| 82 | +``` |
| 83 | +Error responses: |
| 84 | +```json |
| 85 | +{ "success": false, "error": "...", "message": ["..."], "status": 400 } |
| 86 | +``` |
| 87 | + |
| 88 | +### Deployment Platform Branching |
| 89 | +The `DEPLOYMENT_PLATFORM` env var (`"regular"` | `"vercel"`) controls: |
| 90 | +- Route mounting in `app.ts` (serverless wrapper applied only on Vercel) |
| 91 | +- MongoDB connection strategy (`server.ts` vs `connectServerless.ts`) |
| 92 | + |
| 93 | +### Module System |
| 94 | +The project uses ESM (`"type": "module"`). TypeScript targets `NodeNext` modules. Path alias `@/*` maps to `src/*` — `tsc-alias` rewrites these after compilation. |
| 95 | + |
| 96 | +## Environment Setup |
| 97 | + |
| 98 | +Copy `server/.env.example` to `server/.env` and set: |
| 99 | +- `MONGO_URI` — MongoDB connection string |
| 100 | +- `DEPLOYMENT_PLATFORM` — `regular` for local dev |
| 101 | +- `ALLOW_CORS=1` and `ALLOW_ALL_ORIGINS=1` for local dev |
| 102 | +- `BASE_API_URL` — e.g. `http://localhost:3001` |
| 103 | + |
| 104 | +## Code Style |
| 105 | + |
| 106 | +ESLint enforces: single quotes, no semicolons, 2-space indent, Unix line endings, no trailing commas. Run `npm run lint:fix` before committing. TypeScript strict mode is on — no implicit `any`, strict null checks. |
0 commit comments