@cosmicdrift/kumiko-types 0.273.0 → 0.275.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.273.0",
3
+ "version": "0.275.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>",
package/src/config.ts CHANGED
@@ -3,7 +3,7 @@ import type { ConcurrencyMode } from "./concurrency-mode";
3
3
  import type { ConfigScope } from "./config-scope";
4
4
  import type { DbConnection } from "./db-connection";
5
5
  import type { FieldDefinition } from "./fields";
6
- import type { JobContext } from "./handlers";
6
+ import type { EscapeHatchDeclaration, JobContext } from "./handlers";
7
7
  import type {
8
8
  PostDeleteHookFn,
9
9
  PostSaveHookFn,
@@ -392,6 +392,8 @@ export type JobDefinition = {
392
392
  // don't justify a separate worker container — long/CPU-heavy jobs on the
393
393
  // API lane will starve request handlers.
394
394
  readonly runIn?: JobRunIn | undefined;
395
+ // Grants `ctx.db.unsafeRaw(reason)` for this job, audited as `unsafe-raw`.
396
+ readonly escapeHatch?: EscapeHatchDeclaration | undefined;
395
397
  };
396
398
 
397
399
  // --- Notifications ---
@@ -74,7 +74,7 @@ export type EventStoreExecutor = {
74
74
  filter?:
75
75
  | {
76
76
  readonly field: string;
77
- readonly op: "eq" | "ne" | "lt" | "gt" | "in";
77
+ readonly op: "eq" | "ne" | "lt" | "gt" | "lte" | "gte" | "in";
78
78
  readonly value: unknown;
79
79
  }
80
80
  | undefined;
@@ -83,7 +83,7 @@ export type EventStoreExecutor = {
83
83
  filters?:
84
84
  | ReadonlyArray<{
85
85
  readonly field: string;
86
- readonly op: "eq" | "ne" | "lt" | "gt" | "in";
86
+ readonly op: "eq" | "ne" | "lt" | "gt" | "lte" | "gte" | "in";
87
87
  readonly value: unknown;
88
88
  }>
89
89
  | undefined;
package/src/feature.ts CHANGED
@@ -382,6 +382,8 @@ export type FeatureDefinition = {
382
382
  // rendering. Absence means the feature reads no env-vars (or hasn't
383
383
  // been migrated yet — Sprint-9 migration is add-only per phase).
384
384
  readonly envSchema?: z.ZodObject<z.ZodRawShape>;
385
+ // Factory guarantee: two instances with shallow-equal dedupeOptions are interchangeable.
386
+ readonly dedupeOptions?: Readonly<Record<string, unknown>>;
385
387
  };
386
388
 
387
389
  // --- Feature Registrar (the "r" object in defineFeature) ---
package/src/handlers.ts CHANGED
@@ -707,11 +707,14 @@ export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedCon
707
707
  //
708
708
  // The passed identity also decides the target tenant — `writeAs` hands
709
709
  // `user.tenantId` straight to the dispatcher with nothing cross-checking it
710
- // against the job's own tenant, exactly as `queryAs` and the raw `db` above
711
- // already do. Building an identity from job payload data is therefore a
712
- // cross-tenant write path; derive it from a trusted lookup instead.
710
+ // against the job's own tenant, exactly as `queryAs` does. Building an
711
+ // identity from job payload data is therefore a cross-tenant write path;
712
+ // derive it from a trusted lookup instead.
713
713
  export type JobContext = SharedContextFields & {
714
- readonly db: DbConnection;
714
+ // Tenant-filtered to the job's own tenant. Cross-tenant raw access needs
715
+ // `escapeHatch` on the job (`ctx.db.unsafeRaw(reason)`) or `r.systemScope()`
716
+ // (`ctx.systemDb`).
717
+ readonly db: TenantDb;
715
718
  readonly registry: Registry;
716
719
  readonly systemUser: SessionUser;
717
720
  readonly log: Logger;
package/src/screen.ts CHANGED
@@ -171,21 +171,23 @@ export type ListSortSpec = {
171
171
  // unterscheidet sie.
172
172
  //
173
173
  // Operatoren (Drizzle-konsistent):
174
- // eq/ne → field = value | field != value
175
- // lt/gt → field < value | field > value (numerisch / temporal)
176
- // in → field IN (...values), value muss readonly array sein
174
+ // eq/ne → field = value | field != value
175
+ // lt/gt → field < value | field > value (numerisch / temporal)
176
+ // lte/gte → field <= value | field >= value (numerisch / temporal)
177
+ // in → field IN (...values), value muss readonly array sein
177
178
  //
178
179
  // Field muss in der Entity existieren UND `filterable: true` haben
179
- // (Boot-Validator pinned beides). `lt`/`gt` nur auf vergleichbaren
180
- // Field-Types (number/money/date/timestamp/locatedTimestamp); auf
181
- // text/boolean/select/multiSelect lehnt der Validator das ab.
180
+ // (Boot-Validator pinned beides). `lt`/`gt`/`lte`/`gte` nur auf
181
+ // vergleichbaren Field-Types (number/money/date/timestamp/
182
+ // locatedTimestamp); auf text/boolean/select/multiSelect lehnt der
183
+ // Validator das ab.
182
184
  //
183
185
  // Security-Modell: Filter ist UX-Bucketing, KEINE Access-Boundary. Der
184
186
  // Server appliziert den filter aus dem Payload — der Client kann ihn
185
187
  // weglassen oder durch einen anderen ersetzen. Boundary bleiben
186
188
  // access-rule + Tenant-Scope; Felder mit Sicherheits-Bias (encrypted,
187
189
  // restricted) müssen dort geschützt werden, nicht über den Screen-Filter.
188
- export type ScreenFilterOp = "eq" | "ne" | "lt" | "gt" | "in";
190
+ export type ScreenFilterOp = "eq" | "ne" | "lt" | "gt" | "lte" | "gte" | "in";
189
191
  export type ScreenFilter = {
190
192
  readonly field: string;
191
193
  readonly op: ScreenFilterOp;