critical priority medium complexity testing pending testing specialist Tier 2

Acceptance Criteria

Self-attribution test: validator returns ValidationFailure.selfAttribution when coordinator_id equals peer_mentor_id on the activity record
Out-of-scope test: validator returns ValidationFailure.outOfScope when the target peer mentor belongs to a different organisation_unit than the coordinator's scope
Duplicate window — exact overlap: two activities with identical (peer_mentor_id, start_time, end_time) return ValidationFailure.duplicateWindow
Duplicate window — partial overlap: activity B starting before activity A ends returns ValidationFailure.duplicateWindow
Duplicate window — adjacent non-duplicate: activity B starting exactly at activity A's end_time returns ValidationSuccess (adjacent is not duplicate)
Duplicate window — boundary precision: test uses DateTime values with millisecond precision to confirm boundary logic is not off-by-one
Active mentor pass-through: validator returns ValidationSuccess for a valid mentor with status == active in the assignment table
Inactive mentor rejection: validator returns ValidationFailure.inactiveMentor when mentor status is paused or inactive
Happy-path full pass: a fully valid proxy registration with no conflicts returns ValidationSuccess with no side effects
All test cases are independent and do not share mutable state between runs
Test file achieves ≥ 95% branch coverage on ActivityAttributionValidator
Tests run in under 500ms total (pure unit tests, no network or DB calls)

Technical Requirements

frameworks
flutter_test
mocktail
data models
activity
assignment
performance requirements
All tests complete in under 500ms — no async I/O permitted in unit tests
No real Supabase calls — all repository dependencies must be mocked
security requirements
Test fixtures must not contain real personnummer or PII — use synthetic UUIDs
No credentials or API keys in test files

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

The duplicate window detection logic is the most error-prone part — use closed-open interval semantics: [start, end). This means end_time of activity A equals start_time of activity B is NOT a duplicate. Write a private helper `_overlaps(DateTime aStart, DateTime aEnd, DateTime bStart, DateTime bEnd)` and test it in isolation before wiring it into the validator. For the inactive mentor check, query the assignments table filtered by (peer_mentor_id, organization_id) and check the status enum — do not rely on the user profile status field alone as it can lag.

Use `setUp()` to create fresh mock instances per test group to avoid state leakage. Prefer `throwsA(isA())` over checking return values if the validator uses exception-based control flow; if it uses a result type (recommended), use `expect(result, isA())` with field checks.

Testing Requirements

Pure unit tests using flutter_test and mocktail. Create a dedicated test file `test/unit/activity_attribution_validator_test.dart`. Group tests by scenario using `group()` blocks: self_attribution, out_of_scope, duplicate_window, mentor_status, happy_path. Each `test()` must follow Arrange-Act-Assert pattern.

Mock the assignment repository and activity repository using mocktail `Mock` classes. Boundary cases for duplicate detection must use parametrized helper to avoid repetition. Run with `flutter test test/unit/activity_attribution_validator_test.dart --coverage` and verify lcov report shows ≥ 95% branch coverage on the validator file.

Component
Activity Attribution Validator
service medium
Epic Risks (3)
medium impact medium prob technical

The 2-hour window duplicate detection logic requires querying existing proxy records with compound key matching (mentor + date + activity type within time range). If the query is too broad it produces false positives that frustrate coordinators; if too narrow it misses genuine duplicates that corrupt Bufdir data.

Mitigation & Contingency

Mitigation: Define the duplicate detection window as a configurable parameter from the start. Prototype the Supabase query with representative data covering edge cases (midnight boundaries, different activity types same day, same activity type different mentors) before finalising the implementation.

Contingency: If the detection produces excessive false positives in UAT, allow coordinators to explicitly acknowledge and bypass the duplicate warning with a reason field, preserving safety while reducing friction.

high impact medium prob scope

If the proxy registration form does not clearly distinguish between the acting coordinator and the attributed mentor, coordinators may submit records attributing activities to themselves, causing inaccurate Bufdir reporting and potential funding issues.

Mitigation & Contingency

Mitigation: Conduct UAT with at least one real coordinator via TestFlight before release. Use distinct visual treatment (different card colours, explicit 'Registering on behalf of:' label) and require the confirmation screen to show both identities prominently.

Contingency: Add a mandatory confirmation checkbox on the confirmation screen that explicitly names the attributed mentor, preventing accidental self-attribution from slipping through.

high impact medium prob security

Coordinators with multi-chapter access must select an active chapter context before the mentor list is filtered correctly. If chapter scope resolution fails or is bypassed, cross-org proxy registrations could occur, violating data isolation between chapters.

Mitigation & Contingency

Mitigation: Reuse the existing active-chapter-state and hierarchy-service components established by the org hierarchy feature. Add a guard that blocks entry to the proxy flow if no chapter context is active, prompting chapter selection first.

Contingency: If the chapter resolution service is unavailable, default to the most restrictive scope (no mentors visible) and surface a clear error message rather than showing an unfiltered mentor list.