@cosmicdrift/kumiko-bundled-features 0.178.0 → 0.178.1

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-bundled-features",
3
- "version": "0.178.0",
3
+ "version": "0.178.1",
4
4
  "description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -120,12 +120,12 @@
120
120
  "./step-dispatcher": "./src/step-dispatcher/index.ts"
121
121
  },
122
122
  "dependencies": {
123
- "@cosmicdrift/kumiko-dispatcher-live": "0.178.0",
124
- "@cosmicdrift/kumiko-framework": "0.178.0",
125
- "@cosmicdrift/kumiko-headless": "0.178.0",
126
- "@cosmicdrift/kumiko-renderer": "0.178.0",
127
- "@cosmicdrift/kumiko-renderer-web": "0.178.0",
128
- "@cosmicdrift/kumiko-types": "0.178.0",
123
+ "@cosmicdrift/kumiko-dispatcher-live": "0.178.1",
124
+ "@cosmicdrift/kumiko-framework": "0.178.1",
125
+ "@cosmicdrift/kumiko-headless": "0.178.1",
126
+ "@cosmicdrift/kumiko-renderer": "0.178.1",
127
+ "@cosmicdrift/kumiko-renderer-web": "0.178.1",
128
+ "@cosmicdrift/kumiko-types": "0.178.1",
129
129
  "@mollie/api-client": "^4.5.0",
130
130
  "imapflow": "^1.3.3",
131
131
  "mailparser": "^3.9.8",
@@ -1,7 +1,6 @@
1
- // TemplateResolverApi — Cross-Feature-Schnittstelle. renderer-foundation
2
- // + delivery + Apps importieren NUR Types und holen die Implementation
3
- // runtime aus ctx.templateResolver. Pattern symmetrisch zu textContent
4
- // (siehe text-content/api.ts).
1
+ // TemplateResolverApi — cross-feature interface. renderer-foundation,
2
+ // delivery and apps import types ONLY and take the implementation from
3
+ // ctx.templateResolver at runtime.
5
4
 
6
5
  import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
7
6
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
@@ -15,14 +15,14 @@ import { upsertSystemWrite } from "./handlers/upsert-system.write";
15
15
  import { upsertTenantWrite } from "./handlers/upsert-tenant.write";
16
16
  import { templateResourceEntity } from "./table";
17
17
 
18
- // template-resolver — strukturierter Template-Storage mit Tenant-
19
- // Override-Hierarchie, Locale-Fallback und Resource-Linking via
20
- // file-foundation. Plan-Doc: kumiko-platform/docs/plans/features/template-resolver.md
18
+ // template-resolver — structured template storage with tenant-override
19
+ // hierarchy, locale fallback and resource linking via file-foundation.
20
+ // Plan doc: kumiko-platform/docs/plans/features/template-resolver.md
21
21
  //
22
- // Konsumtions-Pfade:
23
- // - Render-Time: ctx.templateResolver.resolveTemplate(...) (siehe api.ts)
24
- // - Admin-UI: write/query-handlers (upsertSystem, upsertTenant, publish, archive, findById, list)
25
- // - Cross-Feature: requireTemplateResolver(ctx, callerName) — Pattern wie requireTextContent
22
+ // Consumption paths:
23
+ // - Render time: ctx.templateResolver.resolveTemplate(...) (see api.ts)
24
+ // - Admin UI: write/query handlers (upsertSystem, upsertTenant, publish, archive, findById, list)
25
+ // - Cross-feature: requireTemplateResolver(ctx, callerName)
26
26
  export type TemplateResolverOptions = {
27
27
  /** Content collections this app mounts. Declared here rather than inside the
28
28
  * feature because `access` needs the host's role vocabulary — a bundled
@@ -50,7 +50,7 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
50
50
  }
51
51
  return defineFeature("template-resolver", (r) => {
52
52
  r.describe(
53
- "Stores notification and mail templates in the database with a 4-level fallback: tenant+locale \u2192 system+locale \u2192 tenant+fallback-locale \u2192 system+fallback-locale. Call `ctx.templateResolver.resolveTemplate({ tenantId, slug, kind, locale })` at render time; manage templates via the `upsertSystem`, `upsertTenant`, `publish`, and `archive` write handlers. Tenants can override system-default templates without touching application code.",
53
+ "The one content store: notification and mail templates, PDF document templates, AI prompts and plain editable text blocks all live here as one entity, distinguished by `kind` (`notification`, `mail-html`, `document-pdf`, `ai-prompt`, `text-block`, `image-snapshot`). Resolution uses a 4-level fallback: tenant+locale \u2192 system+locale \u2192 tenant+fallback-locale \u2192 system+fallback-locale, so tenants can override system defaults without touching application code. Call `ctx.templateResolver.resolveTemplate({ tenantId, slug, kind, locale })` at render time; manage templates via the `upsertSystem`, `upsertTenant`, `publish` and `archive` write handlers. Apps that want an editable collection in their navigation declare it at mount: `createTemplateResolverFeature({ collections: [{ id, kind, access: { roles }, nav }] })` \u2014 `access` belongs to the mount because a bundled feature does not know the host's role vocabulary. Each collection gets its own `<id>-list` / `<id>-item` / `<id>-set` handlers carrying that collection's access rule, so the dispatcher enforces the separation. Replaces the former `text-content` feature, whose blocks now live here as kind `text-block`.",
54
54
  );
55
55
  r.uiHints({
56
56
  displayLabel: "Template Resolver",
@@ -3,14 +3,13 @@ import { z } from "zod";
3
3
  import { CONTENT_FORMATS, TEMPLATE_STATUSES, UPSERT_KINDS } from "../constants";
4
4
  import { templateResourceEntity, templateResourcesTable } from "../table";
5
5
 
6
- // Single executor pro Bundle Pattern aus text-content. Wird von allen
7
- // 4 Handlers geteilt für create/update-Operationen mit Event-Store +
8
- // Optimistic-Lock.
6
+ // One executor per bundle, shared by all four handlers for create/update via
7
+ // event store + optimistic lock.
9
8
  export const executor = createEventStoreExecutor(templateResourcesTable, templateResourceEntity, {
10
9
  entityName: "template-resource",
11
10
  });
12
11
 
13
- // Slug-Regex symmetrisch zu text-content + plan-doc naming-convention.
12
+ // Slug regex follows the plan-doc naming convention.
14
13
  export const slugSchema = z
15
14
  .string()
16
15
  .min(1)
@@ -18,12 +18,11 @@ export const upsertSystemWrite = defineWriteHandler({
18
18
  access: { roles: ["SystemAdmin"] },
19
19
  handler: async (event, ctx) => {
20
20
  const db = ctx.db;
21
- // @cast-boundary engine-payload — SYSTEM_TENANT_ID ist UUID-Literal,
22
- // assert auf TenantId-Branded-Type (parseTenantId-Equivalent).
21
+ // @cast-boundary engine-payload — SYSTEM_TENANT_ID is a UUID literal,
22
+ // asserted to the branded TenantId (parseTenantId equivalent).
23
23
  const tenantId = SYSTEM_TENANT_ID as TenantId;
24
- // executor-user muss SYSTEM_TENANT als tenantId haben, sonst sucht
25
- // event-store stream unter user.tenantId statt SYSTEM_TENANT → conflict.
26
- // Pattern symmetrisch zu text-content setWrite Override-Branch.
24
+ // The executor user must carry SYSTEM_TENANT as tenantId, otherwise the
25
+ // event store looks up the stream under user.tenantId → conflict.
27
26
  const executorUser = { ...event.user, tenantId };
28
27
 
29
28
  const existing = await fetchOne<TemplateResourceRow>(db, templateResourcesTable, {