139 lines
7.2 KiB
Plaintext
139 lines
7.2 KiB
Plaintext
# ────────────────────────────────────────────────────────────────────────
|
|
# Africa Alert PWA — environment configuration template
|
|
# ────────────────────────────────────────────────────────────────────────
|
|
#
|
|
# Copy this file to `.env` at the repo root and fill in real values.
|
|
# `.env` is gitignored; never commit secrets.
|
|
#
|
|
# Dev: `node server/src/index.js` loads `.env` from the server cwd
|
|
# automatically (see server/src/index.js for the loader).
|
|
# Prod: load .env via your orchestrator (Docker, systemd, k8s secret).
|
|
#
|
|
# `server/src/config/index.js` is the single source of truth for which
|
|
# vars are required. The server exits non-zero on startup if a required
|
|
# var is missing in production. See `.harness/docs/conventions.md` for
|
|
# the environment contract.
|
|
|
|
# ─── Node / runtime ────────────────────────────────────────────────────
|
|
NODE_ENV=development
|
|
PORT=3001
|
|
DB_PATH=./data/school.db
|
|
|
|
# ─── Auth (REQUIRED in production) ─────────────────────────────────────
|
|
# HMAC secret for JWT signing/verification.
|
|
# Generate with: node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"
|
|
JWT_SECRET=replace-me-with-64-byte-hex
|
|
|
|
# Comma-separated CORS allow-list. NO wildcard allowed in production.
|
|
ALLOWED_ORIGINS=http://localhost:3000
|
|
|
|
# When true, /api/auth/login response includes `offline_jwt_secret` so the
|
|
# client can mint JWTs while offline. Must be 'true' or 'false'.
|
|
ALLOW_CLIENT_OFFLINE_MINT=true
|
|
|
|
# ─── Paynow (Zimbabwean payment gateway) ────────────────────────────────
|
|
# Credentials are issued at https://www.paynow.co.zw after registering an
|
|
# integration. PAYNOW_INTEGRATION_KEY signs outbound requests AND inbound
|
|
# webhooks — keep it secret.
|
|
PAYNOW_INTEGRATION_ID=
|
|
PAYNOW_INTEGRATION_KEY=
|
|
|
|
# Where Paynow should send status updates and where users land after pay.
|
|
PAYNOW_RETURN_URL=http://localhost:3000/fees
|
|
PAYNOW_BLOCKING_URL=http://localhost:3000/api/payments/webhook
|
|
|
|
# Set to 'true' ONLY for local dev and Playwright tests that simulate
|
|
# Paynow and need to hit the webhook without a real signature. In
|
|
# production leave unset — webhook signature verification is enforced.
|
|
# PAYNOW_SKIP_VERIFY=false
|
|
|
|
# ─── Supabase (optional — sync is no-op when empty) ───────────────────
|
|
# Server-side credentials. The sync engine skips when SUPABASE_KEY is empty.
|
|
SUPABASE_URL=
|
|
SUPABASE_KEY=
|
|
|
|
# Same values exposed to the client bundle. The PWA reads these at build
|
|
# time via Vite's import.meta.env (only VITE_-prefixed vars are inlined).
|
|
VITE_SUPABASE_URL=
|
|
VITE_SUPABASE_ANON_KEY=
|
|
|
|
# ─── SMTP (optional — password recovery emails) ────────────────────────
|
|
# When SMTP_HOST is unset, EmailService falls back to Ethersoft preview
|
|
# mode (dev only). In production set SMTP_HOST to send real mail.
|
|
SMTP_HOST=
|
|
SMTP_PORT=587
|
|
SMTP_SECURE=false
|
|
SMTP_USER=
|
|
SMTP_PASS=
|
|
SMTP_FROM="NextGen Support <support@nextgen.edu>"
|
|
|
|
# ─── Sync tuning ───────────────────────────────────────────────────────
|
|
# Override the default 30s sync interval (in seconds). Empty = default.
|
|
# SYNC_INTERVAL=30
|
|
|
|
# ─── Port allocation ───────────────────────────────────────────────────
|
|
# See PORTS.md for the canonical port plan. Defaults are non-colliding
|
|
# so tenant + superadmin can run side-by-side.
|
|
#
|
|
# Tenant stack:
|
|
PORT=3001 # tenant API (server/src/config/index.js)
|
|
VITE_PORT=3000 # tenant client Vite (client/vite.config.ts)
|
|
VITE_API_TARGET=http://127.0.0.1:3001
|
|
VITE_WS_TARGET=ws://127.0.0.1:3001
|
|
#
|
|
# SuperAdmin stack:
|
|
SUPERADMIN_PORT=3002 # SuperAdmin API (superadmin/server/src/index.js)
|
|
# SuperAdmin client Vite uses VITE_PORT=3003 — set it in superadmin/client/.env
|
|
#
|
|
# Tenant → SuperAdmin JWKS (only SuperAdmin exposes JWKS; default is the
|
|
# dev-proxy path; override to a full URL for cross-origin in prod).
|
|
VITE_SUPERADMIN_JWKS_URL=/api/v1/auth/jwks
|
|
|
|
# ─── SuperAdmin licensing (ed25519 trust anchor + heartbeat) ──────────────
|
|
# Placeholder — replace with the matching SuperAdmin public key.
|
|
SUPERADMIN_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAGB9...REPLACE_ME...\n-----END PUBLIC KEY-----
|
|
VITE_SUPERADMIN_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAGB9...REPLACE_ME...\n-----END PUBLIC KEY-----
|
|
SUPERADMIN_HEARTBEAT_URL=
|
|
LICENSE_HEARTBEAT_INTERVAL_MS=300000
|
|
LICENSE_CLOCK_DRIFT_MS=300000
|
|
# Optional — service auto-detects absence and uses LRU cache only.
|
|
REDIS_URL=
|
|
|
|
# ─── Weekly Government Push (Monday 06:00 server local time) ────────────
|
|
# Pushes the weekly Ministry-style aggregate report
|
|
# (GET /api/reports/weekly payload) to one or more government endpoints.
|
|
# See server/src/services/WeeklyGovPushService.js for the cron logic.
|
|
#
|
|
# The four values below (URLS, AUTH, HMAC_SECRET, SCHOOL_ID) are
|
|
# DEFAULTS. Admins can override them at runtime via
|
|
# Settings → API & Integrations → Ministry Reporting, which writes to
|
|
# the system_settings table; DB values take precedence when set.
|
|
#
|
|
# Set to 0 to disable the cron entirely (kill switch); default is enabled.
|
|
WEEKLY_GOV_PUSH=1
|
|
# Comma-separated target URLs. Replace with real endpoints.
|
|
WEEKLY_GOV_PUSH_URLS=https://mopse.gov.zw/api/v1/weekly,https://placeholder.example.gov.zw/api/v1/weekly
|
|
# Full Authorization header value (e.g. "Bearer xxx"). If empty, no auth header is sent.
|
|
WEEKLY_GOV_PUSH_AUTH=Bearer change-me-to-real-token
|
|
# Optional HMAC-SHA256 secret — if set, the body is signed and sent as X-Signature: sha256=<hex>.
|
|
WEEKLY_GOV_PUSH_HMAC_SECRET=
|
|
# Per-request timeout in ms (default 15000).
|
|
WEEKLY_GOV_PUSH_TIMEOUT_MS=15000
|
|
# Max attempts including the first try (default 3). Backoff is 1s, 4s, 16s.
|
|
WEEKLY_GOV_PUSH_RETRIES=3
|
|
# Tick interval in ms (default 60000). The ticker checks every minute whether it's Monday 06:00.
|
|
WEEKLY_GOV_PUSH_INTERVAL_MS=60000
|
|
# Optional school identifier included in the push envelope so multiple schools can share an endpoint.
|
|
WEEKLY_GOV_PUSH_SCHOOL_ID=
|
|
|
|
# ─── USSD Gateway (Sprint 2) ─────────────────────────────────────────────
|
|
# POST /api/ussd/callback receives USSD callbacks from the telecom
|
|
# gateway. Plain-text CON/END responses.
|
|
#
|
|
# Session inactivity timeout in ms (default 180000 = 3 min). The sweep
|
|
# runs every 60s; sessions older than this are discarded.
|
|
USSD_SESSION_TIMEOUT_MS=180000
|
|
# Optional shared secret. When set, the controller rejects requests
|
|
# whose X-Gateway-Secret header doesn't match. Leave blank in dev.
|
|
USSD_GATEWAY_SECRET=
|