Work Item Breakdown — ZenHub-Ready¶
Audience: Gill (Scrum Master/Helpdesk), Alex (Product Owner). Secondary: Chris (Senior Dev), Nuri (Junior Dev)
Sprints are 1 week. Assignments sized to fit capacity; junior work scoped with explicit AC and checklists. Owners/Reviewers/Approvers shown per item.
Milestone A — MVP Vertical Slice (3–4 sprints)¶
A1. Domain & Storage: Screening Profiles (CRUD)¶
| Field | Value |
|---|---|
| Description | Add Screening Profile aggregate under Project; immutable-once-used; clone |
| Dependencies | None |
| Estimate | M |
| Owner | Chris |
| Reviewer | Chris (self), backup Nuri |
| Approver | Alex (fields/UX), Chris (tech) |
| Sprint Fit | 1 sprint |
Acceptance Criteria:
- Can create/edit/delete (delete only if unused) profiles
- Profiles have criteria text and reconciliation mode (single/dual-automated/dual-manual)
- Clone creates new version; existing outcomes untouched
A2. Stage Settings — Require StudySelectionMode¶
| Field | Value |
|---|---|
| Description | Add required StudySelectionMode to stage creation; add HideExcluded…, MaxInProgress, SessionCountTarget fields |
| Dependencies | A1 |
| Estimate | M |
| Owner | Nuri |
| Reviewer | Chris |
| Approver | Alex |
| Sprint Fit | 1 sprint |
Acceptance Criteria:
- Stage cannot be saved without a mode
- Values persisted; reflected in selection
A3. Filter Set Storage (Nested Schema v2) + MVP UI¶
| Field | Value |
|---|---|
| Description | Implement JSON schema (nested groups); MVP builder allows one rule: Outcome(Profile X) ∈ {Included, Conflict, Maybe} |
| Dependencies | A1 |
| Estimate | M |
| Owner | Nuri |
| Reviewer | Chris |
| Approver | Alex |
| Sprint Fit | 1 sprint |
Acceptance Criteria:
- Schema validates and saves (422 on invalid)
- Backend compiles to efficient Mongo filters
- UI allows selecting a profile and outcomes; previews count
A4. select_next API (Modes) + Stats Endpoint¶
| Field | Value |
|---|---|
| Description | Implement selection service and stats per caller; include ReconciliationInProgress (caller) |
| Dependencies | A2, A3 |
| Estimate | L |
| Owner | Chris |
| Reviewer | Chris; code-walkthrough with Nuri |
| Approver | Alex (behaviour), Chris (tech) |
| Sprint Fit | 1–2 sprints |
Acceptance Criteria:
- POST
/projects/{projectId}/stages/{stageId}/select_nextacceptsmodeand returns 200 with a study or 204 when none - GET
/projects/{projectId}/stages/{stageId}/statsreturns counts:AvailableForScreening,AvailableForAnnotation,ReconciliationEligible,InProgress(caller),Completed(caller),ReconciliationInProgress(caller) - Selection honours
HideExcluded…, per-reviewer suppression,MaxInProgress
A5. Review UI — MVP Wiring¶
| Field | Value |
|---|---|
| Description | Wire "Get next" by mode; show active profile criteria; keyboarding; banners for Reconciliation Mode |
| Dependencies | A4 |
| Estimate | M |
| Owner | Nuri |
| Reviewer | Chris |
| Approver | Alex |
| Sprint Fit | 1 sprint |
Acceptance Criteria:
- "Get next" works across modes; fallbacks on empty
- In Reconciliation Mode, next item is random from eligible set; banner visible
A6. Studies Endpoint — Stage Study Pool Param¶
| Field | Value |
|---|---|
| Description | Extend existing studies endpoint to accept stageId and apply the stage's Filter Set (reviewer-agnostic) |
| Dependencies | A3 |
| Estimate | S |
| Owner | Nuri |
| Reviewer | Chris |
| Approver | Alex |
| Sprint Fit | < 1 sprint |
Acceptance Criteria:
-
GET /projects/{projectId}/studies?stageId=...returns the Stage Study Pool - No per-reviewer suppression applied
A7. Decisions API (Stage-Context Route)¶
| Field | Value |
|---|---|
| Description | Add/confirm route /projects/{projectId}/stages/{stageId}/screening/decisions (server resolves active profile) |
| Dependencies | A1 |
| Estimate | S |
| Owner | Nuri |
| Reviewer | Chris |
| Approver | Alex |
| Sprint Fit | < 1 sprint |
Acceptance Criteria:
- Posting a decision persists under the correct profileId; idempotent; triggers recompute/materialisation
A8. Migration Wizard (Legacy → Profiles)¶
| Field | Value |
|---|---|
| Description | Opt-in wizard; freeze review; snapshot project; backfill initial profile + outcomes; rollback support |
| Dependencies | A1, A7 |
| Estimate | L |
| Owner | Chris |
| Reviewer | Chris; walkthrough with Nuri |
| Approver | Alex |
| Sprint Fit | 1–2 sprints |
Acceptance Criteria:
- Wizard prevents review during migration; shows progress; logs to audit
- Rollback reverts to snapshot if any batch fails
Milestone B — Hardening & UX Polish (1–2 sprints)¶
| ID | Description | Estimate |
|---|---|---|
| B1 | Telemetry: emit selection timings/counters; wire to dashboards | M |
| B2 | Accessibility (A11y) polish: Storybook checks; keyboard traps; ARIA live regions | M |
| B3 | Helpdesk SOP: export bundle (profiles.json, filterSet.json, stats.json) |
S |
Milestone C — Phase-2 Features (Post-MVP)¶
| ID | Description | Priority |
|---|---|---|
| C1 | PRISMA 2020: mapping UI; PNG/SVG/CSV; click-through to filtered lists | High |
| C2 | Annotation-based filtering: use Reconciled Annotations only; extend Filter Builder UI | High |
| C3 | Tie-breaker groups/roles for screening; stage/project group model surfaced in UI | Medium |
| C4 | Optional materialised pools for very large projects | Low |
Example User Stories (ZenHub-Ready)¶
Story: As a Project Admin, I can create a Screening Profile and clone it¶
| Field | Value |
|---|---|
| Description | CRUD for profiles; clone creates a new version |
| Dependencies | None |
| Complexity | 5 |
| Owner | Nuri (UI), Chris (API/domain) |
| Reviewer | Chris |
| Approver | Alex |
| Sprint | A1 |
Acceptance Criteria (Gherkin):
- Given I am a Project Admin When I create a Screening Profile with name and criteria text Then it appears in the project with status "Draft/Unused"
- Given a profile is used in any stage When I attempt to edit it Then the system refuses and offers Clone
Story: As a Reviewer, the next study honours selection policies¶
| Field | Value |
|---|---|
| Description | Implement select_next behaviour per mode and stage settings |
| Complexity | 8 |
| Owner | Chris |
| Reviewer | Chris |
| Approver | Alex |
| Sprint | A4 |
Acceptance Criteria:
- Returns 200 with a study or 204 when none
- Respects
HideExcluded…, per-reviewer suppression,MaxInProgress - In Reconciliation Mode, picks randomly from eligible; excludes self when self-recon is false
Story: As a Project Admin, I can define a Filter Set for a stage (MVP UI)¶
| Field | Value |
|---|---|
| Description | Store nested-capable schema; UI supports single pass-forward rule |
| Complexity | 5 |
| Owner | Nuri |
| Reviewer | Chris |
| Approver | Alex |
| Sprint | A3, A6 |
Acceptance Criteria:
- Validation 422 on bad ids/ops/values
- Stage Study Pool reflected via studies endpoint (
stageId)
Story: As an Admin, I can run the Migration Wizard safely¶
| Field | Value |
|---|---|
| Description | Freeze, snapshot, backfill, rollback |
| Complexity | 8 |
| Owner | Chris |
| Reviewer | Chris |
| Approver | Alex |
| Sprint | A8 |
Acceptance Criteria:
- Migration blocks review actions; progress visible; audit recorded
- Rollback returns project to Legacy Mode
QA & Test Tasks¶
- Unit test ScreeningOutcome derivation; threshold edge cases (ties, incomplete)
- API integration tests for
select_next,stats, decisions posting - UI e2e tests for Stage Settings, Filter Builder, Reviewer next/resume flows
- Migration dry-run test on a copy of a medium project (>10k studies)
DevOps/Infra Tasks¶
- Feature flag plumbing; config for AgreementThreshold defaults
- Mongo indexes (compound on
ScreeningOutcomes.profileId,outcome; session tallies bystageId) - Dashboards for selection timings/counters
Ownership & Approvals (DoD)¶
| Role | Responsibility |
|---|---|
| Nuri | Well-scoped UI and endpoint glue; plan review required for complex domain changes |
| Chris | Domain model, API design, migration, performance |
| Gill | Sprint slicing, helpdesk intake, approvals tracking |
| Alex | User-visible scope, AC, UAT sign-off |
Definition of Done: Passing tests, updated docs, required reviews, feature flag set appropriately, telemetry events visible.