Production Safety

RLS, grants, checkout claims, webhook idempotency, cron auth, outbox workers, request ids, and retention jobs are the production guardrails to preserve.

On this page
Implementation reference5 areas

These Product code locations explain how the documented behavior is implemented. Expand them when you are ready to customize or maintain this area.

Database security baseline

The baseline migration owns grants, RLS enablement, policies, RPC functions, and service-role privileges for the Supabase schema.

  • supabase/migrations/20260426000000_init.sql

Webhook request guard

Webhook utilities centralize rate limiting, raw body reading, payload size limits, structured logging, and request id context.

  • src/lib/security/webhooks/request.ts
  • src/lib/security/webhooks/processing.ts

Cron guard

Cron services reject missing or placeholder secrets, compare authorization safely, rate-limit scheduler calls, and log job outcomes.

  • src/lib/security/secrets/cron-secret.ts
  • src/features/notifications/server/outbox/services/cron.ts

Outbox and retention operations

Background workers claim batches, retry safely, dead-letter exhausted work, and run retention cleanup behind protected cron routes.

  • src/features/notifications/server/outbox/services/worker.ts
  • src/features/compliance/server/retention/service.ts

Supabase server boundaries

Server helpers keep user-scoped Supabase access separate from service-role work; proxy route policy avoids unnecessary fresh-user round trips while preserving request context.

  • src/lib/supabase/server.ts
  • src/lib/supabase/proxy.ts
  • src/lib/request-proxy/route-policy.ts

Reference paths are relative to the Shipflash-Product checkout.

Production safety flow

  1. 1

    Define durable database invariants

    Create tables, constraints, grants, RLS policies, RPC functions, and service-role access in migrations instead of relying on runtime assumptions.

    Relevant Product code
    • supabase/migrations/20260426000000_init.sql
  2. 2

    Preserve request context

    Browser requests receive request context through the proxy, while excluded webhook and scheduled routes establish and return their own request ids.

    Relevant Product code
    • src/proxy.ts
    • src/lib/observe/request/request-id.ts
    • src/app/api/notifications/webhooks/resend/route.ts
  3. 3

    Claim before processing external events

    Webhook handlers verify signatures, store event rows, reject duplicate processed events, and reclaim only stale processing leases.

    Relevant Product code
    • src/lib/security/webhooks/request.ts
    • src/lib/security/webhooks/processing.ts
  4. 4

    Reserve a single-purchase checkout

    Attempt-scoped checkout claims reserve a profile and plan before opening a provider session, then prevent stale or duplicate attempts from overwriting newer checkout state.

    Relevant Product code
    • src/features/billing/server/checkout/persistence/claims.ts
    • supabase/migrations/20260426000000_init.sql
  5. 5

    Protect scheduled work

    Cron services validate CRON_SECRET, reject placeholder values, compare authorization without leaking timing, and rate-limit scheduler calls.

    Relevant Product code
    • src/lib/security/secrets/cron-secret.ts
    • src/features/notifications/server/outbox/services/cron.ts
  6. 6

    Retry through outbox state

    Workers claim a bounded batch, record success or failure, back off transient errors, and dead-letter rows after repeated failures.

    Relevant Product code
    • src/features/notifications/server/outbox/services/worker.ts

Cron secrets fail closed

Use this example as a starting point, then adapt it to your product's rules and configuration.

A configured but obvious placeholder secret is treated the same as a missing secret.

ts
export function readValidatedCronSecret(value: string | undefined = process.env.CRON_SECRET): string | null {
  const secret = value?.trim();
  if (!secret) {
    return null;
  }

  if (PLACEHOLDER_CRON_SECRETS.has(secret.toLowerCase())) {
    return null;
  }

  return secret;
}
Source reference
  • src/lib/security/secrets/cron-secret.ts

Webhook stale lease

Use this example as a starting point, then adapt it to your product's rules and configuration.

A processing row can be retried only after the lease timeout, which protects against duplicate live workers and crashed workers.

ts
const WEBHOOK_PROCESSING_STALE_AFTER_MS = 15 * 60 * 1000;

export function isWebhookProcessingStale(
  processingStartedAt: string | null | undefined,
  nowMs: number = Date.now(),
  staleAfterMs: number = WEBHOOK_PROCESSING_STALE_AFTER_MS,
): boolean {
  if (!processingStartedAt) {
    return true;
  }

  const startedAtMs = Date.parse(processingStartedAt);
  if (!Number.isFinite(startedAtMs)) {
    return true;
  }

  return nowMs - startedAtMs >= staleAfterMs;
}
Source reference
  • src/lib/security/webhooks/processing.ts

Recipe: add a production-safe table

Add a Supabase table that works in production without accidental public access, broken generated types, or missing operational docs.

Implementation locations

Inspect

  • supabase/migrations/20260426000000_init.sql
  • src/lib/supabase/server.ts
  • src/lib/supabase/proxy.ts

Edit

  • supabase/migrations/<timestamp>_<change>.sql
  • src/lib/supabase/types.ts
  • src/features/<domain>/server/persistence/<table>.ts

Steps

  • Create the table, indexes, foreign keys, and durable constraints in a migration.
  • Enable RLS and write policies before exposing user-scoped reads or writes.
  • Grant only the roles that need access, and keep service-role writes server-only.
  • Regenerate Supabase types and route all access through feature-owned persistence helpers.
  • Document any env vars, cron routes, webhooks, or retention behavior introduced by the table.

Verify

  • pnpm run contract:migrations
  • pnpm run supabase:types
  • pnpm run test:features
  • pnpm run quality

Common mistakes

  • Do not add a table without RLS decisions.
  • Do not put service-role reads in client-reachable code.
  • Do not skip generated type refresh after schema changes.

AI prompt: production safety review

AI prompt
Review this change for production safety. Inspect migrations, RLS, grants, webhook/event idempotency, cron authentication, outbox retry behavior, request id logging, generated Supabase types, tests, and deployment checklist impact. Fail closed on auth, billing, admin, webhook, and cron boundaries.
Inspect first
  • supabase/migrations/20260426000000_init.sql
  • src/lib/security/webhooks/request.ts
  • src/lib/security/secrets/cron-secret.ts

Verify

  • pnpm run contract:migrations
  • pnpm run test:features
  • pnpm run quality