Skip to main content

Operations & Runbook

With Infisical (secrets managed):

infisical run -- pnpm nx run teetime-backend:serve --output-style=static

With local env vars:

export TEETIME_DATABASE_URL=postgresql://user:pass@localhost:5432/teetime
pnpm nx run teetime-backend:serve --output-style=static

Swagger docs: http://DEV_DOMAIN:PORT/api/docs.

Build

pnpm nx build teetime-backend

The build uses Webpack to bundle the app. Upstream dependencies (repositories and libraries) are built first.

Health checks

  • Liveness: GET /api/health/liveness – basic process check.
  • Readiness: GET /api/health/readiness – verifies tee‑sheet DB, storage DB and queue.

Public Health UI (frontend)

The teetime-frontend app exposes a public status page at /health that probes:

  • IDP base (VITE_IDP_BASE_URL)
  • Tee Time API base (prefers VITE_TEE_TIME_BASE_URL; falls back to same-origin)
  • Messaging API base (MESSAGING_API_BASE_URL, optional)

These are browser probes; cross-origin servers may block them via CORS. Use backend health endpoints above for authoritative checks.

Admin Health (tenant‑scoped diagnostics)

The admin portal exposes a /health route with:

  • Core Probes for IDP/Tee Time/Messaging.
  • IDP Direct Login & App Login Flow diagnostics with CSRF helpers.
  • Route Access Diagnostics integrating with Access Control capabilities:
    • Admin roles bypass checks.
    • Otherwise the panel calls POST /api/capabilities/can with Authorization: Bearer <token> and x-tenant-id from the JWT.
    • Set VITE_ACCESS_CONTROL_BASE_URL in dev to enable these calls.

Auto‑deploy (Argo CD + Image Updater)

Both Tee Time SPAs and services are configured for automated rollouts:

  • Frontend SPA: kubernetes/teetime/frontend/teetime-frontend-argo.yaml
    • Image Updater annotations present (digest strategy; write‑back Git to main).
    • Deployment uses imagePullPolicy: Always.
  • Admin SPA: kubernetes/teetime/admin/teetime-admin-argo.yaml
    • Image Updater annotations present; same strategy.
    • Deployment uses imagePullPolicy: Always.
  • Backend API: kubernetes/teetime/backend/teetime-backend-argo.yaml
    • Image Updater annotations present (digest strategy; write‑back Git).
    • Deployment uses imagePullPolicy: Always.
  • Events Worker: kubernetes/teetime/events-worker/teetime-events-worker-argo.yaml
    • Image Updater annotations present; same strategy.
    • Deployment uses imagePullPolicy: Always.

Workflow:

  1. Build and push images from the monorepo
    • pnpm nx run teetime-frontend:build && pnpm nx run teetime-frontend:container-push
    • pnpm nx run teetime-admin:build && pnpm nx run teetime-admin:container-push
  2. Argo Image Updater detects the new digest for :latest, commits manifest updates, and Argo CD auto‑syncs.
  3. Verify in Argo (requires access):
    • argocd app get teetime-frontend --grpc-web
  • argocd app get teetime-admin --grpc-web

If needed, force a rollout (e.g., before Image Updater commits):

kubectl -n teetime rollout restart deploy/teetime-frontend
kubectl -n teetime rollout restart deploy/teetime-admin

App of Apps (recursion)

The Tee Time root Argo application is configured with recursive directory scanning so it automatically discovers child *-argo.yaml manifests under kubernetes/teetime/**.

Metrics

  • GET /api/metrics – Prometheus format.
    • service_ready – 1 when all deps are healthy.
    • tt_search_requests_total{kind="visitor|member"} – request volume (from engine).
    • tt_search_latency_ms_*{kind} – request latency histogram.

CORS & security

CORS is restricted to PROD_UI_ORIGIN and a local dev host. Credentials are allowed. Use an API gateway to enforce auth for admin routes or attach Nest guards where necessary.

Troubleshooting

  • Prisma client missing for tee‑sheet data
    • Generate once: pnpm nx run tee-sheet-data:prisma:generate.
  • Storage DB missing
    • App stays up; readiness reports storage unhealthy until configured.
  • GeoIP failures
    • Ensure MAXMIND_* env is set for your chosen mode; check logs for init errors.
  • Memory pressure during Jest
    • Run with --runInBand and NODE_OPTIONS=--max_old_space_size=6144.
  • Pricing eligibility context
    • Visitor pricing and multi-club streams accept optional { tenantId, membershipNumber, providerCode } to apply reciprocity/association rules. Ensure callers pass these when available; missing context will skip eligibility pricing.

Access Control seeding (tenant scope)

Use Infisical‑wrapped scripts to seed Tee Time ACL (idempotent) and verify:

# Seed defaults, roles, permissions, and TT admin capabilities; then verify
pnpm run seed:teetime:acl

# Verify only
bash tools/scripts/seed-teetime-acl.sh --env dev --verify

Notes:

  • Requires DB access (ACCESS_CONTROL_DATABASE_URL) via Infisical.
  • If running off‑cluster, port‑forward the DB or use a VPN/bastion.