Files
suaveplan/openspec/archive/2026-05-25-enterprise-imessage-adapter/tasks.md
2026-05-27 23:29:53 +01:00

101 lines
6.2 KiB
Markdown

# Tasks: enterprise-imessage-adapter
**Change ID**: `enterprise-imessage-adapter`
**Package**: `@suaveplan/imessage-adapter`
**Target path**: `packages/communication/messaging/imessage-adapter/`
**Prerequisite genesis packages**: `@suaveplan/error`, `@suaveplan/events`, `@suaveplan/types`, `@suaveplan/testing`
> Numbered requirement / scenario checklist (AGENTS.md §0c pre-flight #6).
>
> R1 Public surface · R2 Error registry · R3 Zod boundary · R4 Apple-date decode · R5 Handle/chat/attachment resolution · R6 Phone normalisation · R7 SqliteReader seam · R8 Polling loop · R9 AbortSignal · R10 EventBus bridge · R11 Adapter MessageSourceAdapter · R12 InboundMessage projection · R13 OTel · R14 Real fixtures · R15 Runner discipline · R16 Docs coverage · R17 Subpath exports.
## 0. Pre-flight
- [x] 0.1 `git status` and `git worktree list` clean / accounted-for.
- [x] 0.2 `bun:sqlite` available in the genesis runner (Bun-managed).
## 1. Scaffold
- [x] 1.1 Create `packages/communication/messaging/imessage-adapter/` with `src/`, `tests/setup/`.
- [x] 1.2 `package.json` at `0.1.0`, `"type":"module"`, `sideEffects:false`, subpath exports per design (R17), deps on `@suaveplan/error`, `@suaveplan/events`, `@suaveplan/types`, `tslib`, `zod`, `@opentelemetry/api`.
- [x] 1.3 `vite.config.ts`, `vitest.config.ts`, `tsconfig.lib.json` per slack-client sibling.
- [x] 1.4 `tests/setup/polyfills.ts` wiring in-memory OTel meter provider.
## 2. Error-code registry (R2)
- [x] 2.1 `src/error-codes/error-codes.ts` — `defineCodes("IMESSAGE", [...])` with the ten codes, one typed error class per code.
- [x] 2.2 `src/error-codes/error-codes.test.ts` — every code reachable from a real call site (assert via `instanceof` from production-throwing helpers).
- [x] 2.3 `src/error-codes/error-codes.md`.
## 3. Schemas (R3)
- [x] 3.1 `src/schemas/schemas.ts` — Zod schemas for `IMessageWatcherConfig` + `IMessageAdapterConfig` + row + parsed shapes; `parseWatcherConfig` / `parseAdapterConfig` helpers that throw `IMessageInvalidConfigError`.
- [x] 3.2 `src/schemas/schemas.test.ts` — accept happy paths, reject negative pollIntervalMs and bad chatFilter types.
- [x] 3.3 `src/schemas/schemas.md`.
## 4. Types (no `.md` for `.types.ts`)
- [x] 4.1 `src/types/imessage.types.ts` — row, parsed, config interfaces (preserve upstream surface).
- [x] 4.2 `src/types/adapter.types.ts` — `InboundMessage`, `MessageSourceAdapter`.
- [x] 4.3 `src/types/seams.types.ts` — `SqliteReader`, `SqliteHandle`, `SqliteStatement`.
## 5. SQLite reader (R7)
- [x] 5.1 `src/sqlite/bun-sqlite-reader.ts` — `bunSqliteReader: SqliteReader` lazily importing `bun:sqlite`.
- [x] 5.2 `src/sqlite/bun-sqlite-reader.test.ts` — opens a real temp DB, runs a SELECT.
- [x] 5.3 `src/sqlite/bun-sqlite-reader.md`.
## 6. Fixtures
- [x] 6.1 `src/fixtures/chat-db-fixture.ts` — `createChatDbFixture(reader, path)` creating real chat.db-shaped tables + insert helpers.
- [x] 6.2 `src/fixtures/chat-db-fixture.test.ts` — round-trip insert + query.
- [x] 6.3 `src/fixtures/chat-db-fixture.md`.
## 7. Parser (R4, R5, R6)
- [x] 7.1 `src/parser/imessage-parser.ts` — `IMessageParser` with `parseMessage` / `parseAppleDate` / `parseAttachment` / `isGroupChat` / `normalizePhoneNumber`. `parseAppleDate` throws `IMessageAppleDateParseError` on NaN / non-finite.
- [x] 7.2 `src/parser/imessage-parser.test.ts` — covers every behaviour the upstream tests cover + the additional error paths.
- [x] 7.3 `src/parser/imessage-parser.md`.
## 8. Watcher (R8, R9, R10)
- [x] 8.1 `src/watcher/imessage-watcher.ts` — `IMessageWatcher` with EventBus bridge, AbortSignal, injectable reader, injectable clock + timers, OTel record calls.
- [x] 8.2 `src/watcher/imessage-watcher.test.ts` — real-bun:sqlite-fixture poll loop, AbortSignal short-circuit, includeFromMe / chatFilter, lastRowId monotonic, EventBus delivery, bus bridge via legacy `on()`, OTel emissions.
- [x] 8.3 `src/watcher/imessage-watcher.md`.
## 9. Adapter (R11, R12)
- [x] 9.1 `src/adapter/imessage-adapter.ts` — `IMessageAdapter` calling watcher, projecting `InboundMessage`, throwing `IMessageAdapterNotInitializedError` from `poll()` before `initialize()`.
- [x] 9.2 `src/adapter/imessage-adapter.test.ts` — full surface assertion, projection rules, last-processed-id, idempotent close, sibling-.md & subpath presence asserted.
- [x] 9.3 `src/adapter/imessage-adapter.md`.
## 10. OTel (R13)
- [x] 10.1 `src/otel/metrics.ts` — `recordMessageEmitted`, `recordAttachmentEmitted`, `recordPollError`, `recordPollDuration`, `refreshIMessageMeters`.
- [x] 10.2 `src/otel/metrics.test.ts` — assert each instrument lands on the in-memory exporter.
- [x] 10.3 `src/otel/metrics.md`.
## 11. Package barrel + README
- [x] 11.1 `src/index.ts` — explicit named re-exports of the full public surface (R1), side-effect import of `./error-codes/index.js`.
- [x] 11.2 Root `README.md` describing the package, install + usage, the four OTel instruments, the ten error codes, the SqliteReader seam.
## 12. Verify gates (R14, R15, R16, R17)
- [x] 12.1 `grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/communication/messaging/imessage-adapter/src/ packages/communication/messaging/imessage-adapter/tests/` → zero output.
- [x] 12.2 `grep -rnE "vi\.mock|jest\.mock|mock\.module" packages/communication/messaging/imessage-adapter/` → zero output.
- [x] 12.3 `grep -rn "biome-ignore\|TODO\|FIXME\|@deprecated\|ts-ignore\|ts-expect-error\|\.skip\|\.only" packages/communication/messaging/imessage-adapter/src/` → zero output.
- [x] 12.4 `bunx turbo lint typecheck test build --filter=@suaveplan/imessage-adapter` — green.
- [x] 12.5 `bunx turbo test:coverage --filter=@suaveplan/imessage-adapter` — 100/100/100/100.
## 13. Manifest + STATUS + finalisation
- [x] 13.1 `bun scripts/folder-reorg/generate-manifest.ts`.
- [x] 13.2 Flip `STATUS.md` `imessage-adapter` row to `✅` and bump the "Migrated" counter.
- [x] 13.3 Fold `specs/imessage-adapter/spec.md` into `openspec/specs/imessage-adapter/spec.md`.
- [x] 13.4 Move the change folder to `openspec/archive/2026-05-25-enterprise-imessage-adapter/`.
## 14. Commit (no push)
- [x] 14.1 Conventional commit + `Co-Authored-By: Claude` footer on branch `feat/migrate-imessage-adapter`.