critical priority medium complexity backend pending backend specialist Tier 1

Acceptance Criteria

index.ts exports a default Deno.serve handler that accepts only POST requests — GET and other methods return HTTP 405
Incoming cron trigger is authenticated by verifying a shared secret in the Authorization header (Bearer token matching CRON_SECRET env var) — unauthenticated requests return HTTP 401
A Supabase client is initialised with the service role key from EdgeFunctionConfig — the client is scoped to the request and not reused across invocations
A structured ExecutionContext object is assembled before delegating to the scheduler, containing: invocation_id (UUID), timestamp, organisation_count (from initial DB query), and config reference
All log entries are structured JSON (not plain strings) with at minimum: level, message, invocation_id, and timestamp fields
On successful delegated execution the function returns HTTP 200 with a JSON body containing invocation_id and items_processed count
On uncaught exceptions the function returns HTTP 500 with a JSON error body — stack traces are logged server-side but not included in the HTTP response body
Cold start time (from request receipt to first Supabase query) must not exceed 1 second under normal conditions
The entry point is covered by integration tests that send real HTTP requests to a local Supabase emulator

Technical Requirements

frameworks
Supabase Edge Functions (Deno runtime)
TypeScript (strict mode)
@supabase/supabase-js (service role client)
apis
Supabase REST API (service role)
Supabase Edge Function runtime (Deno.serve)
performance requirements
Cold start to first DB query under 1 second
Entry point handler must not perform blocking I/O before authentication check
security requirements
Service role key initialised from config — never from request headers or body
Cron secret validated via constant-time comparison to prevent timing attacks
No sensitive data (keys, tokens, personal data) included in HTTP response bodies
Supabase client created per-invocation to avoid credential leakage between concurrent invocations

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Structure the entry point file to have three distinct responsibilities: (1) HTTP request validation and authentication, (2) context assembly, (3) delegation to the scheduler service. Keep index.ts under 80 lines — extract the scheduler invocation into a separate module. Use crypto.timingSafeEqual for the cron secret comparison to prevent timing-based secret extraction. Initialise the Supabase client inside the request handler (not at module scope) to ensure per-invocation isolation — module-scope clients can leak state in Deno's warm instance model.

For the invocation_id, use crypto.randomUUID() available natively in Deno. Log the invocation_id at the start of every log entry to enable log correlation across a single function execution.

Testing Requirements

Integration tests using Deno.test with a local Supabase emulator (supabase start). Test: (1) POST with valid cron secret returns 200 and JSON body with invocation_id, (2) POST with missing Authorization header returns 401, (3) POST with wrong secret returns 401, (4) GET request returns 405, (5) scheduler throws uncaught error → function returns 500 with JSON error body (not stack trace). Use a test double for the scheduler invocation to isolate entry point logic. Verify log output contains structured JSON entries for each invocation.

Component
Scenario Evaluation Edge Function
infrastructure medium
Epic Risks (2)
medium impact low prob technical

Supabase Edge Functions on Deno can have cold-start latency of 500ms–2s. If the evaluation window contains many activities (e.g., post-holiday catch-up), the function may approach the 60-second invocation timeout before completing all evaluations.

Mitigation & Contingency

Mitigation: Implement pagination in the activity fetch query with a configurable page size; process pages sequentially and commit history records per page so partial runs are recoverable on the next invocation.

Contingency: If timeout remains an issue at scale, split the evaluation into per-chapter invocations triggered by a fan-out pattern using Supabase Realtime or a lightweight queue.

medium impact low prob dependency

Supabase cron triggers (pg_cron or Edge Function schedules) may miss invocations during platform maintenance windows, causing evaluation gaps that delay time-sensitive prompts beyond their intended delivery window.

Mitigation & Contingency

Mitigation: Configure the look-back window to be 2× the cron interval (e.g., 2-hour look-back for hourly cron) so a single missed invocation does not result in missed prompts; log each run's look-back range for auditability.

Contingency: If missed invocations are detected via monitoring alerts, implement a manual re-trigger endpoint accessible to admins that runs the evaluation for a specified time range.