Initial Commit
This commit is contained in:
88
openspec/archive/2026-05-09-i18n-backend-http/tasks.md
Normal file
88
openspec/archive/2026-05-09-i18n-backend-http/tasks.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Tasks — `@suaveplan/i18n-backend-http` (fetch-based translation backend)
|
||||
|
||||
> Every checkbox MUST reflect work actually done in this change. Do not retroactively tick.
|
||||
|
||||
## 1. Spec authoring
|
||||
|
||||
- [x] 1.1 Read `openspec/cross-cutting-designs/2026-05-05-i18n-modular-split.md` end-to-end (especially §3, §6, §6.1)
|
||||
- [x] 1.2 Read `openspec/AGENTS.md` Sections 0, 0a, 6a, 7, 9, 13
|
||||
- [x] 1.3 Read source: `packages/i18n/i18n/src/core/backend/http/http-backend.ts`, `http-backend.test.ts`, `http-backend.schemas.ts`, `http-backend.md`, plus `packages/i18n/i18n/src/core/backend/backend.types.ts`
|
||||
- [x] 1.4 Draft `proposal.md` from `openspec/templates/proposal.md`
|
||||
- [x] 1.5 Fill `## Source mapping` table with verified line ranges from monolith
|
||||
- [x] 1.6 Draft `specs/i18n-backend-http/spec.md` from `openspec/templates/spec-delta.md`
|
||||
- [x] 1.7 Every requirement carries a `**Verified by:**` line naming concrete `it(...)` titles
|
||||
- [x] 1.8 `openspec change validate i18n-backend-http` exits with no errors
|
||||
|
||||
## 2. Package scaffold
|
||||
|
||||
- [x] 2.1 `mkdir -p packages/i18n/i18n-backend-http/src`
|
||||
- [x] 2.2 Author `package.json` — name `@suaveplan/i18n-backend-http`, version `0.1.0`, type `module`, sideEffects `false`. Deps: `@suaveplan/i18n-shared workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/error workspace:^`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`, `zod catalog:forms`. devDeps: `@suaveplan/testing workspace:^`, `@suaveplan/typescript-config workspace:^`, `@vitest/coverage-istanbul catalog:testing`, `vitest catalog:testing`.
|
||||
- [x] 2.3 Author `tsconfig.json` extending `@suaveplan/typescript-config/library.json`
|
||||
- [x] 2.4 Author `vite.config.ts` using `createTestConfig()` from `@suaveplan/testing/config`
|
||||
- [x] 2.5 Author `README.md` (≥200 words, includes Modules table linking to each `.md`)
|
||||
- [x] 2.6 Add `package.json` `exports` map with subpaths `.`, `./backend`, `./factory`, `./parser`, `./url-builder`
|
||||
|
||||
## 3. Implementation
|
||||
|
||||
- [x] 3.1 Author `src/backend.types.ts` — port `HttpBackendOptions`, `ParsePayloadFn`, `HttpHeadersInit`, `CustomHeadersFn`, `HttpBackendRetry` from monolith L8-L70 verbatim
|
||||
- [x] 3.2 Author `src/backend.schemas.ts` — port `HttpBackendOptionsSchema` Zod schema verbatim (40 lines)
|
||||
- [x] 3.3 Author `src/url-builder.ts` — extract `#buildUrl` body into a standalone `buildUrl(loadPath, locale, namespace): string` function with URL-encoding
|
||||
- [x] 3.4 Author `src/payload-parser.ts` — extract `defaultParsePayload` ParsePayloadFn (JSON parse + non-object rejection) as a standalone export
|
||||
- [x] 3.5 Author `src/observability.ts` — inline equivalents of `recordRead` from `packages/i18n/i18n/src/observability/backend-metrics.ts`; export `i18n.backend.http.read_duration_ms` histogram, `i18n.backend.http.read_total{outcome}` counter, `i18n.backend.http.read_errors_total{code,status?}` counter
|
||||
- [x] 3.6 Author `src/backend.ts` — port `HttpBackend` class from monolith L80-L240; rewire imports; emit metrics via `src/observability.ts`; thread optional `signal?: AbortSignal` into the `RequestInit` passed to `fetch` AND throw `I18nError(I18N.BACKEND_TIMEOUT)` when the signal aborts during retry; preserve `defaultFetch()` fallback (L242-L252)
|
||||
|
||||
## 4. Factory function
|
||||
|
||||
- [x] 4.1 Author `src/factory.ts` — `httpBackend(options: HttpBackendOptions): HttpBackend` returning `new HttpBackend(options)`
|
||||
|
||||
## 5. Documentation (sibling `.md` per implementation file)
|
||||
|
||||
- [x] 5.1 `src/backend.md` — port from `packages/i18n/i18n/src/core/backend/http/http-backend.md`; ≥200 words; basic + advanced examples (custom parser, custom headers, retry policy)
|
||||
- [x] 5.2 `src/factory.md` — ≥200 words; basic + advanced examples
|
||||
- [x] 5.3 `src/url-builder.md` — placeholder substitution + URL-encoding semantics
|
||||
- [x] 5.4 `src/payload-parser.md` — JSON-object rejection rules; how to plug a custom parser
|
||||
- [x] 5.5 `src/observability.md` — emitted metrics + units + cardinality
|
||||
- [x] 5.6 `README.md` `## Modules` section links every `.md`
|
||||
|
||||
## 6. Tests (Vitest, runner-neutral imports per CLAUDE.md §11)
|
||||
|
||||
- [x] 6.1 `src/backend.test.ts` — port every test from `packages/i18n/i18n/src/core/backend/http/http-backend.test.ts`; same `it(...)` titles for conformance traceability; cover 200 OK, 404 → `BACKEND_LOCALE_NOT_AVAILABLE`, 500 → `BACKEND_READ_FAILED`, TypeError network failure → `BACKEND_READ_FAILED`, payload-parse failure → `BACKEND_READ_FAILED`, custom `parsePayload`, `customHeaders` callback, `crossDomain: true`, injected retry policy
|
||||
- [x] 6.2 `src/backend.spec-conformance.test.ts` — one `it(...)` per spec requirement; titles match `**Verified by:**` lines exactly
|
||||
- [x] 6.3 `src/factory.test.ts` — `httpBackend()` returns `HttpBackend` instance; default `name === "http"`
|
||||
- [x] 6.4 `src/url-builder.test.ts` — `{locale}` and `{namespace}` substitution; URL-encoding for special characters
|
||||
- [x] 6.5 `src/payload-parser.test.ts` — JSON object accepted; array / null / primitive rejected with `BACKEND_READ_FAILED`
|
||||
- [x] 6.6 `src/index.test.ts` — every documented public export resolves through `.`, `./backend`, `./factory`, `./parser`, `./url-builder`
|
||||
- [x] 6.7 Add an AbortSignal cancellation test — pre-aborted signal causes `read` to throw `I18nError(I18N.BACKEND_TIMEOUT)`; mid-flight abort during retry also throws `BACKEND_TIMEOUT`
|
||||
- [x] 6.8 Every `it(...)` carries `{ timeout: 5000 }`
|
||||
- [x] 6.9 All test imports go through `@suaveplan/testing/runner` (CLAUDE.md §11) — verified by `grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/i18n/i18n-backend-http/src/` returning zero hits
|
||||
- [x] 6.10 No `// biome-ignore` suppressions (CLAUDE.md §9)
|
||||
- [x] 6.11 No `export *` in any non-root barrel (CLAUDE.md §10)
|
||||
|
||||
## 7. Pre-archive verification (5-gate triple)
|
||||
|
||||
- [x] 7.1 `bun run check` — Biome 0/0/0 across the monorepo
|
||||
- [x] 7.2 `bunx turbo lint typecheck test --filter=@suaveplan/i18n-backend-http` — green
|
||||
- [x] 7.3 `bunx turbo test:coverage --filter=@suaveplan/i18n-backend-http` — 100/100/100/100
|
||||
- [x] 7.4 `bun scripts/openspec-conformance.ts @suaveplan/i18n-backend-http` — exit 0
|
||||
- [x] 7.5 `bunx turbo build --filter=@suaveplan/i18n-backend-http` — green
|
||||
|
||||
## 8. Pre-archive 7-row checklist (AGENTS.md Section 13)
|
||||
|
||||
- [x] 8.1 Generics threaded — `HttpBackendRetry.run<T>` parametric generic preserved; `ParsePayloadFn` correctly typed
|
||||
- [x] 8.2 Zod schemas wired at the public boundary — `HttpBackendOptionsSchema` parses constructor input
|
||||
- [x] 8.3 Every error code thrown by at least one production path: `INVALID_OPTIONS` (constructor), `BACKEND_LOCALE_NOT_AVAILABLE` (404), `BACKEND_READ_FAILED` (5xx / network / parse failure), `BACKEND_TIMEOUT` (signal aborted)
|
||||
- [x] 8.4 Strict-mode tested — `RequestInit` shape verified via `expectTypeOf`
|
||||
- [x] 8.5 OTel histograms emitted from production paths: `i18n.backend.http.read_duration_ms`; counters `read_total`, `read_errors_total{status}`
|
||||
- [x] 8.6 Lifecycle dedup — N/A (HTTP backend has no async init/dispose)
|
||||
- [x] 8.7 No retroactive tick — every box reflects work done in this change
|
||||
|
||||
## 9. Manifest + ecosystem awareness
|
||||
|
||||
- [x] 9.1 Add `@suaveplan/i18n-backend-http` entry to root `CLAUDE.md` package listing
|
||||
- [x] 9.2 Run `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md`
|
||||
- [x] 9.3 Append `@suaveplan/i18n-backend-http` to `STATUS.md` Completed list
|
||||
|
||||
## 10. Archive
|
||||
|
||||
- [x] 10.1 Fold spec delta into `openspec/specs/i18n-backend-http/spec.md` (NEW capability spec — first delta becomes canonical)
|
||||
- [x] 10.2 Move `openspec/changes/i18n-backend-http/` → `openspec/archive/<yyyy-mm-dd>-i18n-backend-http/`
|
||||
Reference in New Issue
Block a user