ZoomProp

Operator console

Operator console

Last updated 5/3/2026

ZoomProp Operator Console

Document ID: OPS-CONSOLE-001 Classification: Internal — Restricted to Engineering, DevOps, and Support Staff Repository: zoomprop/zp-alpha Stack: Next.js 15 (Turbopack), TypeScript, Clerk Auth, Elasticsearch, OpenTelemetry, Knock, Vitest, Playwright Last Updated: Based on commit 08ce25f (PR #463 merged — staging CI baseline + orchestrator cost guards)


Table of Contents

  1. Platform Overview
  2. Admin Dashboard Capabilities and Routes
  3. Internal Tooling Inventory
  4. Operational Workflows
  5. Monitoring and Alerting
  6. Support Workflows
  7. Environment Management
  8. Secret Management
  9. Health Check Endpoints and Status
  10. Escalation Matrix

1. Platform Overview

ZoomProp is an AI-powered real estate investment platform (zoomprop-ai-platform, v0.1.0). The frontend is a Next.js 15 application served from zp-alpha. A companion fetch microservice lives at zp-fetch-service/ and is independently containerized via zp-fetch-service/Dockerfile. The platform integrates Clerk for identity, Elasticsearch for property search, OpenAI/LangChain for AI features, Knock for notification delivery, Mapbox and Google Maps for spatial features, and OpenTelemetry for distributed tracing.

The archive/legacy-api-backup/ tree contains deprecated route handlers retained for reference. The archive/root-cleanup-20250804/ tree contains service files cleaned from the root on 2025-08-04. Neither directory is deployed.


2. Admin Dashboard Capabilities and Routes

2.1 Active API Surface

All routes live under src/app/api/. The following groupings define operational domains.

Authentication and Organization Management

RouteFileOperator Use
GET/POST /api/auth/sessionsrc/app/api/auth/session/route.tsInspect or invalidate active sessions
POST /api/auth/active-orgsrc/app/api/auth/active-org/route.tsSwitch or inspect a user's active organization context
GET /api/auth/testsrc/app/api/auth/test/route.tsValidate Clerk integration in non-production environments

User and Alert Management

RouteFileOperator Use
GET/POST /api/alerts/userssrc/app/api/alerts/users/route.tsList users subscribed to alert channels
POST /api/alerts/configuresrc/app/api/alerts/configure/route.tsSet alert rules for a user or organization
GET /api/alerts/historysrc/app/api/alerts/history/route.tsRetrieve delivery history for audit
POST /api/alerts/testsrc/app/api/alerts/test/route.tsFire a test notification via Knock; used to verify delivery pipelines
POST /api/alerts/triggersrc/app/api/alerts/trigger/route.tsManually trigger an alert workflow
POST /api/alerts/messages/archivesrc/app/api/alerts/messages/archive/route.tsBulk-archive notifications
POST /api/alerts/messages/unarchivesrc/app/api/alerts/messages/unarchive/route.tsRestore archived notifications
GET/POST /api/alerts/preferencessrc/app/api/alerts/preferences/route.tsRead or write per-user notification preferences
GET/POST /api/alert-filterssrc/app/api/alert-filters/route.tsManage saved filter definitions
GET/POST /api/alert-filters/assignmentssrc/app/api/alert-filters/assignments/route.tsAssign filters to users or organizations

Analytics and Performance Monitoring

RouteFileOperator Use
GET /api/analytics-dashboardsrc/app/api/analytics-dashboard/route.tsAggregate dashboard metrics
GET /api/analytics/performancesrc/app/api/analytics/performance/route.tsPlatform-wide performance KPIs
GET /api/analytics/portfoliosrc/app/api/analytics/portfolio/route.tsPortfolio-level analytics by org
GET /api/analytics/marketssrc/app/api/analytics/markets/route.tsMarket data aggregations
GET /api/analytics/propertiessrc/app/api/analytics/properties/route.tsPer-property analytics
GET /api/analytics/appreciation-distributionsrc/app/api/analytics/appreciation-distribution/route.tsValue-appreciation histogram data
GET /api/ai/performance-monitoringsrc/app/api/ai/performance-monitoring/route.tsAI inference latency and cost tracking
GET /api/automation/analyticssrc/app/api/automation/analytics/route.tsAutomation pipeline execution metrics

AI Operations

RouteFileOperator Use
GET/POST /api/ai/conversationssrc/app/api/ai/conversations/route.tsList all chat conversations
GET/DELETE /api/ai/conversations/:idsrc/app/api/ai/conversations/[id]/route.tsInspect or delete a specific conversation
GET/POST /api/ai/personassrc/app/api/ai/personas/route.tsManage AI persona configurations
POST /api/ai/intentsrc/app/api/ai/intent/route.tsClassify user intent; useful for debugging AI routing
GET/POST /api/ai-search-templatessrc/app/api/ai-search-templates/route.tsManage AI-driven search template library
POST /api/actions/analyze-property-investigationsrc/app/api/actions/analyze-property-investigation/route.tsTrigger a full LangGraph property investigation

Automation Board Configuration

RouteFileOperator Use
GET/POST /api/automation/board-configsrc/app/api/automation/board-config/route.tsRead or write kanban automation board state

2.2 Legacy Admin Capabilities (Archive — Not Deployed)

The archive/legacy-api-backup/ tree documents historical operator capabilities that were available in the v0.x platform. These routes are not callable in the current deployment but are retained for reference when migrating capabilities:

  • archive/legacy-api-backup/operator/route.ts — Direct operator mutation endpoint
  • archive/legacy-api-backup/update-org-metadata/route.ts — Org metadata patching
  • archive/legacy-api-backup/update-org-subscription/route.ts — Subscription tier adjustment
  • archive/legacy-api-backup/update-user-metadata/route.ts — User metadata patching
  • archive/legacy-api-backup/users-list/route.ts — Full user enumeration
  • archive/legacy-api-backup/get-org-metadata/route.ts — Org metadata read
  • archive/legacy-api-backup/ensure-organization/route.ts — Idempotent org creation
  • archive/legacy-api-backup/check-org-subscription/route.ts — Subscription status check
  • archive/legacy-api-backup/waiting-list/route.ts — Waitlist management

TECH-001: No first-party admin panel UI exists in the current v0.1.0 release. Admin operations are performed via direct API calls, Clerk's dashboard, or the scripts described in §3. Building a dedicated /admin UI surface is a known gap.

2.3 Subscription and Billing (Free Query Grant)

PR #455 introduced a monthly free query grant API (feat: add monthly free queries grant API and context integration for unpaid users). The route src/app/api/auth/session/route.ts or an adjacent route manages this grant. Operators can reset or inspect a user's free query count through the Clerk user metadata interface until a dedicated admin API is built.


3. Internal Tooling Inventory

3.1 NPM Scripts (package.json)

All scripts are invoked from the repository root via npm run <script> or the equivalent pnpm/yarn command.

Development

ScriptCommandPurpose
devnext dev --turbopackStart local dev server with Turbopack bundler
buildnext buildProduction build
startnext startServe production build locally

Code Quality

ScriptCommandPurpose
lintnext lintESLint pass across the project
lint:fixnext lint --fixAuto-fix ESLint violations
formatprettier --write .Format all files in-place
format:checkprettier --check .CI format validation
type-checktsc --noEmitTypeScript strict type validation without emitting output

Note: next.config.ts sets ignoreBuildErrors: true and eslint.ignoreDuringBuilds: true. This means npm run build alone is insufficient for catching type or lint errors. Operators must run npm run type-check and npm run lint explicitly before promoting a release.

Testing

ScriptCommandPurpose
testvitestRun all unit tests in watch mode
test:unitvitest runSingle-pass unit test run (CI mode)
test:coveragevitest --coverageUnit tests with coverage report
test:coverage:reportvitest --coverage && npx serve coverageGenerate and serve HTML coverage report
test:e2eplaywright testFull Playwright end-to-end suite
test:e2e:uiplaywright test --uiPlaywright with interactive UI
test:e2e:debugplaywright test --debugPlaywright with debugger attached
test:e2e:headedplaywright test --headedPlaywright with visible browser
test:allnpm run test:unit && npm run test:e2eFull test suite, no coverage
test:all:coveragenpm run test:coverage && npm run test:e2eFull test suite with coverage

Theme Tooling

ScriptCommandPurpose
theme:audittsx tools/scripts/theme-audit-runner.tsRun design token audit
theme:audit:verbosetsx tools/scripts/theme-audit-runner.ts --verboseVerbose token audit output
theme:audit:reporttsx tools/scripts/theme-audit-runner.ts --output=theme-audit-report.jsonWrite JSON audit report to theme-audit-report.json

3.2 CLI Tools and Scripts

tools/scripts/theme-audit-runner.ts

The theme audit runner validates design token consistency across the component library. It is invoked by the three theme:* scripts above. Run before major releases to catch unresolved token references or theme contract violations introduced by PRs that touch components.json or Tailwind configuration.

Usage:

# Standard audit to stdout
npm run theme:audit

# Machine-readable output for CI diff checks
npm run theme:audit:report

api_tests/ — Python API Integration Test Suite

A standalone Python test suite exists at api_tests/ for integration testing against the ZoomProp backend API. This suite is independent of the Node/Vitest stack.

FilePurpose
api_tests/config/settings.pyEnvironment configuration (API base URL, credentials)
api_tests/conftest.pyPytest fixtures and session setup
api_tests/utils/api_client.pyHTTP client wrapper for API calls
api_tests/utils/auth_helper.pyAuthentication token acquisition helpers
api_tests/fixtures/property_fixtures.pyProperty test data factories
api_tests/integration/test_property_workflow.pyEnd-to-end property workflow integration tests
api_tests/unit/test_properties.pyUnit-level property API tests

Running the Python suite:

cd api_tests
pip install -r requirements.txt
pytest                     # all tests
pytest unit/               # unit only
pytest integration/        # integration only
pytest --cov               # with coverage (see .coveragerc)

Configuration is controlled by api_tests/config/settings.py. Set the target environment via environment variables documented in that file before running against staging or production.

zp-fetch-service/ — Data Fetch Microservice

The zp-fetch-service/Dockerfile defines a containerized data fetch service that runs independently of the Next.js application. This service is responsible for fetching external property and market data. Build and deploy lifecycle is separate from the main application.

# Build
docker build -t zp-fetch-service:latest ./zp-fetch-service

# Run locally
docker run --env-file .env.local zp-fetch-service:latest

3.3 Pre-commit Hooks

.husky/pre-commit is installed via "prepare": "husky" in package.json. The hook runs before every commit. Operators adding or modifying hooks must update .husky/pre-commit and ensure husky is initialized (npm run prepare) after cloning.

3.4 Static Analysis and Code Quality Integrations

ToolConfig FileScope
Codacy.codacy.ymlAutomated code quality gates on PRs
DeepSource.deepsource.tomlContinuous static analysis
Audit CI.auditcircDependency vulnerability scanning
Prettier.prettierrc.json, .prettierignoreCode formatting
ESLintnext lintNext.js-aware linting
TypeScripttsconfig.jsonStrict type checking ("strict": true)

4. Operational Workflows

4.1 Deployment Workflow

The repository uses GitHub Actions for CI/CD. Relevant workflow files:

WorkflowFileTrigger
PR Checks.github/workflows/pr-checks.ymlPull request opened, synchronized, or reopened
Unit Tests.github/workflows/test.ymlPush and PR
Test Coverage.github/workflows/test-coverage.ymlPush and PR
Alert Testing.github/workflows/alert-testing.ymlPush and PR (alert-related paths)

PR merge → deploy sequence:

  1. Developer opens PR against main (or staging branch).
  2. .github/workflows/pr-checks.yml runs: format check, lint, type-check, unit tests.
  3. .github/workflows/test-coverage.yml generates coverage and uploads artifact.
  4. Code owners review per the Codacy and DeepSource gates.
  5. PR merges. Deployment pipeline (not fully visible in this repository snapshot) picks up the merge commit.
  6. npm run build produces the Next.js production output.
  7. The zp-fetch-service Docker image is built separately and deployed to its container runtime.

PR #463 (M0: repair staging CI baseline + orchestrator cost guards) established the current CI baseline and introduced cost guards for AI orchestrator calls. Operators should review this PR before modifying AI-related routes or increasing model call frequency.

4.2 Rollback Procedure

Because TypeScript and ESLint errors are suppressed during build (ignoreBuildErrors: true, ignoreDuringBuilds: true), a broken build may deploy silently. Rollback is therefore the primary recovery mechanism for runtime regressions.

Rollback steps:

  1. Identify the last known-good commit hash from GitHub (reference recent commits: 08ce25f, ee3b2fa, 69c94a5).
  2. Trigger a redeployment of the last known-good image from the deployment platform (Vercel, Railway, or equivalent — confirm with DevOps).
  3. If the regression involves AI cost overruns, verify the orchestrator cost guards introduced in PR #463 are intact.
  4. Communicate rollback status in the #incidents Slack channel with the affected commit range.
  5. Open a hotfix PR using .github/PULL_REQUEST_TEMPLATE/hotfix.md to track the fix.
  6. After the hotfix merges, confirm CI green before re-promoting to production.

4.3 Feature Flags

No dedicated feature flag service (LaunchDarkly, Unleash, etc.) is observed in the current dependency manifest. Feature control is implemented through:

  • Clerk user/organization metadata: The free query grant system (PR #455) stores entitlement state in Clerk org metadata. Operators toggle feature access by updating org metadata via the Clerk dashboard or archive/legacy-api-backup/update-org-metadata/route.ts patterns (when re-implemented in active routes).
  • Environment variables: Features gated on process.env.* values are toggled by updating the deployment environment's variable set (see §7).
  • AI persona configuration: GET/POST /api/ai/personas allows operators to modify AI behavior at runtime without a code deploy.

TECH-002: A formal feature flag service is not present in v0.1.0. This is a gap; complex multi-variant rollouts require environment restarts. Recommend adding a flag service before the v1.0 Growth milestone.

4.4 User Management

User identity and organization management is delegated to Clerk. Operator actions available via the Clerk dashboard:

  • Create, suspend, or delete user accounts
  • Manage organization memberships and roles
  • Inspect session tokens and force sign-out
  • Read and write user/organization metadata (entitlements, free query grants, subscription tier markers)
  • View sign-in/sign-up audit logs

Active API routes that complement Clerk dashboard operations:

  • POST /api/auth/active-org — Force an organization context switch server-side
  • GET /api/auth/session — Inspect the current session payload
  • GET /api/alerts/users — List alert-subscribed users

Onboarding flow operator controls: The multi-step onboarding wizard (src/app/(auth)/onboarding/) progresses users through business verification, identity verification, billing setup, geographic focus, and investment interests steps. If a user is stuck in onboarding, an operator can inspect their Clerk metadata to identify which step state is persisted and reset it manually.


5. Monitoring and Alerting

5.1 Observability Stack

LayerTechnologyIntegration Point
Distributed TracingOpenTelemetry (@opentelemetry/api v1.9.0, @opentelemetry/sdk-trace-base v2.0.1, @opentelemetry/core v2.0.1)Instrumented at API route and LangChain call sites
AI Performance Monitoring/api/ai/performance-monitoringTracks inference latency, token counts, and model call costs
Notification DeliveryKnock (@knocklabs/node v1.11.1, @knocklabs/client v0.15.1)Tracks notification delivery, bounce, and open events
Automation Analytics/api/automation/analyticsPipeline execution counts, durations, and failure rates

5.2 What Is Observed

AI Subsystem

  • Route: GET /api/ai/performance-monitoring
  • Metrics collected: Inference latency per model call, token consumption per conversation, cost per request, LangGraph node execution times
  • Cost guards: PR #463 introduced orchestrator cost guards. These guards should cap runaway AI spending. Verify they are active by checking the src/app/api/ai/ route handlers for budget-limit logic.

Alert and Notification Delivery

  • Route: GET /api/alerts/history
  • Metrics: Delivery success/failure rates per channel, alert trigger frequency, message archive rate
  • Knock dashboard: Real-time notification delivery status, per-workflow success rates, and per-user preference overrides are visible in the Knock console at app.knock.com.

Analytics Pipeline

  • Route: GET /api/analytics/performance
  • Metrics: API response times, property search query counts, portfolio access frequency
  • Route: GET /api/automation/analytics
  • Metrics: Automation board workflow execution counts, step failure rates

5.3 GitHub Actions Monitoring

The .github/workflows/alert-testing.yml workflow specifically tests the alert delivery path on every relevant push. This provides a continuous canary for the Knock integration. A failing alert-testing workflow run signals a degraded notification delivery pipeline.

5.4 Thresholds and Escalation

SignalThresholdEscalation Path
AI orchestrator cost spikeDefined by cost guards in PR #463Alert on-call engineer → review /api/ai/performance-monitoring → rate-limit or disable specific AI routes
Alert delivery failure rate>5% failures over 15-minute window (verify in Knock dashboard)Support engineer → Knock status page → escalate to backend engineer if systemic
Playwright E2E test failure in CIAny test failure on mainBlock deploy → assign to owning engineer
Dependency vulnerabilityaudit-ci gate fails on PRBlock merge → update or pin affected package
Coverage regressionBelow project baseline (verify in test-coverage.yml artifact)Flag in PR review → author must restore coverage before merge

6. Support Workflows

6.1 Issue Triage

Issues are submitted via GitHub using structured templates:

TemplateFileUse Case
Bug Report.github/ISSUE_TEMPLATE/bug_report.ymlUser-facing or internal defects
Feature Request.github/ISSUE_TEMPLATE/feature_request.ymlNew capability requests
Config.github/ISSUE_TEMPLATE/config.ymlTemplate routing configuration

Triage SLO (target):

  • P1 (production down / data loss risk): 1 hour to engineer assignment
  • P2 (major feature broken): 4 hours to assignment
  • P3 (minor defect): Next sprint planning

6.2 PR Workflow for Fixes

The repository provides three PR templates:

TemplateFileUse Case
Feature.github/PULL_REQUEST_TEMPLATE/feature.mdNew feature development
Bugfix.github/PULL_REQUEST_TEMPLATE/bugfix.mdNon-urgent defect fixes
Hotfix.github/PULL_REQUEST_TEMPLATE/hotfix.mdUrgent production fixes bypassing normal sprint flow

All PRs are gated by .github/workflows/pr-checks.yml. Hotfix PRs should still pass CI before merge. If CI must be bypassed for a critical incident, document the bypass reason in the PR and open a follow-up issue immediately.

6.3 Common Issues and Resolution Playbooks

PLAY-001: User Cannot Complete Onboarding

Symptoms: User reports being stuck on one of the onboarding steps (business-verification-form.tsx, identity-verification-step.tsx, billing-setup-step.tsx, etc.).

Resolution:

  1. Pull the user's Clerk metadata from the Clerk dashboard.
  2. Identify the persisted step state. Onboarding progress is stored in user or organization metadata.
  3. If the billing step (billing-setup-step.tsx / embedded-checkout.tsx) is stuck, verify Stripe checkout session creation is functional.
  4. Clear or reset the stuck step state in Clerk metadata.
  5. Advise the user to reload and re-attempt from src/app/(auth)/onboarding/page.tsx.
  6. If the issue recurs, open a bug report using .github/ISSUE_TEMPLATE/bug_report.yml.

PLAY-002: AI Chat Not Responding

Symptoms: /api/ai/chat returns errors or the chat UI at the dashboard stalls.

Resolution:

  1. Check OPENAI_API_KEY is valid and within quota using the OpenAI dashboard.
  2. Inspect GET /api/ai/performance-monitoring for recent latency spikes or error rates.
  3. Review the LangGraph orchestrator cost guard state (PR #463 context).
  4. Check GET /api/ai/conversations for stuck conversation state that may block the chat stream.
  5. If the issue is model-side, test the @ai-sdk/openai integration using GET /api/auth/test pattern to isolate Next.js from OpenAI.
  6. Verify serverExternalPackages in next.config.ts includes langchain, @langchain/core, @langchain/community (it does as of current config).

PLAY-003: Alerts Not Delivering

Symptoms: Users report not receiving property or market alerts.

Resolution:

  1. Fire a test notification using POST /api/alerts/test to verify the Knock pipeline is alive.
  2. Check GET /api/alerts/history for the affected user to confirm triggers are firing.
  3. Inspect GET /api/alerts/preferences for the user — delivery may be disabled.
  4. Check the Knock dashboard for workflow execution logs and channel delivery status.
  5. Verify KNOCK_API_KEY (or equivalent secret) is set in the deployment environment (see §8).
  6. If the alert-testing GitHub Actions workflow is failing, treat as a systemic pipeline failure and escalate to backend engineering.

PLAY-004: Elasticsearch Property Search Failing

Symptoms: Search returns empty results or 500 errors. The @elastic/elasticsearch v8.18.2 client is used.

Resolution:

  1. Verify ELASTICSEARCH_URL and credentials are correctly set in the deployment environment.
  2. Check tests/api/search/route.test.ts and api_tests/unit/test_properties.py for the expected API contract.
  3. Run the Python integration suite against staging: cd api_tests && pytest integration/.
  4. Inspect Elasticsearch cluster health directly.
  5. Review archive/legacy-api-backup/elastic-search/ for historical route behavior if debugging a regression.

PLAY-005: Theme or UI Inconsistency

Symptoms: Visual elements appear broken after a theme-related PR (reference open PR #458 — "Fix theme persistence").

Resolution:

  1. Run npm run theme:audit to identify token violations.
  2. Run npm run theme:audit:report to produce theme-audit-report.json for diffing.
  3. Trace the issue to the ThemeProvider wiring documented in PR #458.
  4. Ensure use-theme custom hook is wired to the ThemeProvider, not the default Next.js theme provider.

7. Environment Management

7.1 Environment Tiers

TierAPI Base URLImage Domain Pattern
Productionhttps://api.zoomprop.comapi.zoomprop.com (configured in next.config.ts images.domains)
Staginghttps://api-staging.zoomprop.comapi-staging.zoomprop.com (configured in next.config.ts)
Local DevelopmentConfigured via .env.local, defaults to localhostN/A

The NEXT_PUBLIC_ZOOMPROP_API_URL_V1 and NEXT_PUBLIC_ZOOMPROP_WEBSOCKET_URL environment variables switch the API target between tiers. Both are surfaced through next.config.ts.

7.2 Environment Variables

The following variables are declared in next.config.ts and must be present in each deployment tier:

VariablePurposePublic
NEXT_PUBLIC_ZOOMPROP_API_URL_V1ZoomProp backend API base URLYes
NEXT_PUBLIC_ZOOMPROP_WEBSOCKET_URLWebSocket endpoint for real-time featuresYes
NEXT_PUBLIC_MAPBOX_ACCESS_TOKENMapbox GL JS map renderingYes
OPENAI_API_KEYOpenAI API authentication for AI featuresNo — server only
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYClerk frontend authenticationYes
NEXT_PUBLIC_CLERK_SIGN_IN_URLClerk sign-in redirect targetYes
NEXT_PUBLIC_CLERK_SIGN_UP_URLClerk sign-up redirect targetYes

Additional variables inferred from dependencies (not exhaustively listed in the visible next.config.ts fragment):

VariableDependencyNotes
CLERK_SECRET_KEY@clerk/nextjsServer-side Clerk operations
KNOCK_API_KEY@knocklabs/nodeKnock notification service (server-side)
NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY@knocklabs/reactKnock client-side feed
NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID@knocklabs/reactKnock in-app feed channel ID
ELASTICSEARCH_URL@elastic/elasticsearchElasticsearch cluster endpoint
ELASTICSEARCH_API_KEY@elastic/elasticsearchElasticsearch authentication
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY@googlemaps/js-api-loaderGoogle Maps static and dynamic maps

7.3 Node Version

.nvmrc pins the Node.js version. Engineers and CI runners must use the version specified in .nvmrc. Run nvm use in the repository root to activate it.

7.4 Local Development Setup

Refer to .github/QUICK_SETUP_CHECKLIST.md and .github/FIRST_TIME_USER_GUIDE.md for the authoritative onboarding sequence. The high-level steps are:

  1. nvm use (ensure correct Node version from .nvmrc)
  2. npm install (installs all dependencies including Husky hooks via prepare)
  3. Copy .env.example to .env.local and populate all required variables
  4. npm run dev to start the Turbopack dev server
  5. Verify npm run type-check and npm run lint pass before committing

8. Secret Management

8.1 Secret Inventory

Secret IDSecret NameServiceRotation Frequency
SEC-001OPENAI_API_KEYOpenAI90 days or immediately on suspected exposure
SEC-002CLERK_SECRET_KEYClerk180 days or on team member offboarding
SEC-003NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYClerkOn Clerk application rotation
SEC-004KNOCK_API_KEYKnock180 days or on team member offboarding
SEC-005NEXT_PUBLIC_KNOCK_PUBLIC_API_KEYKnockOn Knock workspace rotation
SEC-006ELASTICSEARCH_URLElasticsearchOn cluster migration or credential compromise
SEC-007ELASTICSEARCH_API_KEYElasticsearch90 days
SEC-008NEXT_PUBLIC_MAPBOX_ACCESS_TOKENMapbox365 days (scope-restricted tokens preferred)
SEC-009NEXT_PUBLIC_GOOGLE_MAPS_API_KEYGoogle Maps365 days (API key restrictions enforced in GCP console)

8.2 Secret Storage

  • Production and Staging: Secrets are injected as environment variables at the deployment platform level (Vercel environment variables, or equivalent container secrets). They are never committed to the repository.
  • Local Development: Stored in .env.local which is listed in .gitignore.