Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
# Wire SurrealDB job-persistence store into `@suaveplan/api-plugin-export`
**Package**: `@suaveplan/api-plugin-export`
**Status**: PROPOSED
**Type**: follow-up (MODIFIED-Requirements)
**Spec delta**: ./specs/api-plugin-export/spec.md
## Why
`@suaveplan/api-plugin-export` shipped at `741e1b176` with the upstream §2 "Current-state assessment" surface only. The proposal (`openspec/archive/2026-05-19-add-api-plugin-export/proposal.md`) explicitly carved out `§3 "Job persistence" via SurrealDB`:
> Upstream §2 ships the in-memory `Map<string, ExportJob>`. SurrealDB persistence is §3 work and requires `surql/` migrations + integration tests against `@suaveplan/api-plugin-database`. Deferred.
The dependencies that were missing at ship time — `@suaveplan/api-plugin-database`, `@suaveplan/surrealdb`, `@suaveplan/api-plugin-events` (canonical positional-SurQL pattern) — have now landed on genesis. This change wires the previously-excluded SurrealDB job-persistence store in.
## What changes
- ADDED: `ExportJobStore` — formal async store contract (`get`, `set`, `delete`, `list`, `has`, `clear`) extracted from the implicit `Map<string, ExportJob>` surface so two backends can co-exist behind the same name.
- ADDED: `MemoryExportJobStore` — `Map<string, ExportJob>` wrapper implementing `ExportJobStore`. Equivalent to the existing in-memory job store; keeps the in-memory path on the new typed contract.
- ADDED: `SurrealExportStore` — SurrealDB-backed `ExportJobStore` implementation. CRUD over the `export_job` table using positional `$p0…$pN` placeholders (genesis canonical, matching `@suaveplan/api-plugin-events` repositories). Wraps every failure with `ExportError(EXPORT_CODES.JOB_PERSISTENCE_FAILED)`.
- ADDED: `EXPORT_CODES.JOB_PERSISTENCE_FAILED` — surfaces SurrealDB driver / network / parse failures from the `SurrealExportStore`. Cause chain preserves the underlying error.
- ADDED: `surql/tables/export_job.surql` migration — `DEFINE TABLE OVERWRITE export_job SCHEMAFULL` + every field on `ExportJobSchema` + indexes on `(status)`, `(format)`, `(resource)`, `(created_at)`.
- ADDED: `ServiceRegistry` slot `exportJobStore: ExportJobStore` via module augmentation. Independent of the pre-existing `exportJobs: Map<string, ExportJob>` slot, which remains for back-compat — callers wire whichever they want.
- MODIFIED: `Public surface and side-effect imports` requirement — the package barrel now also re-exports `ExportJobStore`, `MemoryExportJobStore`, `SurrealExportStore`, and the `JOB_PERSISTENCE_FAILED` code; new subpath exports `./store/types`, `./store/memory/memory-store`, `./store/surreal/surreal-store`.
## Out of scope
Hard-bound to "wire SurrealDB persistence". Specifically excluded from this change (per the calling instructions):
- Re-plumbing `ExportRoutesDeps.jobs` from `Map<string, ExportJob>` to `ExportJobStore`. The routes, the format writers (CSV / JSON / XLSX), and the streaming pipeline are untouched. Callers wire the new store directly until a future route-refactor change lands.
- `GET /:id/download` handler — separate excluded item from the original migration; remains deferred.
- Streaming exporters, S3 sink, OOXML extras, auth / rate-limit / idempotency / audit middleware composition, signed URLs, Parquet, scheduled exports — all unchanged from the original carve-out.
## Source mapping
| Requirement | Source | Notes |
|---|---|---|
| `ExportJobStore` async contract | `enterprise/api-plugin-export.md §3` + `events.EventRepository` shape | Mirrors the `IEventRepository` async-CRUD convention. |
| `SurrealExportStore` positional SurQL | `packages/api/api-plugin-events/src/repositories/event-repository/event-repository.ts` | Genesis-canonical `$p0`/`$p1` pattern. |
| `export_job.surql` migration | Upstream `../suaveplan/packages/server/api-plugin-export/surql/` parity + `ExportJobSchema` shape | All `ExportJobSchema` fields persisted. |
| `JOB_PERSISTENCE_FAILED` code | Genesis-wide `defineCodes` registry + `ExportError` hierarchy | New code; wired in `SurrealExportStore` only. |
## Impact
### Affected dependents
`@suaveplan/api-plugin-export` ships at `0.1.0` with no genesis consumers yet:
- `bunx turbo ls --filter=...@suaveplan/api-plugin-export` returns the package itself only — `[x] no action needed (no downstream consumers on genesis at this date)`.
### Migration note
No consumer-visible behavior change. The pre-existing `Map`-based job slot (`exportJobs: Map<string, ExportJob>`) is preserved unchanged. The new `ExportJobStore` interface and the two implementations (`MemoryExportJobStore`, `SurrealExportStore`) are additive surface; no existing call site is renamed, removed, or rerouted.