Architecture (monorepo)
Backend process
Section titled “Backend process”- Entry:
apps/backend/src/main.ts— createsNestExpressApplication, appliesapplyGlobalHttpConfig, mounts static SPAs when build artifacts exist. - CORS:
CORS_ORIGIN— comma-separated origins; defaulthttp://localhost:5173. - Port:
PORT(default3000).
For Throttler, ValidationPipe, Swagger exclusions, and module imports, see Backend architecture (NestJS). For controller namespaces, see Backend modules.
HTTP hardening
Section titled “HTTP hardening”- Helmet is applied in
bootstrap-http.ts(CSP relaxed for Swagger UI). - ValidationPipe: whitelist, forbid non-whitelisted properties, transform enabled.
Static SPAs
Section titled “Static SPAs”- Built admin and vendor apps can be served from
apps/backend/static/— seemountStaticSpasIfPresentinbootstrap-static-spas.ts. - Admin assets: prefix
/admin. - Vendor is the default app at
/; paths reserved for API and Swagger are not handed to the vendor SPA (/api,/admin, Swagger UI + JSON underSWAGGER_PATH, … — seeisReservedNonVendorPath).
Container image (production-shaped)
Section titled “Container image (production-shaped)”- Root
Dockerfile: multi-stage build runsnpm run build:deploy(admin → vendor → backend), copiesapps/backend/distandapps/backend/staticinto the runtime image, exposesPORT(default3000), and uses a health check againstGET /api/v1/health. - Vite is built with
VITE_API_URL=(empty) so browser calls use a same-origin relative base (/api/v1/…) when the UI and API share one host.
.github/workflows/docker-build.yml— builds the image on push/PR tomain/master(docker/build-push-action, no push; tagindochina-pos:ci). Use it to verify the Dockerfile after dependency or build changes.
Deploy without Docker
Section titled “Deploy without Docker”deploy/deploy-to-vps.sh— optional rsync + SSH flow for a VPS (PM2 or systemd). Configuredeploy/.env.deployfromdeploy/env.deploy.example. Targets:admin,vendor,backend, orall.
Organization-specific notes
Section titled “Organization-specific notes”Document separately for each environment: TLS termination, CDN or reverse proxy rules, and where static/admin and static/vendor are produced in your pipeline if not using the repo Dockerfile.