|
| 1 | +--- |
| 2 | +"@objectstack/spec": major |
| 3 | +"@objectstack/service-analytics": major |
| 4 | +"@objectstack/metadata": patch |
| 5 | +--- |
| 6 | + |
| 7 | +feat(spec)!: converge the 11 contracts-vs-domain dual-source type names (#4538) |
| 8 | + |
| 9 | +`packages/spec/src/contracts/` hand-wrote parameter/result interfaces whose |
| 10 | +names collided with same-named zod-derived types in the domains — the #4411 |
| 11 | +trap, tracked as 11 rows of `dual-source-exports.baseline.json`. Each name was |
| 12 | +judged individually against a three-repo import-level scan (framework, cloud, |
| 13 | +objectui): which declaration actually flows at runtime decides the direction. |
| 14 | +All 11 rows are deleted from the baseline; no name below is exported twice |
| 15 | +anymore. |
| 16 | + |
| 17 | +**Converged — `./contracts` now re-exports the domain zod type (same |
| 18 | +declaration on both entries, imports keep compiling from either):** |
| 19 | + |
| 20 | +- `NotificationChannel` → `system/notification.zod`'s |
| 21 | + `z.infer<NotificationChannelSchema>` (member sets were identical). |
| 22 | +- `ValidationResult` → `kernel/plugin-validator.zod` (shapes were identical). |
| 23 | +- `HealthStatus` → `kernel/startup-orchestrator.zod` (`details` narrows |
| 24 | + `Record<string, any>` → `Record<string, unknown>`). |
| 25 | +- `PluginStartupResult` → `kernel/startup-orchestrator.zod`. FROM `plugin: |
| 26 | + Plugin` (live object) and `error?: Error` TO the serializable projection |
| 27 | + (`plugin: { name, version? }`-passthrough, `error?: { name, message, |
| 28 | + stack?, code? }`). Neither side had any consumer outside spec; the |
| 29 | + zod-validatable shape wins. |
| 30 | +- `StartupOptions` → `kernel/startup-orchestrator.zod` — the PARSED tier |
| 31 | + (defaults applied). `IStartupOrchestrator.orchestrateStartup` now takes |
| 32 | + `StartupOptionsInput` (the caller-authored all-optional tier, also |
| 33 | + re-exported from `./contracts`). Fix for callers typed to the old |
| 34 | + all-optional `StartupOptions`: rename to `StartupOptionsInput`. |
| 35 | +- `JobExecution` → `system/job.zod`. The system schema's `duration` field is |
| 36 | + RENAMED `durationMs` — that is what every job adapter produces and what the |
| 37 | + `sys_job_run.duration_ms` column round-trips; the schema described records |
| 38 | + nothing ever wrote. Fix: `duration` → `durationMs` when parsing |
| 39 | + `JobExecutionSchema` payloads. |
| 40 | +- `AnalyticsQuery` → `data/analytics.zod`. The domain schema aligned to the |
| 41 | + contract's semantics first: `timezone` LOST its `.default('UTC')` — absence |
| 42 | + is meaningful (the engine resolves org timezone, #1982/#2018; the |
| 43 | + `/analytics` entry always refused to apply that default). The schema is now |
| 44 | + transform-free, so `AnalyticsQuery` ≡ `AnalyticsQueryInput` (both kept |
| 45 | + exported). Fix for code that relied on `.parse()` injecting `timezone: |
| 46 | + 'UTC'`: pass the timezone explicitly or resolve it via the engine chain |
| 47 | + (`selection.timezone ?? context.timezone ?? 'UTC'`). |
| 48 | + |
| 49 | +**Renamed — two genuinely different concepts were sharing one name (both |
| 50 | +flow at runtime):** |
| 51 | + |
| 52 | +- `./contracts` `DriverCapabilities` → **`AnalyticsDriverCapabilities`** |
| 53 | + (`{ nativeSql, objectqlAggregate, inMemory }`, the analytics strategy-chain |
| 54 | + execution-path probe). The `DriverCapabilities` name now belongs solely to |
| 55 | + the data domain's driver feature-flag record (`DriverCapabilitiesSchema`, |
| 56 | + what `IDataDriver.supports` declares). Fix: importers of the trio from |
| 57 | + `@objectstack/spec/contracts` (or `@objectstack/service-analytics`, whose |
| 58 | + re-export is renamed in lockstep) rename the import; importers who meant |
| 59 | + the driver flags import `DriverCapabilities` from `@objectstack/spec/data`. |
| 60 | + |
| 61 | +**Removed — the domain-side declaration was dead (zero import-level consumers |
| 62 | +in framework/cloud/objectui; the #4411 family's last survivors):** |
| 63 | + |
| 64 | +- `system` `MetadataExportOptionsSchema` / `MetadataExportOptions` and |
| 65 | + `MetadataImportOptionsSchema` / `MetadataImportOptions` (the |
| 66 | + `output`/`source`-directory bags). The names now have ONE declaration each: |
| 67 | + the `IMetadataService.exportMetadata` / `importMetadata` parameter |
| 68 | + interfaces on `./contracts` (`types`/`namespaces`/`format` and |
| 69 | + `conflictResolution`/`validate`/`dryRun`), which `MetadataManager` |
| 70 | + implements. No tombstone/D2 conversion, deliberately — these are runtime |
| 71 | + option-bag types, not authorable metadata (same reasoning as #4458). |
| 72 | + `@objectstack/metadata` re-exports the two names from `./contracts` now |
| 73 | + (it previously re-exported the dead system-side shapes its own manager |
| 74 | + did not accept). |
| 75 | +- `system` `JobSchedule` (the `= Schedule` back-compat alias). The name's one |
| 76 | + declaration is the `IJobService.schedule` boundary shape on `./contracts` |
| 77 | + (plain-string cron `expression`); the authored metadata type keeps its real |
| 78 | + name `Schedule`. Fix: `import type { JobSchedule } from |
| 79 | + '@objectstack/spec/system'` → `Schedule` (authoring tier) or the |
| 80 | + `./contracts` `JobSchedule` (service boundary), whichever you meant. |
0 commit comments