Validation: shared NaN-guarded Zod coercion helpers in schemas/common.ts replace the raw number|string transform idiom across every schema (the root-cause NaN bug class); emailOrEmpty + lenient isoDateString/timeString. Security: roles privilege-escalation closed; refresh-token family revocation on reuse; TOTP uses config params; read endpoints permission-guarded; received-invoices gross VAT on all paths; orders-pdf custom-items authz. Concurrency: $queryRaw SELECT...FOR UPDATE locks in ascending-id order (warehouse confirm/cancel, attendance lockUserRow); uniqueness checks moved into create transactions (TOCTOU -> 409); deterministic id tiebreak on second-precision timestamp ordering (plan resolveCell/resolveGrid, warehouse FIFO). Frontend: Rules-of-Hooks fixed across ~14 pages + PlanCellModal; UTC-date persisted fields; dashboard invalidation gaps; stale-closure confirm bugs. Tooling/tests: ESLint flat config (react-hooks/rules-of-hooks = error) + Prettier; tsconfig.test.json so tsc -b type-checks the tests; removed 3 dead deps; npm audit fix (8 -> 3). Suite 195 -> 247 (happy-path auth, FIFO oldest-first, flakiness fixes), isolated on app_test via .env.test with a hard-throw setup guard. Gates: tsc 0 | build 0 | vitest 247/247 | eslint 0 errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
63 lines
3.4 KiB
Plaintext
63 lines
3.4 KiB
Plaintext
# ─────────────────────────────────────────────────────────────────────────
|
|
# boha-app-ts environment template. Copy to `.env` (dev) / `.env.test` (tests).
|
|
# Required vars throw at boot if missing; optional vars show their defaults.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
|
|
# ── Required ──────────────────────────────────────────────────────────────
|
|
DATABASE_URL=mysql://user:password@localhost:3306/app
|
|
# Auth — MUST regenerate for production: openssl rand -hex 32
|
|
JWT_SECRET=REPLACE_WITH_64_CHAR_HEX_STRING_RUN_openssl_rand_hex_32
|
|
# TOTP — MUST regenerate for production: openssl rand -hex 32
|
|
TOTP_ENCRYPTION_KEY=REPLACE_WITH_64_CHAR_HEX_STRING_RUN_openssl_rand_hex_32
|
|
|
|
# ── Server ────────────────────────────────────────────────────────────────
|
|
PORT=3001 # production port (dev is hardcoded to 3050)
|
|
HOST=127.0.0.1
|
|
APP_ENV=local # local | production — controls CSP/CORS/HSTS
|
|
APP_URL= # base URL used in email links
|
|
# TRUST_PROXY=127.0.0.1,::1 # comma-separated trusted proxy IPs
|
|
|
|
# ── Tokens (seconds) ──────────────────────────────────────────────────────
|
|
ACCESS_TOKEN_EXPIRY=900
|
|
REFRESH_TOKEN_SESSION_EXPIRY=3600
|
|
REFRESH_TOKEN_REMEMBER_EXPIRY=2592000
|
|
|
|
# ── TOTP / 2FA (optional, sensible defaults) ──────────────────────────────
|
|
# TOTP_ALGORITHM=SHA1
|
|
# TOTP_DIGITS=6
|
|
# TOTP_PERIOD=30
|
|
# LOGIN_TOKEN_EXPIRY_MINUTES=5
|
|
|
|
# ── Rate limiting (optional) ──────────────────────────────────────────────
|
|
# RATE_LIMIT_MAX=300
|
|
# RATE_LIMIT_WINDOW=1 minute
|
|
# RATE_LIMIT_LOGIN=20
|
|
# RATE_LIMIT_TOTP=5
|
|
# RATE_LIMIT_REFRESH=10
|
|
|
|
# ── File storage (NAS network shares) ─────────────────────────────────────
|
|
NAS_PATH=Z:/02_PROJEKTY
|
|
# NAS_FINANCIALS_PATH=
|
|
# NAS_OFFERS_PATH=
|
|
MAX_UPLOAD_SIZE=52428800 # 50 MB
|
|
|
|
# ── Email ─────────────────────────────────────────────────────────────────
|
|
CONTACT_EMAIL_TO=
|
|
CONTACT_EMAIL_FROM=
|
|
SMTP_FROM=
|
|
# SMTP_FROM_NAME=
|
|
LEAVE_NOTIFY_EMAIL=
|
|
# INVOICE_ALERT_EMAIL= # set to enable the daily 08:00 invoice-alert cron
|
|
# Optional SMTP transport (defaults to local sendmail when SMTP_HOST is unset):
|
|
# SMTP_HOST=
|
|
# SMTP_PORT=587
|
|
# SMTP_SECURE=false
|
|
# SMTP_USER=
|
|
# SMTP_PASS=
|
|
|
|
# ── CORS (production only, comma-separated) ───────────────────────────────
|
|
CORS_ORIGINS=
|
|
|
|
# ── AI assistant "Odin" (optional; feature self-hides when unset) ─────────
|
|
# ANTHROPIC_API_KEY=
|