medium priority low complexity documentation pending documentor Tier 5

Acceptance Criteria

Markdown file created at docs/badges/badge-data-layer.md (or equivalent project docs path)
Document includes a schema section with a table for each of the four badge database tables listing column name, type, nullable, and description
Document includes the exact JSON structure for the criteria field with at minimum two annotated examples (threshold-based and streak-based criteria)
Document includes a step-by-step guide (numbered list) for adding a new badge definition via Supabase without code changes, including which table to insert into and required fields
Document includes a Flutter widget usage section for BadgeCardWidget with a complete Dart code example showing all supported props
Document explicitly states which props affect accessibility (semanticLabel, isEarned, progress) and what WCAG 2.2 AA requirements they fulfil
Document includes a section on BadgeIconAssetManager covering the asset naming convention, the directory path in assets/, and the steps to add a new icon
Document includes a section explaining the Supabase RLS policy design with rationale for multi-tenant org_id isolation
All code examples in the document compile without errors against the implemented codebase
Document is written entirely in English

Technical Requirements

frameworks
Flutter
Supabase
apis
Supabase REST API (for schema reference)
Supabase RLS policy syntax
data models
BadgeDefinition
EarnedBadge
BadgeCriteria
OrgBadgeConfig
security requirements
Documentation must not include real org_ids, user_ids, or production credentials
RLS policy examples must use placeholder values only
ui components
BadgeCardWidget
BadgeIconAssetManager

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Read the implemented source files for all dependent tasks before writing documentation to ensure accuracy. Use the exact column names from the database migration SQL. For the criteria JSON format, document both the property names and value types, and show a threshold example (e.g., {"type": "assignment_count", "threshold": 15}) and a streak example. For the RLS section, explain the multi-tenant design decision: each row is scoped to an org_id and users can only read/write their own org's badges, which is critical for the multi-organization deployment model (NHF, Blindeforbundet, HLF share infrastructure).

Keep the document concise — use tables and code blocks rather than long prose paragraphs.

Testing Requirements

Documentation quality review: (1) have a second developer follow the 'add new badge definition' guide end-to-end and verify a badge appears in the app without any code changes; (2) copy-paste the BadgeCardWidget Dart example into the project and verify it compiles; (3) follow the 'add new icon' guide and verify the icon resolves correctly at runtime. These are manual verification steps, not automated tests.

Component
Badge Definition Repository
data low
Dependencies (8)
Write unit tests for BadgeIconAssetManager covering: resolveIconPath returns correct asset path for locked and unlocked variants, fallback to placeholder icon when asset does not exist, validateContrastRatio correctly computes pass/fail for known colour pairs (e.g., white on dark blue passes, light grey on white fails WCAG AA), and the service initialises without errors when the asset manifest is loaded. epic-achievement-badges-foundation-task-012 Write unit and integration tests for BadgeRepository covering: fetchEarnedBadgesForUser returns only records scoped to the correct organisation_id, awardBadge inserts a record and the uniqueness constraint prevents duplicate awards, revokeBadge soft-deletes or removes the record, and RLS policy blocks cross-organisation access. Use a Supabase test database or mock the Supabase client with mocktail. Achieve at least 80% line coverage. epic-achievement-badges-foundation-task-010 Write unit tests for BadgeDefinitionRepository covering: correct deserialisation of the criteria JSON column into typed BadgeCriteria models, handling of missing or malformed criteria JSON without throwing, fetching definitions returns only organisation-scoped results, and creating a definition with threshold criteria persists the JSON correctly. Include edge case tests for the honorar-threshold criteria with values 3 and 15. epic-achievement-badges-foundation-task-011 Write Flutter widget tests for BadgeCardWidget covering: earned badge renders unlocked icon and correct name label, locked badge renders locked icon with muted styling, milestone progress indicator displays correct percentage, semantic labels are present and correctly describe earned state and progress for screen reader accessibility, and tapping an earned card fires an optional onTap callback. Run flutter_test with accessibility checks enabled. epic-achievement-badges-foundation-task-013 Implement the BadgeRepository Dart class that provides full CRUD operations for earned_badges and tier_assignments tables via the Supabase client. Methods required: fetchEarnedBadgesForUser, awardBadge, revokeBadge, fetchTierAssignment, assignTier, and updateTierAssignment. All queries must be organisation-scoped. Implement error handling and map Supabase exceptions to domain-level exceptions. epic-achievement-badges-foundation-task-003 Implement BadgeDefinitionRepository Dart class for the badge_definitions table. Must support fetching all badge definitions for an organisation, fetching by ID, and creating/updating definitions. Crucially, the repository must correctly serialise and deserialise the criteria JSON column that stores configurable threshold rules (e.g., assignment count triggers for honorar levels). Provide a typed BadgeCriteria model parsed from the JSON column. epic-achievement-badges-foundation-task-004 Implement RecognitionTierRepository Dart class providing read and write access to the recognition_tiers table. Expose methods: fetchAllTiers, fetchTierById, createTier, updateTier. Tiers are organisation-scoped. Ensure ordering by threshold value is supported. Repository should return strongly typed RecognitionTier domain models with fields for name, threshold, icon reference, and colour token. epic-achievement-badges-foundation-task-005 Implement the BadgeCardWidget as a stateless Flutter widget that renders a single badge. The widget must display: badge icon (locked or unlocked variant via BadgeIconAssetManager), badge name label, earned/locked state with visually distinct styling, and an optional milestone progress indicator (e.g., LinearProgressIndicator showing progress toward earning the badge). Apply correct semantic labels and accessibility roles so VoiceOver/TalkBack correctly announces badge name, earned state, and progress percentage. epic-achievement-badges-foundation-task-008
Epic Risks (2)
high impact medium prob scope

Badge criteria are stored as structured JSON in badge_definitions. If the JSON schema for criteria (threshold counts, streak lengths, training completion flags) is not well-defined upfront, the evaluation service will be built against a moving target, requiring costly migrations and refactors.

Mitigation & Contingency

Mitigation: Define and document the criteria JSON schema in a shared type file before any repository code is written. Review the schema with all three organisations' badge requirements — especially Blindeforbundet's honorar thresholds — and version the JSON schema using a 'criteria_version' field from day one.

Contingency: If the criteria schema must change after services are built, write a Supabase migration to backfill existing rows and add a migration version column. Keep the evaluation service criteria parser isolated behind an interface so only one function needs updating.

medium impact medium prob dependency

Badge icon assets may not yet exist or may fail WCAG 2.2 AA contrast validation (minimum 3:1 for graphical objects) when rendered over design-token backgrounds. Missing or non-compliant icons could block UI epic delivery for Blindeforbundet, for whom screen reader and visual accessibility is non-negotiable.

Mitigation & Contingency

Mitigation: During this epic, implement the contrast-ratio validator in badge-icon-asset-manager and run it as a Flutter test against all candidate icon assets early. Coordinate with the design team to provide WCAG-compliant SVG icons in both locked and unlocked variants before the UI epic begins.

Contingency: If assets are late or fail contrast checks, ship placeholder icons that are guaranteed compliant (solid design-token colour fills with text labels) and swap in final assets post-QA without requiring a code change.