high priority low complexity frontend pending frontend specialist Tier 3

Acceptance Criteria

RecurringTemplateSelector is rendered at the top of ProxyRegistrationScreen above the form fields, inside a collapsible or always-visible section labelled 'Use saved template'
Selecting a template calls ProxyRegistrationFormCubit.applyTemplate(RecurringTemplate) which sets activityTypeId, durationMinutes, and notes from the template
After template pre-fill, the coordinator can freely edit any field and the edits are retained — no automatic re-apply occurs
Selecting a different template after manual edits replaces only the template-derived fields (activityTypeId, durationMinutes, notes) — manually set date, startTime, and selectedMentorId are not overwritten
If the coordinator has no templates, the RecurringTemplateSelector renders its empty state and no layout shift or error occurs
Template selector is clearly labelled as optional — form can be submitted without selecting a template
Cubit isDirty flag is set to true after template application (same as manual edit)
Accessibility: template selector section has a Semantics container with a meaningful label for screen readers

Technical Requirements

frameworks
Flutter
BLoC/Cubit
Riverpod
data models
activity_type
performance requirements
Template application (applyTemplate) updates form state in a single cubit emit — no multiple rebuilds
security requirements
Template notes content is treated as user-provided text — apply the same 2000-character max and whitespace trim as manual notes input
ui components
RecurringTemplateSelector (task-004)
ProxyRegistrationScreen (task-006)
ProxyRegistrationFormCubit.applyTemplate() method (new)

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Add `applyTemplate(RecurringTemplate template)` method to `ProxyRegistrationFormCubit`: emit a new state via `copyWith(activityTypeId: template.activityTypeId, durationMinutes: template.defaultDurationMinutes, notes: template.notesTemplate, isDirty: true)`. This is a pure state update — no conditional logic needed because `copyWith` only updates the specified fields. The key correctness property is that `applyTemplate` only touches the three template-derived fields, leaving all other fields unchanged. In the screen, pass `onTemplateSelected: context.read().applyTemplate` directly as the callback — no intermediate handler needed.

Wrap the RecurringTemplateSelector in an `AnimatedSize` widget to smoothly handle the transition between loading/empty/populated states without layout jumps.

Testing Requirements

Widget tests extending the ProxyRegistrationScreen test file from task-006. Add test cases: (1) RecurringTemplateSelector is present in the widget tree, (2) selecting a template updates the activity type dropdown and duration field to match the template, (3) editing the duration field after template selection retains the edited value on next rebuild, (4) selecting a second template does not overwrite a manually set date. Also add a cubit unit test for `applyTemplate()`: verify all three fields (activityTypeId, durationMinutes, notes) are updated and date/startTime/selectedMentorId are unchanged.

Component
Proxy Registration Screen
ui 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.