critical priority high complexity backend pending backend specialist Tier 2

Acceptance Criteria

The Edge Function entry point accepts POST requests with a JSON body containing at minimum: { integrationId: string, integrationTypeId: string, payload: object }
Requests missing required fields return HTTP 400 with a JSON error body: { error: 'INVALID_REQUEST', message: string }
The router resolves the correct adapter from the AdapterRegistry by integrationTypeId — supported types: 'xledger', 'dynamics', 'cornerstone', 'consio', 'bufdir'
Requesting an unregistered integrationTypeId returns HTTP 422 with { error: 'UNKNOWN_INTEGRATION_TYPE', integrationTypeId: string }
Field mappings are resolved via FieldMappingResolver.resolve(integrationId, payload) before passing to the adapter — the adapter receives a transformed payload, not the raw one
The adapter executes the export and the router returns HTTP 200 with { success: true, integrationId, result: <adapter result object> } on success
If the adapter throws a CredentialNotFoundError (from task-002), the router returns HTTP 503 with { error: 'CREDENTIAL_UNAVAILABLE', integrationId }
If the adapter throws any other error, the router returns HTTP 502 with { error: 'ADAPTER_EXECUTION_FAILED', integrationTypeId, message: <sanitised message> } — internal error details are logged server-side only
All HTTP responses include Content-Type: application/json
Unit tests achieve ≥ 85% branch coverage on the router logic
The function handles concurrent invocations safely — no shared mutable state between requests

Technical Requirements

frameworks
Supabase Edge Functions (Deno)
Deno standard library (HTTP server)
apis
Xledger REST API
Microsoft Dynamics REST API
Cornerstone API
Consio API
Bufdir API
data models
ExportJobRequest
FieldMapping
AdapterResult
IntegrationConfig
performance requirements
Total dispatch time (validation + field mapping resolution + adapter call) must complete within Supabase Edge Function timeout (default 150s) — adapter calls to slow external APIs must implement a 30s per-adapter timeout
Field mapping resolution must be cached per integrationId within the invocation to avoid repeated DB queries for the same integration
security requirements
JWT verification must be enabled — only authenticated Supabase users with the 'admin' or 'coordinator' role may invoke this function
The request payload must be size-limited (max 512KB) to prevent abuse
Adapter error messages returned to clients must be sanitised — never include raw external API error bodies which may contain sensitive information
All requests and their outcomes (success/failure, integrationId, integrationTypeId, duration) must be logged to Supabase structured logs without including credential values or PII from the payload

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Integration Task

Handles integration between different epics or system components. Requires coordination across multiple development streams.

Implementation Notes

Structure the router as a single handler function: serve(async (req) => { ... }) using Supabase's serve helper. Use a plain object as the AdapterRegistry (a Map) populated at module load time — this avoids dynamic require/import overhead per request. Define an IntegrationAdapter interface: { execute(config: IntegrationConfig, mappedPayload: object): Promise }.

Each adapter (XledgerAdapter, DynamicsAdapter, etc.) implements this interface and is responsible for its own HTTP calls to the external system. The FieldMappingResolver should query the field_mappings table in Supabase using the service role client and apply transformations — memoize the mapping lookup per integrationId within the invocation using a local Map. Wrap the entire handler body in a try/catch to guarantee that unhandled errors always return a valid JSON response rather than a Deno runtime error page. Use AbortSignal.timeout(30_000) for all external adapter HTTP calls to enforce the per-adapter timeout.

Testing Requirements

Write Deno unit tests covering: (1) valid request routes to the correct adapter and returns 200 with result; (2) missing required field returns 400; (3) unknown integrationTypeId returns 422; (4) CredentialNotFoundError from adapter returns 503; (5) generic adapter error returns 502 with sanitised message; (6) field mapping resolver is called with the correct integrationId and payload before the adapter; (7) adapter receives the resolved (transformed) payload, not the raw one. Mock AdapterRegistry, FieldMappingResolver, and CredentialProvider — do not make real external API calls in unit tests. Additionally write one integration test (integration_test/) that deploys the function to a local Supabase instance and sends a real POST request with a stub adapter registered for 'test-type'.

Component
Integration Edge Functions
infrastructure high
Epic Risks (3)
medium impact medium prob technical

Supabase Edge Functions have cold start latency that can cause the first sync invocation after idle periods to fail or timeout when the external API has a short connection window, leading to missed scheduled syncs that go undetected.

Mitigation & Contingency

Mitigation: Configure Edge Function memory and implement a warm-up ping mechanism before heavy sync invocations. Set generous timeout values on the external API calls. Log all cold-start incidents for monitoring.

Contingency: If cold starts cause consistent sync failures, migrate the sync scheduler to a persistent Supabase cron job that pre-warms the function 30 seconds before the scheduled sync time.

high impact low prob technical

The sync scheduler must execute jobs at predictable times for financial reporting accuracy. Drift in cron execution timing (due to Supabase infrastructure delays) could cause syncs to run at wrong times, leading to missing data in accounting exports or duplicate exports across reporting periods.

Mitigation & Contingency

Mitigation: Implement idempotency keys based on integration ID + scheduled period, so re-runs of a delayed sync cannot create duplicate exports. Log actual execution timestamps vs scheduled timestamps and alert on drift exceeding 5 minutes.

Contingency: If scheduler reliability is insufficient, integrate with a dedicated cron service (e.g., pg_cron on Supabase) for millisecond-precise scheduling, replacing the application-level scheduler.

high impact medium prob integration

Aggressive health monitoring ping frequency could trigger rate limiting on external APIs (especially Xledger and Dynamics), causing legitimate export calls to fail after the monitor exhausts the API's request quota.

Mitigation & Contingency

Mitigation: Use lightweight health check endpoints (HEAD requests or vendor-specific ping/status endpoints) rather than data requests. Set health check frequency to once per 15 minutes minimum. Implement exponential backoff after consecutive failures.

Contingency: If rate limiting occurs, disable active health monitoring for the affected integration type and switch to passive health detection (mark unhealthy only when a scheduled sync fails).