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
- Platform Overview
- Admin Dashboard Capabilities and Routes
- Internal Tooling Inventory
- Operational Workflows
- Monitoring and Alerting
- Support Workflows
- Environment Management
- Secret Management
- Health Check Endpoints and Status
- 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
| Route | File | Operator Use |
|---|---|---|
GET/POST /api/auth/session | src/app/api/auth/session/route.ts | Inspect or invalidate active sessions |
POST /api/auth/active-org | src/app/api/auth/active-org/route.ts | Switch or inspect a user's active organization context |
GET /api/auth/test | src/app/api/auth/test/route.ts | Validate Clerk integration in non-production environments |
User and Alert Management
| Route | File | Operator Use |
|---|---|---|
GET/POST /api/alerts/users | src/app/api/alerts/users/route.ts | List users subscribed to alert channels |
POST /api/alerts/configure | src/app/api/alerts/configure/route.ts | Set alert rules for a user or organization |
GET /api/alerts/history | src/app/api/alerts/history/route.ts | Retrieve delivery history for audit |
POST /api/alerts/test | src/app/api/alerts/test/route.ts | Fire a test notification via Knock; used to verify delivery pipelines |
POST /api/alerts/trigger | src/app/api/alerts/trigger/route.ts | Manually trigger an alert workflow |
POST /api/alerts/messages/archive | src/app/api/alerts/messages/archive/route.ts | Bulk-archive notifications |
POST /api/alerts/messages/unarchive | src/app/api/alerts/messages/unarchive/route.ts | Restore archived notifications |
GET/POST /api/alerts/preferences | src/app/api/alerts/preferences/route.ts | Read or write per-user notification preferences |
GET/POST /api/alert-filters | src/app/api/alert-filters/route.ts | Manage saved filter definitions |
GET/POST /api/alert-filters/assignments | src/app/api/alert-filters/assignments/route.ts | Assign filters to users or organizations |
Analytics and Performance Monitoring
| Route | File | Operator Use |
|---|---|---|
GET /api/analytics-dashboard | src/app/api/analytics-dashboard/route.ts | Aggregate dashboard metrics |
GET /api/analytics/performance | src/app/api/analytics/performance/route.ts | Platform-wide performance KPIs |
GET /api/analytics/portfolio | src/app/api/analytics/portfolio/route.ts | Portfolio-level analytics by org |
GET /api/analytics/markets | src/app/api/analytics/markets/route.ts | Market data aggregations |
GET /api/analytics/properties | src/app/api/analytics/properties/route.ts | Per-property analytics |
GET /api/analytics/appreciation-distribution | src/app/api/analytics/appreciation-distribution/route.ts | Value-appreciation histogram data |
GET /api/ai/performance-monitoring | src/app/api/ai/performance-monitoring/route.ts | AI inference latency and cost tracking |
GET /api/automation/analytics | src/app/api/automation/analytics/route.ts | Automation pipeline execution metrics |
AI Operations
| Route | File | Operator Use |
|---|---|---|
GET/POST /api/ai/conversations | src/app/api/ai/conversations/route.ts | List all chat conversations |
GET/DELETE /api/ai/conversations/:id | src/app/api/ai/conversations/[id]/route.ts | Inspect or delete a specific conversation |
GET/POST /api/ai/personas | src/app/api/ai/personas/route.ts | Manage AI persona configurations |
POST /api/ai/intent | src/app/api/ai/intent/route.ts | Classify user intent; useful for debugging AI routing |
GET/POST /api/ai-search-templates | src/app/api/ai-search-templates/route.ts | Manage AI-driven search template library |
POST /api/actions/analyze-property-investigation | src/app/api/actions/analyze-property-investigation/route.ts | Trigger a full LangGraph property investigation |
Automation Board Configuration
| Route | File | Operator Use |
|---|---|---|
GET/POST /api/automation/board-config | src/app/api/automation/board-config/route.ts | Read 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 endpointarchive/legacy-api-backup/update-org-metadata/route.ts— Org metadata patchingarchive/legacy-api-backup/update-org-subscription/route.ts— Subscription tier adjustmentarchive/legacy-api-backup/update-user-metadata/route.ts— User metadata patchingarchive/legacy-api-backup/users-list/route.ts— Full user enumerationarchive/legacy-api-backup/get-org-metadata/route.ts— Org metadata readarchive/legacy-api-backup/ensure-organization/route.ts— Idempotent org creationarchive/legacy-api-backup/check-org-subscription/route.ts— Subscription status checkarchive/legacy-api-backup/waiting-list/route.ts— Waitlist management
TECH-001: No first-party admin panel UI exists in the current
v0.1.0release. Admin operations are performed via direct API calls, Clerk's dashboard, or the scripts described in §3. Building a dedicated/adminUI 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
| Script | Command | Purpose |
|---|---|---|
dev | next dev --turbopack | Start local dev server with Turbopack bundler |
build | next build | Production build |
start | next start | Serve production build locally |
Code Quality
| Script | Command | Purpose |
|---|---|---|
lint | next lint | ESLint pass across the project |
lint:fix | next lint --fix | Auto-fix ESLint violations |
format | prettier --write . | Format all files in-place |
format:check | prettier --check . | CI format validation |
type-check | tsc --noEmit | TypeScript strict type validation without emitting output |
Note:
next.config.tssetsignoreBuildErrors: trueandeslint.ignoreDuringBuilds: true. This meansnpm run buildalone is insufficient for catching type or lint errors. Operators must runnpm run type-checkandnpm run lintexplicitly before promoting a release.
Testing
| Script | Command | Purpose |
|---|---|---|
test | vitest | Run all unit tests in watch mode |
test:unit | vitest run | Single-pass unit test run (CI mode) |
test:coverage | vitest --coverage | Unit tests with coverage report |
test:coverage:report | vitest --coverage && npx serve coverage | Generate and serve HTML coverage report |
test:e2e | playwright test | Full Playwright end-to-end suite |
test:e2e:ui | playwright test --ui | Playwright with interactive UI |
test:e2e:debug | playwright test --debug | Playwright with debugger attached |
test:e2e:headed | playwright test --headed | Playwright with visible browser |
test:all | npm run test:unit && npm run test:e2e | Full test suite, no coverage |
test:all:coverage | npm run test:coverage && npm run test:e2e | Full test suite with coverage |
Theme Tooling
| Script | Command | Purpose |
|---|---|---|
theme:audit | tsx tools/scripts/theme-audit-runner.ts | Run design token audit |
theme:audit:verbose | tsx tools/scripts/theme-audit-runner.ts --verbose | Verbose token audit output |
theme:audit:report | tsx tools/scripts/theme-audit-runner.ts --output=theme-audit-report.json | Write 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.
| File | Purpose |
|---|---|
api_tests/config/settings.py | Environment configuration (API base URL, credentials) |
api_tests/conftest.py | Pytest fixtures and session setup |
api_tests/utils/api_client.py | HTTP client wrapper for API calls |
api_tests/utils/auth_helper.py | Authentication token acquisition helpers |
api_tests/fixtures/property_fixtures.py | Property test data factories |
api_tests/integration/test_property_workflow.py | End-to-end property workflow integration tests |
api_tests/unit/test_properties.py | Unit-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
| Tool | Config File | Scope |
|---|---|---|
| Codacy | .codacy.yml | Automated code quality gates on PRs |
| DeepSource | .deepsource.toml | Continuous static analysis |
| Audit CI | .auditcirc | Dependency vulnerability scanning |
| Prettier | .prettierrc.json, .prettierignore | Code formatting |
| ESLint | next lint | Next.js-aware linting |
| TypeScript | tsconfig.json | Strict type checking ("strict": true) |
4. Operational Workflows
4.1 Deployment Workflow
The repository uses GitHub Actions for CI/CD. Relevant workflow files:
| Workflow | File | Trigger |
|---|---|---|
| PR Checks | .github/workflows/pr-checks.yml | Pull request opened, synchronized, or reopened |
| Unit Tests | .github/workflows/test.yml | Push and PR |
| Test Coverage | .github/workflows/test-coverage.yml | Push and PR |
| Alert Testing | .github/workflows/alert-testing.yml | Push and PR (alert-related paths) |
PR merge → deploy sequence:
- Developer opens PR against
main(or staging branch). .github/workflows/pr-checks.ymlruns: format check, lint, type-check, unit tests..github/workflows/test-coverage.ymlgenerates coverage and uploads artifact.- Code owners review per the Codacy and DeepSource gates.
- PR merges. Deployment pipeline (not fully visible in this repository snapshot) picks up the merge commit.
npm run buildproduces the Next.js production output.- The
zp-fetch-serviceDocker 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:
- Identify the last known-good commit hash from GitHub (reference recent commits:
08ce25f,ee3b2fa,69c94a5). - Trigger a redeployment of the last known-good image from the deployment platform (Vercel, Railway, or equivalent — confirm with DevOps).
- If the regression involves AI cost overruns, verify the orchestrator cost guards introduced in PR #463 are intact.
- Communicate rollback status in the
#incidentsSlack channel with the affected commit range. - Open a
hotfixPR using.github/PULL_REQUEST_TEMPLATE/hotfix.mdto track the fix. - 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.tspatterns (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/personasallows 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 thev1.0Growth 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-sideGET /api/auth/session— Inspect the current session payloadGET /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
| Layer | Technology | Integration Point |
|---|---|---|
| Distributed Tracing | OpenTelemetry (@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-monitoring | Tracks inference latency, token counts, and model call costs |
| Notification Delivery | Knock (@knocklabs/node v1.11.1, @knocklabs/client v0.15.1) | Tracks notification delivery, bounce, and open events |
| Automation Analytics | /api/automation/analytics | Pipeline 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
| Signal | Threshold | Escalation Path |
|---|---|---|
| AI orchestrator cost spike | Defined by cost guards in PR #463 | Alert 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 CI | Any test failure on main | Block deploy → assign to owning engineer |
| Dependency vulnerability | audit-ci gate fails on PR | Block merge → update or pin affected package |
| Coverage regression | Below 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:
| Template | File | Use Case |
|---|---|---|
| Bug Report | .github/ISSUE_TEMPLATE/bug_report.yml | User-facing or internal defects |
| Feature Request | .github/ISSUE_TEMPLATE/feature_request.yml | New capability requests |
| Config | .github/ISSUE_TEMPLATE/config.yml | Template 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:
| Template | File | Use Case |
|---|---|---|
| Feature | .github/PULL_REQUEST_TEMPLATE/feature.md | New feature development |
| Bugfix | .github/PULL_REQUEST_TEMPLATE/bugfix.md | Non-urgent defect fixes |
| Hotfix | .github/PULL_REQUEST_TEMPLATE/hotfix.md | Urgent 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:
- Pull the user's Clerk metadata from the Clerk dashboard.
- Identify the persisted step state. Onboarding progress is stored in user or organization metadata.
- If the billing step (
billing-setup-step.tsx/embedded-checkout.tsx) is stuck, verify Stripe checkout session creation is functional. - Clear or reset the stuck step state in Clerk metadata.
- Advise the user to reload and re-attempt from
src/app/(auth)/onboarding/page.tsx. - 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:
- Check
OPENAI_API_KEYis valid and within quota using the OpenAI dashboard. - Inspect
GET /api/ai/performance-monitoringfor recent latency spikes or error rates. - Review the LangGraph orchestrator cost guard state (PR #463 context).
- Check
GET /api/ai/conversationsfor stuck conversation state that may block the chat stream. - If the issue is model-side, test the
@ai-sdk/openaiintegration usingGET /api/auth/testpattern to isolate Next.js from OpenAI. - Verify
serverExternalPackagesinnext.config.tsincludeslangchain,@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:
- Fire a test notification using
POST /api/alerts/testto verify the Knock pipeline is alive. - Check
GET /api/alerts/historyfor the affected user to confirm triggers are firing. - Inspect
GET /api/alerts/preferencesfor the user — delivery may be disabled. - Check the Knock dashboard for workflow execution logs and channel delivery status.
- Verify
KNOCK_API_KEY(or equivalent secret) is set in the deployment environment (see §8). - If the
alert-testingGitHub 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:
- Verify
ELASTICSEARCH_URLand credentials are correctly set in the deployment environment. - Check
tests/api/search/route.test.tsandapi_tests/unit/test_properties.pyfor the expected API contract. - Run the Python integration suite against staging:
cd api_tests && pytest integration/. - Inspect Elasticsearch cluster health directly.
- 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:
- Run
npm run theme:auditto identify token violations. - Run
npm run theme:audit:reportto producetheme-audit-report.jsonfor diffing. - Trace the issue to the
ThemeProviderwiring documented in PR #458. - Ensure
use-themecustom hook is wired to theThemeProvider, not the default Next.js theme provider.
7. Environment Management
7.1 Environment Tiers
| Tier | API Base URL | Image Domain Pattern |
|---|---|---|
| Production | https://api.zoomprop.com | api.zoomprop.com (configured in next.config.ts images.domains) |
| Staging | https://api-staging.zoomprop.com | api-staging.zoomprop.com (configured in next.config.ts) |
| Local Development | Configured via .env.local, defaults to localhost | N/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:
| Variable | Purpose | Public |
|---|---|---|
NEXT_PUBLIC_ZOOMPROP_API_URL_V1 | ZoomProp backend API base URL | Yes |
NEXT_PUBLIC_ZOOMPROP_WEBSOCKET_URL | WebSocket endpoint for real-time features | Yes |
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN | Mapbox GL JS map rendering | Yes |
OPENAI_API_KEY | OpenAI API authentication for AI features | No — server only |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Clerk frontend authentication | Yes |
NEXT_PUBLIC_CLERK_SIGN_IN_URL | Clerk sign-in redirect target | Yes |
NEXT_PUBLIC_CLERK_SIGN_UP_URL | Clerk sign-up redirect target | Yes |
Additional variables inferred from dependencies (not exhaustively listed in the visible next.config.ts fragment):
| Variable | Dependency | Notes |
|---|---|---|
CLERK_SECRET_KEY | @clerk/nextjs | Server-side Clerk operations |
KNOCK_API_KEY | @knocklabs/node | Knock notification service (server-side) |
NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY | @knocklabs/react | Knock client-side feed |
NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID | @knocklabs/react | Knock in-app feed channel ID |
ELASTICSEARCH_URL | @elastic/elasticsearch | Elasticsearch cluster endpoint |
ELASTICSEARCH_API_KEY | @elastic/elasticsearch | Elasticsearch authentication |
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY | @googlemaps/js-api-loader | Google 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:
nvm use(ensure correct Node version from.nvmrc)npm install(installs all dependencies including Husky hooks viaprepare)- Copy
.env.exampleto.env.localand populate all required variables npm run devto start the Turbopack dev server- Verify
npm run type-checkandnpm run lintpass before committing
8. Secret Management
8.1 Secret Inventory
| Secret ID | Secret Name | Service | Rotation Frequency |
|---|---|---|---|
| SEC-001 | OPENAI_API_KEY | OpenAI | 90 days or immediately on suspected exposure |
| SEC-002 | CLERK_SECRET_KEY | Clerk | 180 days or on team member offboarding |
| SEC-003 | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Clerk | On Clerk application rotation |
| SEC-004 | KNOCK_API_KEY | Knock | 180 days or on team member offboarding |
| SEC-005 | NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY | Knock | On Knock workspace rotation |
| SEC-006 | ELASTICSEARCH_URL | Elasticsearch | On cluster migration or credential compromise |
| SEC-007 | ELASTICSEARCH_API_KEY | Elasticsearch | 90 days |
| SEC-008 | NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN | Mapbox | 365 days (scope-restricted tokens preferred) |
| SEC-009 | NEXT_PUBLIC_GOOGLE_MAPS_API_KEY | Google Maps | 365 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.localwhich is listed in.gitignore.