workorder-desk/.env.example

155 lines
7.3 KiB
Text

# ─────────────────────────────────────────────────────────────────────────────
# Field Service Work Order Management — environment template
#
# Copy to `.env` and fill in real values:
# cp .env.example .env
# NEVER commit `.env`. Real secrets must never be committed to the repo.
# ─────────────────────────────────────────────────────────────────────────────
# ── HTTP / runtime ────────────────────────────────────────────────────────────
# Port the Express API listens on (default 4000).
PORT=4000
# development | test | production
NODE_ENV=development
# ── Database ──────────────────────────────────────────────────────────────────
# MongoDB connection string (required).
MONGODB_URI=mongodb://127.0.0.1:27017/workorders
# ── Secrets (REQUIRED) ────────────────────────────────────────────────────────
# HS256 signing secret for the 15-minute access JWT.
# MUST be >= 32 characters and MUST NOT be a placeholder such as "secret",
# "changeme", or "replace-me". Rotating it invalidates issued access tokens.
JWT_SECRET=0123456789abcdef0123456789abcdef0123456789abcdef
# Secret used by cookie-parser to sign cookie values (integrity only).
# MUST be >= 32 characters. It is NOT authentication.
COOKIE_SECRET=fedcba9876543210fedcba9876543210fedcba9876543210
# NOTE: JWT_SECRET and COOKIE_SECRET must each be at least 32 characters and
# must not be placeholder values. Generate real ones with:
# openssl rand -hex 32
# and never commit them to version control.
# ── CORS / URLs ───────────────────────────────────────────────────────────────
# Comma-separated list of allowed origins. `credentials: true` is set, so "*"
# is rejected. Same-origin deployments only need the SPA origin.
CORS_ORIGIN=http://localhost:5173
# Public SPA origin (used for password-reset links and cookie handling).
APP_URL=http://localhost:5173
# ── Mailer ────────────────────────────────────────────────────────────────────
# Resend API key (https://resend.com/docs/api-reference/emails/send).
# Leave empty to use the log-only mailer (logs a REDACTED reset URL).
RESEND_API_KEY=
# Verified sender. Defaults to Resend's shared onboarding@resend.dev.
# Use an address on your verified domain (e.g. no-reply@mail.lverma.com).
RESEND_FROM=Work Order Desk <no-reply@mail.lverma.com>
# ── Proxy / observability ─────────────────────────────────────────────────────
# Number of trusted reverse-proxy hops. nginx sets X-Forwarded-* in prod;
# keep 0 when the API is reached directly (local dev).
TRUST_PROXY_HOPS=0
# Set to true to return stack traces in 500 responses (dev only, never prod).
DEBUG_ERRORS=false
# pino log level: trace | debug | info | warn | error | fatal
LOG_LEVEL=info
# ── Rate limiting (window in ms, max requests per key) ────────────────────────
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX=300
RATE_LIMIT_LOGIN_MAX=10
RATE_LIMIT_FORGOT_MAX=3
# ── Seed credentials (`npm run seed`, idempotent) ─────────────────────────────
SEED_ADMIN_EMAIL=admin@example.com
SEED_ADMIN_PASSWORD=Admin1234
SEED_USER_EMAIL=user@example.com
SEED_USER_PASSWORD=User1234
SEED_VIEWER_EMAIL=viewer@example.com
SEED_VIEWER_PASSWORD=Viewer1234
# ── Frontend (Vite, consumed at build time) ───────────────────────────────────
# Must match APP_URL.
VITE_APP_URL=http://localhost:5173
# Empty in dev → relative `/api/v1`, proxied by Vite (dev) or nginx (prod).
# Set to the API origin only for a split-origin deployment.
VITE_API_URL=
# ── Agentic AI ────────────────────────────────────────────────────────────────
# OPT-IN. Off by default: a fresh checkout without these keys boots normally
# and the AI surfaces (copilot, triage worker) are inert. Setting
# AI_ENABLED=true REQUIRES a real AI_BASE_URL (https, non-private host) and
# AI_API_KEY. AI_API_KEY is a server-side secret — NEVER commit it, never send
# it to the browser. The backend reads these keys via backend/src/config/env.ts
# (from .env at the repo root or backend/); the worker process reads the same
# .env and needs no extra configuration.
# Master switch. false = copilot API and triage worker refuse to run (hard kill).
AI_ENABLED=false
# OpenAI-compatible chat/completions base URL (e.g. https://api.openai.com/v1
# or a compatible gateway). Must be https and NOT a private/loopback host.
AI_BASE_URL=
# Server-side API key for the provider. Never committed; pino redacts it.
AI_API_KEY=
# Model name passed to the provider (default gpt-4o-mini).
AI_MODEL=gpt-4o-mini
# Max tool-call steps per agent run, incl. retries and failed parses (default 8).
AI_MAX_STEPS_PER_RUN=8
# Max tokens a single provider call may output (default 2048).
AI_MAX_OUTPUT_TOKENS=2048
# Per-run prompt (context) token budget (default 16384).
AI_MAX_CONTEXT_TOKENS=16384
# Cost per 1M tokens used for spend accounting (USD, defaults 0.15 / 0.60).
AI_PRICE_PER_1M_INPUT=0.15
AI_PRICE_PER_1M_OUTPUT=0.60
# Daily spend caps in USD (defaults 1.00 per user / 1.00 per agent / 5.00 global).
AI_DAILY_SPEND_USD=1.00
AGENT_DAILY_SPEND_USD=1.00
AI_GLOBAL_DAILY_SPEND_USD=5.00
# Copilot approval lifetime in ms before a staged write expires (default 600000).
AI_APPROVAL_TTL_MS=600000
# SSE keepalive interval in ms (default 15000).
AI_SSE_KEEPALIVE_MS=15000
# AI-specific rate limit: stream starts per (user + IP) window (default 20).
AI_RATE_LIMIT_MAX=20
# Triage worker poll interval in ms (default 5000).
AGENT_POLL_INTERVAL_MS=5000
# Outbox event claim lease in ms; a crashed claim is requeued after this (default 15000).
AGENT_LEASE_MS=15000
# Worker sweep interval in ms (stale runs, expired approvals, reconcile) (default 30000).
AGENT_SWEEP_INTERVAL_MS=30000
# Max attempts per outbox event before it is marked failed (default 3).
AGENT_MAX_ATTEMPTS=3
# Reconcile pass re-emits events older than this (default 60000).
AGENT_RECONCILE_AFTER_MS=60000
# Triage mode: suggest | auto-apply (default suggest).
AGENT_TRIAGE_MODE=suggest
# Working-hours window for autonomous triage; "*" = 24/7 (default *).
AGENT_WORKING_HOURS=*
# Max concurrent outbox claims per worker (default 2).
AGENT_CONCURRENCY=2