MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-979

2.9.2 Read path — list archived work items (paginated, archivedAt IS NOT NULL)

Done
Description

Estimate: 50m · Type: code

The read path for archived items — the inverse of the pervasive archivedAt IS NULL filter. Today nothing lists archived items.

  • Repository (lib/repositories/workItemRepository.ts): add a single-op read that returns archived items for a project (archivedAt IS NOT NULL), workspace+project scoped (mirror the scoping of the existing reads), ordered by archivedAt DESC, paginated (reuse the existing clamp infra — ISSUE_LIST_PAGE_SIZE / clampIssuePageSize / take+offset) and returning a total count. FLAT list, not a forest (archive is single-node; archived items drop out of subtrees) — do NOT reuse the recursive forest CTE.
  • Service (lib/services/workItemsService.ts): a listArchivedWorkItems(params, ctx) that gates read access (per the 2.9.1 view-access decision — canBrowse), maps to a paginated DTO via lib/mappers/*, and includes the archivedAt + archived-by actor (from the latest archived revision) the view needs.
  • Transport: expose via a server action or GET route consistent with how /issues reads (4-layer: route/action → service → repo → Prisma; no Prisma in the route).

Acceptance criteria

  • A new repo read returns ONLY archived items (archivedAt IS NOT NULL), scoped + ordered by archivedAt DESC, paginated with a total count; non-archived items never appear.
  • A listArchivedWorkItems service method returns the paginated DTO (incl. archived-at + archived-by) and enforces the read-access gate; respects the page-size clamp.
  • Vitest covers: only-archived filter, scope isolation, pagination/clamp, empty result. (Per the coverage gate — subtask-targeted tests; CI verifies the per-file branch/fn/line bar.)

Context refs

  • lib/repositories/workItemRepository.ts (the archivedAt IS NULL reads to invert; listWorkItems/listRootIssues scoping)
  • lib/services/workItemsService.ts:404 clampIssuePageSize / clampTreePage / ISSUE_LIST_PAGE_SIZE (reuse), listWorkItems (shape)
  • lib/repositories/workItemRepository.ts:2008-2027 archive / unarchive (the column semantics)
  • motir-core/CLAUDE.md (4-layer: write-vs-read tx rules; DTO mapping)