Skip to content

Part of the approved Iteration 2 design pack. Read together with design-decision.md, which records binding corrections.

Iteration 2 — source truth (grounded in camaradesuk/syrf@main, commit cc271f478d03, read 2026-09-01)

Authoritative for every status string, capability, and progress rule in the Iteration 2 designs. Supersedes the handover-pack shorthand where they differ (differences listed at the end).

Search Import — SearchImportJobStatus (api-client.generated.ts:8056)

Value Enum Deployed display label (systematic-searches.component statusText) Progress bar today
0 Uploading "Transferring..." buffer
1 Parsing "File received. Processing..." indeterminate
2 Complete "Complete" none
3 Error "Error" (button → SearchErrorComponent dialog) none
4 Received "File received. Processing..." indeterminate
5 Saving "Saving studies... (numberOfSavedStudies/totalNumberOfStudies)" determinate when total > 0

Parse error kinds (8081): MissingHeader, UnrecognisedHeader, MissingXmlElements, MalformedRecord, NoMatchingScreener, UnsupportedFileType, UnknownError, CancelledEarly, MissingRequiredField, ResourceLimitExceeded, UnsupportedEncoding. Parse warning codes (8108): UnsupportedFieldOmitted, InvalidOptionalFieldOmitted, DiagnosticsTruncated. Persisted warnings render as "N import warning(s)" + warning_amber icon + tooltip (role="status"). DTO truth: LastModified only — no created/started/completed/initiator (brief confirmed).

Bulk Study Update — BulkStudyUpdateJobStatus (8132; update-studies.component.ts map)

UploadingToS3=0, ErrorUploadingToS3=1, ValidatingOnServer=2, ErrorValidatingOnServer=3, Parsing=4, CompletedParsing=5, ErrorParsing=6. Client job states also include browser-local phases: retrievingS3Signature, uploadingToS3, errorUploadingToS3, successfullySentToS3 (dialog-lifetime only today). DTO truth: created, intended last modified (convention-mapping bug → year-one risk), initiating investigator (can vanish for non-public members → "Not available"). No cancel/retry endpoints. Truthful completion = StudyUpdateParseResult matched/modified, never parsed-row count.

Risk of Bias — RiskOfBiasJobStatus (8179; risk-of-bias-job-table statusMap)

Value Display label Value Display label
0 Not Started 8 Parsing Output
1 Converting PDFs to Text 9 Output Parsing Error
2 No PDFs Found 10 Study Results Parsed
3 Text Files Generated 11 Completed
4 Converting to Text Error 12 General Error
5 Input CSV File Creation Error 13 Timed Out
6 Model Processing 14 Cancelled
7 Model Processing Error

(Value 7 restored during the plan-gate review: the deployed statusMap defines "Model Processing Error" and exhaustive Wave 2 handling must treat it as a needs-attention error state — terminal, no progress bar — not the unknown fallback.)

Unknown → "Unknown" today. Progress rules (component): ConvertingPdfsToText = pdfRetrieved/studiesInSearch; ModelProcessing = processed/pdfRetrieved (buffer bar); ParsingOutput = resultsParsed/processed; terminal → no bar. Existing table columns: Search, Attempt, Created On, Studies, Status, Progress, Completed On; "hide completed" default on. DTO truth: created/lastUpdated/completed timestamps, counts; NO initiator; NO cancel/retry API (Cancelled enum value exists but is not a user capability).

Bulk PDF — BulkPdfUploadJobStatus (8252) + status-presentation.ts (the shipped StatusView contract)

Queued=0, Uploaded=1, Scanning=2, Copying=3, Finalizing=4, Complete=5, Failed=6, Infected=7, Expired=8, Uploading=9, Completing=10, Aborting=11, Abandoned=12, Cancelled=13. Terminal: Complete, Failed, Infected, Abandoned, Cancelled. Expired is NOT terminal (cleanup pending).

Deployed labels: Uploading→"Uploading PDFs" (determinate: verifiedPartCount/partCount); Completing→"Finishing the transfer"; Queued→"Queued for processing"; Uploaded+Scanning→"Checking files"; Copying→"Copying to the PDF server (processed/total processed)"; Finalizing→"Finalizing"; Complete→"PDFs uploaded" + "X copied · Y replaced · Z unmatched"; Infected→"Upload stopped" + See details; Failed→"Upload failed" + See reason; Expired→"Never finished" + "Retry starts over" (muted); Abandoned→"Upload interrupted" (muted); Aborting→"Cancelling…" (neutral tone); Cancelled→"Upload cancelled" (muted); unknown value→"Status unavailable" + "Refresh the page". Chip kinds: ok / stopped / warn / muted / info. Indeterminate aria: "Working — no estimate available". Determinate aria: "{label}, {percent} complete". Commands: initiate/complete/abandon/cancel/retry/ report — the ONLY family with cancel/retry.

Permissions (ProjectPermission enum, 8795)

ViewStudies=8, BulkUpdateStudies=13, ImportSearch=14, ViewSearches=15, RemoveSearch=16, BulkPdfUpload=23. Processing view policy: server-filtered aggregate (ProjectDetails), one loading boundary.

Differences vs the handover pack (decision log entries)

  1. Pack fixture "Saving 8,420 / 12,000" → rendered as deployed label "Saving studies... (8,420/12,000)"; unit "references" appears in the detail line, not the label.
  2. Pack fixture "Validating 2,104 / 5,000" → raw enum is ValidatingOnServer; display label "Validating on server" (sentence-cased from enum; no deployed map exists for this family outside the dialog) with "2,104 / 5,000 rows"; raw enum + value shown in row detail.
  3. Pack fixture "Parse error" (Search Import) → deployed status is "Error"; the parse-error KIND (e.g. MalformedRecord) and the bounded error list carry the specifics.
  4. Pack fixture "Model processing 78 / 120" → display label is "Model Processing" (title case per deployed statusMap); unit PDFs.
  5. Pack "Scanning indeterminate" → deployed label "Checking files"; raw enum Scanning in detail.
  6. Status-chip semantics: adopt the shipped StatusView chip-kind contract (ok/stopped/warn/muted/info
  7. honest bar modes + ariaValueText) as the shared component across all four families, replacing Iteration 1's dot/triangle raw hexes. Colour roles map to emitted --mat-sys-* / --syrf-* only.
  8. Unknown future value → "Unknown status (17)" (handoff rule) rather than Bulk PDF's "Status unavailable": the numeric value is known and diagnostic. Recorded as a deliberate divergence from the shipped Bulk PDF fallback, to be reconciled in Wave 4 (whose ledger owns project-admin/bulk-pdf-upload/**).