critical priority medium complexity infrastructure pending backend specialist Tier 2

Acceptance Criteria

AnnualSummaryHiveAdapter is generated (or hand-written) and correctly serialises/deserialises all fields of the AnnualSummary domain model including nested objects and enums
The Hive TypeAdapter is registered exactly once during app initialisation before any box is opened, and calling registerAdapters() twice does not throw
The Hive box named 'annual_summaries' is opened during app startup and its future completes before the Wrapped feature route is reachable
Schema version constant (e.g. kAnnualSummarySchemaVersion = 1) is defined and included in stored records to support future migration logic
If the box contains records written with an older schema version, the adapter logs a warning and returns null rather than throwing a runtime exception
Unit tests confirm that an AnnualSummary round-trips through put/get without data loss for all field types (int, double, String, DateTime, enums, nullable fields)
The box is closed cleanly when the app is backgrounded or terminated (Hive.close() called in app lifecycle observer)
No Hive box open call appears outside the designated initialisation path

Technical Requirements

frameworks
Flutter
Hive
hive_flutter
hive_generator
build_runner
data models
annual_summary
performance requirements
Box open completes within 200 ms on mid-range Android device
Single put() operation completes within 5 ms
Single get() operation completes within 2 ms
security requirements
Box must NOT store raw Supabase JWTs or auth tokens alongside summary data
Sensitive PII fields (peer_mentor_id) stored only as UUID strings, never as full profile objects
Consider HiveAesCipher for the box if the app's threat model requires encryption at rest — confirm with team

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Use hive_generator with @HiveType/@HiveField annotations on the AnnualSummary model if code generation is already used in the project; otherwise write a hand-coded TypeAdapter. Register all adapters in a single registerHiveAdapters() top-level function called from main() before runApp(). Open the box inside a dedicated HiveService.init() that returns a Future and is awaited in main(). Use a splash/loading screen to cover the async init.

Store the schemaVersion as a separate Hive box key ('annual_summaries_schema_version') so migration logic can compare on next open. For future-proofing, store entries keyed by '${mentorId}_${year}' string to guarantee uniqueness and enable efficient targeted reads.

Testing Requirements

Unit tests (flutter_test) covering: (1) adapter registration does not throw on repeated calls, (2) AnnualSummary serialisation round-trip with all field types present, (3) AnnualSummary serialisation round-trip with all optional fields null, (4) schema version mismatch returns null without throwing. Integration test: open box, write three records for different mentor/year combinations, read each back and assert equality. No widget tests required for this task.

Component
Summary Offline Cache
data low
Epic Risks (3)
medium impact medium prob dependency

Rive animation files may not be available at implementation time, blocking the wrapped-animation-controller from being fully tested. If asset delivery is delayed, the controller cannot be validated for memory-leak-free disposal.

Mitigation & Contingency

Mitigation: Implement the animation controller with stub/placeholder AnimationController instances first so the lifecycle and disposal logic can be unit-tested independently of Rive assets. Define a named animation registry interface early so UI components can reference animations by name without coupling to specific Rive files.

Contingency: If Rive assets are not delivered before Epic 3 begins, replace Rive animations with Flutter implicit animations (AnimatedOpacity, ScaleTransition) as a drop-in and schedule Rive integration as a follow-on task once assets arrive.

high impact medium prob technical

The annual_summaries Supabase RPC aggregating 12 months of activity records per mentor may exceed acceptable query latency (>2s) for mentors with high activity volumes such as the HLF mentor with 380 registrations cited in workshop notes.

Mitigation & Contingency

Mitigation: Design the RPC to materialise summary results into the annual_summaries table via a scheduled edge function rather than computing on demand. The repository reads pre-computed rows, keeping query latency constant regardless of activity volume.

Contingency: If on-demand queries are required for real-time period switching, add a PostgreSQL partial index on (mentor_id, activity_date) and implement a client-side loading skeleton so slow queries degrade gracefully rather than blocking the UI.

medium impact low prob technical

iOS requires photo library permission before saving a screenshot to the gallery. If the permission prompt is triggered at an unexpected point in the share flow, the UX breaks and users may deny permission permanently, making gallery save unavailable.

Mitigation & Contingency

Mitigation: Trigger the permission request only when the user explicitly chooses 'Save to gallery' in the share overlay, not on screen load. Implement a pre-prompt explanation screen following Apple HIG so users understand why the permission is needed before the system dialog appears.

Contingency: If permission is denied, gracefully fall back to clipboard copy and system share sheet options which do not require photo library access, and surface a non-blocking snackbar explaining the limitation.