Canonical backend template: apps/backend/.env.example. Copy to .env locally; never commit real secrets.
MySQL-backed tests (Playwright, manual API smoke): copy apps/backend/.env.test.example → .env.test, then from apps/backend run npm run db:test:prepare and npm run start:test. That uses database test_nipos and seeds owner@test.nipos.local / cashier@test.nipos.local (password 123123). Playwright loads .env.test automatically via apps/vendor-web/e2e/load-backend-test-env.cjs.
| Variable | Purpose |
|---|
PORT | HTTP port (default 3000) |
CORS_ORIGIN | Comma-separated browser origins (e.g. http://localhost:5173) |
NODE_ENV | production disables detailed validation messages (ValidationPipe) |
| Variable | Purpose |
|---|
SWAGGER_ENABLED | false disables OpenAPI + Swagger UI |
SWAGGER_PATH | Path segment for UI (default docs); JSON at {path}-json |
| Variable | Purpose |
|---|
APP_URL | Public site URL; aligns POS/admin image paths with Laravel asset(...) expectations (see comment in .env.example) |
IMAGE_APP_URL | Optional. Public origin for Nest-uploaded storage keys that use the nest/ prefix (e.g. gallery_files.file_key like nest/vendor/{id}/…). Full URLs are built with IMAGE_APP_URL when set; otherwise APP_URL is used. |
PUBLIC_STORAGE_ROOT | Optional absolute path to the physical public/storage directory used for polymorphic gallery uploads (gallery_files rows; vendor flows use public/storage/vendor-gallery/..., served at /public/storage/*). Defaults to {cwd}/public/storage when unset. Production: point outside the deploy directory (PM2) or rely on Docker Compose named volumes — see Deployment and static SPAs → Upload persistence. |
VENDOR_IMPORT_STORAGE_ROOT | Optional absolute path for temporary Clover/product import files. Defaults to {cwd}/storage/vendor-imports. Use a persistent path in production alongside PUBLIC_STORAGE_ROOT. |
| Variable | Purpose |
|---|
DB_ENABLED | false skips DB (e.g. CI tests) |
DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASE | MySQL connection |
DB_SYNCHRONIZE | Dev-only; use migrations in production |
DB_LOGGING | SQL logging |
TABLE_PREFIX, TABLE_FIELD_PREFIX | Legacy schema compatibility |
| Variable | Purpose |
|---|
JWT_ACCESS_SECRET, JWT_REFRESH_SECRET | Signing keys |
JWT_ACCESS_EXPIRES, JWT_REFRESH_EXPIRES | e.g. 15m, 7d |
| Variable | Purpose |
|---|
AUTH_SEED_* | Demo customer user |
AUTH_VENDOR_* | Vendor owner/employee seeds, role JSON, zone topic, store active flags |
AUTH_ADMIN_* | Admin + staff seeds, AUTH_ADMIN_EMPLOYEE_MODULES_JSON for module parity; with DB-backed admin_roles, AUTH_ADMIN_MERGE_ITEM_MODULE_ROLE_IDS (default 2) merges catalog item into admin_roles.modules when missing so staff can use product APIs |
| Variable | Purpose |
|---|
| (per store) | Terminal key is not global — devices are configured in app settings; sent as x-pos-terminal-key (see POS and payment webhooks) |
| Variable | Purpose |
|---|
PUBLIC_API_BASE_URL | Optional. Public API origin (no path) used when POST /api/v1/pos-bridge/activate builds wsUrl and webhookUrl. If unset, the handler uses X-Forwarded-Host / Host and X-Forwarded-Proto / request protocol from the activate request (see pos-bridge.controller.ts). Set this when terminals must use a different base than the host header seen by the server (e.g. reverse proxy, split DNS). |
DEFAULT_POS_CURRENCY | Optional. Fallback ISO currency for POS payment flows when not specified (defaults to USD in PosService). |
| Variable | Apps | Purpose |
|---|
VITE_API_URL | admin-web, vendor-web | API origin; empty in Docker build → same-origin /api/v1 (see Frontend applications) |
These are read by apps/vendor-web/playwright.config.cjs and e2e/login.spec.ts (not Vite import.meta.env):
| Variable | Default | Purpose |
|---|
PLAYWRIGHT_API_BASE_URL | http://127.0.0.1:3000 | Nest origin; wired into the Playwright-managed Vite process as VITE_API_URL |
PLAYWRIGHT_VENDOR_WEB_PORT | 5187 | Port for npm run dev under test (avoids 5174 dev default) |
PLAYWRIGHT_VENDOR_OWNER_EMAIL | owner@nipos.local (or owner@test.nipos.local when .env.test is loaded) | Owner login E2E — must exist in DB when DB_ENABLED=true |
PLAYWRIGHT_VENDOR_OWNER_PASSWORD | secret12 / 123123 with .env.test | Owner password for the same test |
PLAYWRIGHT_VENDOR_EMPLOYEE_EMAIL | employee@nipos.local (or cashier@test.nipos.local for Cashier desktop) | Staff / cashier login E2E |
PLAYWRIGHT_VENDOR_EMPLOYEE_PASSWORD | secret12 / 123123 with .env.test | Staff password for the same test |
Failure screenshots, video, and traces are written under apps/vendor-web/test-results/ (see Frontend applications — Screenshots & traces). Login E2E also attaches a full-page PNG per test in the HTML report via e2e/helpers/attach-screenshot.ts.