3.4 KiB
3.4 KiB
Tasks: add-import-sse-progress
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. OTel — extend instruments bundle
- Add
sseConnected: Counter(import.sse.connected) toImportInstruments. - Add
sseEventsSent: Counter(import.sse.events_sent) labelled bykind. - Add
sseDisconnected: Counter(import.sse.disconnected) labelled byreason. - Update
src/otel/instruments.mdto describe the three new counters. - Extend
src/otel/instruments.test.tsto assert the new counters round-trip through a freshMeterProvider.
2. Route — GET /:id/progress
- Create
src/routes/progress-sse/progress-sse.tsexportingregisterProgressSseRoute(app, deps). - Wire the handler into
createImportRoutesinsrc/routes/build-routes.ts. - Subscribe to
service.bus(import.progress,import.completed,import.failed) — NO polling. - Forward the request
AbortSignalto detach the listener on client disconnect. - Frame format:
id: <jobId>-<seq>,event: progress|complete|failed, JSON-stringifiedImportProgresspayload, double-newline terminator. - Initial frame: snapshot from
service.getJob(id, ownerId)so the client sees current state before the first bus tick. - Terminal events (
complete/failed) close the stream cleanly.
3. Errors
- Reuse
IMPORT.NOT_FOUNDfor foreign-owner / missing jobs (404 problem+json). - Reuse
IMPORT.UNAUTHENTICATED(viarequireAuth()middleware already inbuild-routes.ts) for the 401 path. - No new error codes added.
4. Tests
src/routes/progress-sse/progress-sse.test.tscovering eight scenarios listed inproposal.md#source-mapping.- Tests use Hono's
app.request()returning aResponsewith a streamed body; assertions read viabody.getReader()and decode UTF-8. - No mocks. Real
ImportService, real Hono, real in-memoryMeterProvider.
5. Docs
src/routes/progress-sse/progress-sse.md(≥200 words, Purpose / Features / Usage Basic / Usage Advanced / API Reference / Implementation Notes).- Update package
README.mdFeatures list and routes table to include the new SSE endpoint.
6. Subpath export
- Add
./routes/progress-sse/progress-ssetopackage.json#exports.
7. Gates (in order)
bunx biome check src/bunx turbo lint typecheck test --filter=@suaveplan/api-plugin-importbunx turbo test:coverage --filter=@suaveplan/api-plugin-import(100/100/100/100)bun scripts/openspec-conformance.ts @suaveplan/api-plugin-import(0 errors)bunx turbo build --filter=@suaveplan/api-plugin-import
8. Archive
- Fold spec delta into
openspec/specs/api-plugin-import/spec.md. mv openspec/changes/add-import-sse-progress openspec/archive/2026-05-20-add-import-sse-progress.