# Copy this file to `.env.local` for local development. # # For LOCAL DEVELOPMENT, DATABASE_URL must point at the local Postgres started by # docker-compose (`pnpm db:start`). `pnpm dev` will REFUSE to start against a # non-local host (e.g. the production Neon database) unless you explicitly set # ALLOW_REMOTE_DB=true — this is intentional, to protect production data. DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo PAYLOAD_SECRET=YOUR_SECRET_HERE # Media storage (OPS52) — Garage S3 (homeserver). When ANY of the four required # envs (S3_BUCKET, S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY) is set, # ALL of them must be: a partial config aborts the boot with the exact missing # names (fail-closed). When none is set, Payload falls back to local disk storage # (dev/test). The bucket stays PRIVATE: the app proxies the files through its # /media/file route (the plugin streams each object from Garage), so no public # bucket/DNS is needed. Production: S3_BUCKET=teqo-media, # S3_ENDPOINT=http://100.119.220.31:3900 (tailnet do homeserver). Staging # (OPS103) has its own bucket `teqo-media-staging` — never share the # production bucket across environments. S3_BUCKET= S3_ENDPOINT= S3_REGION=garage S3_ACCESS_KEY_ID= S3_SECRET_ACCESS_KEY= # Canonical public origin used in absolute campaign invite links. In production # this must be an exact HTTPS non-local origin: no credentials, path other than # `/`, query, or fragment. Production ignores request headers and invite # creation fails closed when this value is invalid. Development/test accepts # request-derived origins only for exact localhost, 127.0.0.1, or ::1 hosts and # normalizes them to HTTP; otherwise this configured origin is the only fallback. NEXT_PUBLIC_SITE_URL=http://localhost:3000 # Shared secret guarding POST /api/revalidate, which busts ISR cache tags on demand. # Needed after direct-DB writes (e.g. `pnpm db:seed:posts`, Onda 0 migrations) since those # bypass the deployed Payload hooks. Default tag is `posts`; allowlisted tags also include # `global_privacy-policy` for /privacidade. MUST be set in the Vercel project env for production. Generate with e.g. `openssl rand -hex 32`. REVALIDATE_SECRET=YOUR_REVALIDATE_SECRET_HERE # Web Push (D2 — /campanha notifications). Generate VAPID keys with: npx web-push generate-vapid-keys VAPID_PUBLIC_KEY= VAPID_PRIVATE_KEY= VAPID_SUBJECT=mailto:campanha@jorgesolla.com.br NEXT_PUBLIC_VAPID_PUBLIC_KEY= # Campaign password reset emails (Resend). Required in production for forgot-password. RESEND_API_KEY=YOUR_RESEND_API_KEY_HERE CAMPAIGN_EMAIL_FROM=campanha@jorgesolla.com.br CAMPAIGN_EMAIL_FROM_NAME=Campanha Jorge Solla # Note: the automated test suite ignores this file and reads .env.test instead, # and only ever runs against a database whose name ends with "_test". # DeepSeek API key for the AI chat feature (Sollinha) — the LLM talks directly # to api.deepseek.com (cache-hit input is ~6x cheaper than via Deep Infra). # Get one at https://platform.deepseek.com/api_keys DEEPSEEK_API_KEY=YOUR_DEEPSEEK_API_KEY_HERE # Deep Infra API key for the Sollinha voice transcription (STT, Whisper large-v3) # — cheapest speech-to-text around ($0.00045/audio min). Get one at https://deepinfra.com DEEPINFRA_API_KEY=YOUR_DEEPINFRA_API_KEY_HERE # C114 — Google Calendar mirror (Agenda da Campanha): base64 of the Google Cloud # service-account JSON key (cat key.json | base64 -w0). The service account must # be granted "make changes to events" on the campaign's public calendar; the # calendar ID itself is configured by an admin in the `googleCalendarSync` # collection. Absent/malformed → the agenda shows "não configurado" and the # mirror stays off — the Teqo agenda never depends on this. GOOGLE_CALENDAR_SERVICE_ACCOUNT_KEY= # C149 — Google OAuth client pair for the "Conectar com o Google" button. Create # a "Web application" OAuth client in the same GCP project, register the # redirect URIs (`/campanha/agenda/google-oauth/callback`, plus the # local dev origin) and publish the app to production (unverified is fine for # internal use) so the refresh token does not expire in ~7 days. Absent → the # dialog falls back to the service-account runbook and the mirror keeps working # via `GOOGLE_CALENDAR_SERVICE_ACCOUNT_KEY`. GOOGLE_CALENDAR_OAUTH_CLIENT_ID= GOOGLE_CALENDAR_OAUTH_CLIENT_SECRET= # C167 — binary used to cut the exact [início,fim] MP4 of the acervo. Empty # falls back to `ffmpeg` from PATH (the production image installs it); tests # point it at a fake binary, and a host without ffmpeg can install it or set # this to a wrapper. FFMPEG_PATH=