This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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.
The codebase lives in /server — all development work happens there.
Run these from the /server directory:
# Development
npm run dev # Start with nodemon (tsx, no compilation needed)
npm run watch # Watch TypeScript files (tsc --watch)
# Type checking & linting
npm run transpile:noemit # Type-check without emitting files
npm run lint # Lint TypeScript files
npm run lint:fix # Auto-fix lint errors
# Build (full pipeline: transpile + docs)
npm run build # Compile TypeScript + build all API docs
npm run transpile # Compile TypeScript only (tsc-alias for path rewrites)
# Database seeding
npm run seed # Seed MongoDB with Philippine location data
# API documentation
npm run docs:gen # Generate OpenAPI YAML/JSON from Zod schemas
npm run docs:build # Build Redocly HTML documentation
npm run docs:swagger # Copy Swagger UI assets + generate docsDocker (run from repo root):
docker compose up # Start app + MongoDB (development mode)HTTP Request → CORS → Body Parser → Zod Validation Middleware → Controller → MongoCrudClass → Mongoose → MongoDB
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.
server/src/middleware/validate.ts — Generic validation middleware that takes a Zod schema and validates req.query or req.body. Throws ServerError on failure.
server/src/middleware/connectServerless.ts — Wraps controllers for Vercel serverless, re-establishing MongoDB connections per request (stateless environment).
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.
Island (1) → Region (many) → Province (many) → Municipality (many) → Barangays (Stats collection)
Mongoose models use virtual population for nested queries. Stats holds barangay counts per municipality.
Zod schemas in server/src/schemas/ drive both:
- Runtime validation — query parameter and payload validation via middleware
- OpenAPI documentation —
@asteasolutions/zod-to-openapigenerates the spec from the same schemas
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.
All successful responses follow this structure:
{
"success": true,
"total": 17,
"metadata": { "version": "...", "author": "...", "url": "...", "description": "..." },
"data": []
}Error responses:
{ "success": false, "error": "...", "message": ["..."], "status": 400 }The DEPLOYMENT_PLATFORM env var ("regular" | "vercel") controls:
- Route mounting in
app.ts(serverless wrapper applied only on Vercel) - MongoDB connection strategy (
server.tsvsconnectServerless.ts)
The project uses ESM ("type": "module"). TypeScript targets NodeNext modules. Path alias @/* maps to src/* — tsc-alias rewrites these after compilation.
Copy server/.env.example to server/.env and set:
MONGO_URI— MongoDB connection stringDEPLOYMENT_PLATFORM—regularfor local devALLOW_CORS=1andALLOW_ALL_ORIGINS=1for local devBASE_API_URL— e.g.http://localhost:3001
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.