@cosmicdrift/kumiko-types 0.288.0 → 0.290.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.288.0",
3
+ "version": "0.290.0",
4
4
  "description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -0,0 +1,14 @@
1
+ [
2
+ {
3
+ "version": "0.290.0",
4
+ "type": "improvement",
5
+ "title": "EventMetadata: feature + handler + UNATTRIBUTED_ORIGIN",
6
+ "detail": "EventMetadata traegt zwei neue optionale Felder (feature, handler) und exportiert die Sentinel-Konstante UNATTRIBUTED_ORIGIN fuer Appends ausserhalb eines attribuierten Ausfuehrungsscopes. Additiv, bestehende Zeilen bleiben ohne Backfill lesbar."
7
+ },
8
+ {
9
+ "version": "0.289.0",
10
+ "type": "improvement",
11
+ "title": "EntityDefinition gains an optional transferable flag",
12
+ "detail": "Declares that an entity's rows can move to a different tenant via the tenant-handover bundled feature (kumiko-framework#3035): the root entity, or any parentRef-linked entity, that is NOT declared transferable makes a claim attempt fail with a named error instead of silently leaving its rows behind. Additive — every existing entity is unaffected (transferable defaults to unset/false)."
13
+ }
14
+ ]
@@ -37,7 +37,26 @@ export type EventStoreExecutor = {
37
37
  payload: { id: EntityId; version?: number | undefined; changes: Record<string, unknown> },
38
38
  user: SessionUser,
39
39
  db: TenantDb,
40
- options?: { skipOptimisticLock?: boolean; skipUnchanged?: boolean; preSave?: PreSaveRunner },
40
+ options?: {
41
+ skipOptimisticLock?: boolean;
42
+ skipUnchanged?: boolean;
43
+ preSave?: PreSaveRunner;
44
+ // Declarative precondition for a "genau einmal"-transition (kumiko-
45
+ // framework#3024): field/value pairs the row must still hold at write
46
+ // time — a `null` expected value matches a null field. Re-read fresh,
47
+ // atomically with the write's stream version (not the payload's stale
48
+ // `previous`), so a concurrent writer that already moved the row on is
49
+ // caught even when it doesn't collide with the stream-version check.
50
+ // Mismatch fails the whole update with PreconditionFailedError instead
51
+ // of applying it.
52
+ // Scalars only (string/number/boolean/null) — the check is `!==`, so an
53
+ // object/Date/Instant value would compare by reference and silently
54
+ // never match; a timestamp precondition needs its own scalar mirror
55
+ // field to check against, not the compound value itself. Also plain
56
+ // columns only: the check reads raw column values (no decrypt pass),
57
+ // so a pii/encrypted field can't be used here.
58
+ expect?: Readonly<Record<string, string | number | boolean | null>>;
59
+ },
41
60
  ) => Promise<WriteResult<SaveContext>>;
42
61
 
43
62
  delete: (
@@ -37,8 +37,21 @@ export type EventMetadata = {
37
37
  // app reads them when filtering/auditing. Keep values JSON-primitive
38
38
  // (string|number|boolean) so JSON serialization stays bulletproof.
39
39
  readonly headers?: Readonly<Record<string, string | number | boolean>>;
40
+ // Feature that owned the execution scope which wrote this event, and the
41
+ // qualified name of the handler/consumer/job inside it. Derived in
42
+ // event-store.append() from the ambient request scope, never passed in by
43
+ // the writer — attribution handed over can lie, attribution derived cannot.
44
+ // Optional so rows written before #3043 stay readable without a backfill;
45
+ // every new row carries both, falling back to UNATTRIBUTED_ORIGIN.
46
+ readonly feature?: string;
47
+ readonly handler?: string;
40
48
  };
41
49
 
50
+ // Stamped when an append runs outside any attributed scope (seed scripts,
51
+ // tests, direct event-store use). A distinct value, not an omission —
52
+ // omitted would be indistinguishable from a pre-#3043 row.
53
+ export const UNATTRIBUTED_ORIGIN = "unknown";
54
+
42
55
  // Generic over the payload shape. Default = Record<string, unknown> keeps
43
56
  // all existing consumers backwards-compatible; annotate `StoredEvent<MyEventPayload>`
44
57
  // where a typed payload read is needed.
package/src/fields.ts CHANGED
@@ -1012,4 +1012,14 @@ export type EntityDefinition<
1012
1012
  readonly derivedFields?: DerivedFieldsMap;
1013
1013
  /** Optional free-text semantics for the AI agent manifest — see TextFieldDef.description. */
1014
1014
  readonly description?: string;
1015
+ /**
1016
+ * Opts this entity's rows into the `tenant-handover` bundled feature
1017
+ * (kumiko-framework#3035): a row-bound-grant-legitimated ownership change
1018
+ * from an anonymous/public tenant to a freshly signed-up account's tenant.
1019
+ * An entity reachable from a transfer's root — the root itself, or any
1020
+ * entity whose `parentRef` names the root's type — that is NOT declared
1021
+ * `transferable: true` makes the whole transfer fail with a named error
1022
+ * instead of silently leaving that entity's rows behind.
1023
+ */
1024
+ readonly transferable?: boolean;
1015
1025
  };