high priority low complexity backend pending backend specialist Tier 6

Acceptance Criteria

Acknowledgement submission with scroll_to_bottom = false is rejected with HTTP 422 and error code SCROLL_INCOMPLETE
Acknowledgement submission with scroll_to_bottom = true proceeds to downstream validation without error
Error response body includes a human-readable message: 'You must scroll to the bottom of the document before acknowledging'
Error response body includes field: 'field': 'scroll_to_bottom' for client-side field highlighting
Validation is enforced server-side in the Supabase Edge Function — the client cannot bypass it by omitting the field (treat missing as false)
The scroll_to_bottom field is present and typed as boolean in the acknowledgement request schema/DTO
Unit test confirms that a request payload missing scroll_to_bottom is treated identically to scroll_to_bottom = false
No changes to the happy-path acknowledgement flow performance: p95 latency remains under 400 ms
Validation error is logged at WARN level with declaration_id and actor_id for audit review

Technical Requirements

frameworks
Supabase Edge Functions (Deno/TypeScript)
Flutter (client enforces scroll state before calling API)
BLoC (AcknowledgementBloc emits error state on 422 response)
apis
POST /declarations/:id/acknowledge — existing endpoint extended with scroll guard
data models
DeclarationAcknowledgement (scroll_to_bottom: bool, declaration_id, actor_id)
Declaration (status, id)
performance requirements
Validation must short-circuit before any database read — no unnecessary round trips on invalid input
Edge Function cold-start budget shared with sibling functions: keep handler under 50 KB
security requirements
scroll_to_bottom must be validated server-side regardless of client claims — never trust client-only enforcement
Actor identity must already be authenticated via Supabase JWT before reaching this validation layer
Do not expose internal stack traces in the 422 error body

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

Implement as the first guard clause in the Edge Function handler before any DB access. Pattern: `if (!body.scroll_to_bottom) { return new Response(JSON.stringify({ error: 'SCROLL_INCOMPLETE', message: '...', field: 'scroll_to_bottom' }), { status: 422 }) }`. On the Flutter side the BLoC should already gate the submit button behind a scroll listener — this server check is the legal backstop, not the UX gate. Use Zod or manual type narrowing in the Edge Function to coerce missing field to false.

Keep the validation logic in a pure function `assertScrollComplete(body)` so it is trivially unit-testable without spinning up a server.

Testing Requirements

Unit tests (Dart flutter_test + Edge Function Deno test runner): (1) payload with scroll_to_bottom=false returns 422 with SCROLL_INCOMPLETE code; (2) payload missing scroll_to_bottom returns 422; (3) payload with scroll_to_bottom=true passes validation and delegates to next handler. Integration test against local Supabase: confirm end-to-end 422 is propagated correctly and BLoC emits AcknowledgementError state on the Flutter side. No e2e UI test required for this isolated guard.

Component
Declaration Acknowledgement Service
service medium
Epic Risks (4)
high impact medium prob security

Org-scoped encryption key management is complex. If keys are not correctly isolated per organization, a breach in one org's key could expose another org's declarations. Additionally, key rotation is not specified but may be needed for compliance, and the current implementation may not support it.

Mitigation & Contingency

Mitigation: Use Supabase Vault or a dedicated secrets management approach for org-scoped key storage. Define the key derivation strategy (per-org master key) in a security design document reviewed before implementation begins. Include key isolation tests in the test suite.

Contingency: If a full per-org key management system cannot be safely implemented within the sprint, fall back to a single platform-level encryption key with strict RLS isolation as a temporary measure, flagging the key rotation gap as a security debt item with a defined resolution milestone.

medium impact medium prob integration

Push notification delivery to drivers depends on FCM token availability and device connectivity. If a driver has not granted notification permissions or has an expired FCM token, the declaration delivery notification will silently fail, leaving the coordinator unaware and the declaration unacknowledged.

Mitigation & Contingency

Mitigation: Implement delivery status tracking in declaration-notification-service. Fall back to in-app notification and SMS (if configured) when push delivery fails. Expose delivery failure status in the declaration status badge so coordinators can identify and manually follow up.

Contingency: If push delivery proves unreliable, implement a polling-based in-app notification fallback where drivers see pending declarations on next app open, ensuring the workflow can complete even without push notifications.

medium impact medium prob technical

The acknowledgement service is meant to validate that the driver has fully scrolled through the declaration before confirming. Implementing reliable scroll completion detection in Flutter across different screen sizes and font sizes is technically non-trivial and could be bypassed.

Mitigation & Contingency

Mitigation: Implement scroll position tracking using ScrollController with a threshold (e.g., 95% of content height reached) and record the validated state server-side before allowing acknowledgement submission. Document the approach in the legal sign-off checkpoint noted in the feature documentation.

Contingency: If reliable scroll detection cannot be implemented within the sprint, add a mandatory reading delay timer (e.g., estimated reading time based on word count) as an alternative validation mechanism, pending legal review of the approach.

medium impact low prob dependency

The driver assignment service must coordinate with the threshold-based expense approval workflow for fees above configured thresholds. If the expense approval workflow interface changes or is not yet stable, the integration point could break or produce incorrect routing behavior.

Mitigation & Contingency

Mitigation: Define a clear interface contract between driver-assignment-service and the expense approval workflow before implementation. Use dependency injection so the expense workflow client can be mocked in tests. Monitor the expense approval feature for interface changes.

Contingency: If the expense approval workflow interface is not stable, implement a direct database insert to the expense records table as a temporary bypass, with a flag indicating manual review is needed, until the stable interface is available.