@cosmicdrift/kumiko-samples 0.351.0 → 0.352.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.
Files changed (49) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +2 -2
  3. package/packages/bundled-features/src/cap-counter/book-cap-usage.ts +95 -54
  4. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +247 -0
  5. package/packages/bundled-features/src/cap-counter/changes.json +28 -0
  6. package/packages/bundled-features/src/cap-counter/constants.ts +8 -0
  7. package/packages/bundled-features/src/cap-counter/feature.ts +7 -0
  8. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +5 -0
  9. package/packages/bundled-features/src/cap-counter/index.ts +9 -0
  10. package/packages/bundled-features/src/cap-counter/payload-field.ts +10 -0
  11. package/packages/bundled-features/src/cap-counter/reservation-chain.ts +51 -0
  12. package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +3 -0
  13. package/packages/bundled-features/src/cap-counter/tables.ts +53 -0
  14. package/packages/bundled-features/src/cap-counter/value-cap-guard.ts +70 -0
  15. package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +63 -70
  16. package/packages/bundled-features/src/channel-discord/feature.ts +1 -0
  17. package/packages/bundled-features/src/channel-slack/feature.ts +1 -0
  18. package/packages/bundled-features/src/channel-teams/feature.ts +1 -0
  19. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +40 -0
  20. package/packages/bundled-features/src/delivery/attempt-log.ts +26 -3
  21. package/packages/bundled-features/src/delivery/changes.json +12 -0
  22. package/packages/bundled-features/src/delivery/constants.ts +1 -0
  23. package/packages/bundled-features/src/delivery/events.ts +3 -0
  24. package/packages/bundled-features/src/delivery/feature.ts +50 -2
  25. package/packages/bundled-features/src/delivery/index.ts +6 -0
  26. package/packages/bundled-features/src/delivery/mask-recipient-address.ts +40 -0
  27. package/packages/bundled-features/src/delivery/public-names.ts +5 -0
  28. package/packages/bundled-features/src/delivery/types.ts +12 -2
  29. package/packages/bundled-features/src/derivatives-sharp/changes.json +6 -0
  30. package/packages/bundled-features/src/legal-pages/README.md +3 -3
  31. package/packages/bundled-features/src/legal-pages/changes.json +6 -0
  32. package/packages/bundled-features/src/renderer-foundation/types.ts +1 -1
  33. package/packages/bundled-features/src/renderer-simple/changes.json +6 -0
  34. package/packages/bundled-features/src/renderer-simple/feature.ts +4 -6
  35. package/packages/bundled-features/src/renderer-simple/index.ts +1 -0
  36. package/packages/bundled-features/src/renderer-simple/mail-blocks.ts +138 -0
  37. package/packages/bundled-features/src/renderer-simple/simple-renderer.ts +33 -4
  38. package/packages/bundled-features/src/tier-engine/changes.json +6 -0
  39. package/packages/bundled-features/src/tier-engine/index.ts +7 -0
  40. package/packages/bundled-features/src/tier-engine/tier-option-gate.ts +148 -0
  41. package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +36 -6
  42. package/samples/apps/marketing-demo/src/app/seed-data.ts +2 -2
  43. package/samples/apps/styleguide/src/app/shell.tsx +1 -1
  44. package/samples/apps/styleguide/src/features/gallery/web/Gallery.tsx +9 -3
  45. package/samples/apps/ui-walkthrough/src/app/assistant-action.tsx +6 -5
  46. package/samples/apps/ui-walkthrough/src/app/shell.tsx +3 -2
  47. package/samples/apps/ui-walkthrough/src/features/tasks/i18n.ts +8 -0
  48. package/samples/recipes/files-post-processing/package.json +1 -1
  49. package/samples/recipes/seed-migration/README.md +13 -1
@@ -606,20 +606,26 @@ export function Gallery(): ReactNode {
606
606
  <div className="flex flex-col gap-5 px-6 py-6">
607
607
  <div className="flex items-center gap-4">
608
608
  <div className="bg-muted text-foreground flex size-16 items-center justify-center rounded-full text-lg font-semibold">
609
- MF
609
+ AM
610
610
  </div>
611
611
  <Button variant="secondary">Change avatar</Button>
612
612
  </div>
613
613
  <div className="grid gap-4 sm:grid-cols-2">
614
614
  <Field id="pf-name" label="Full name">
615
- <Input kind="text" id="pf-name" name="pf-name" value="Marc Frost" onChange={noop} />
615
+ <Input
616
+ kind="text"
617
+ id="pf-name"
618
+ name="pf-name"
619
+ value="Alex Morgan"
620
+ onChange={noop}
621
+ />
616
622
  </Field>
617
623
  <Field id="pf-email" label="Email">
618
624
  <Input
619
625
  kind="text"
620
626
  id="pf-email"
621
627
  name="pf-email"
622
- value="marc@cosmicdrift.dev"
628
+ value="alex@example.com"
623
629
  onChange={noop}
624
630
  />
625
631
  </Field>
@@ -1,4 +1,4 @@
1
- import { usePrimitives } from "@cosmicdrift/kumiko-renderer";
1
+ import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
2
2
  import { WandSparkles } from "lucide-react";
3
3
  import { type ReactNode, useEffect, useState } from "react";
4
4
 
@@ -6,6 +6,7 @@ const noop = (): void => {};
6
6
 
7
7
  export function AssistantAction(): ReactNode {
8
8
  const { Dialog } = usePrimitives();
9
+ const t = useTranslation();
9
10
  const [open, setOpen] = useState(false);
10
11
 
11
12
  // Registered here on purpose: an overflow menu that unmounts this component
@@ -30,7 +31,7 @@ export function AssistantAction(): ReactNode {
30
31
  className="inline-flex h-9 items-center gap-2 rounded-md border border-border bg-card px-3 text-sm font-medium text-foreground hover:bg-accent"
31
32
  >
32
33
  <WandSparkles className="h-4 w-4" aria-hidden="true" />
33
- Assistent
34
+ {t("tasks.assistant.label")}
34
35
  <kbd className="rounded border border-border px-1 font-sans text-xs text-muted-foreground">
35
36
  ⌘K
36
37
  </kbd>
@@ -38,9 +39,9 @@ export function AssistantAction(): ReactNode {
38
39
  <Dialog
39
40
  open={open}
40
41
  onOpenChange={setOpen}
41
- title="Assistent"
42
- description="Der Assistent ist im Walkthrough nicht angebunden."
43
- confirmLabel="Schließen"
42
+ title={t("tasks.assistant.label")}
43
+ description={t("tasks.assistant.description")}
44
+ confirmLabel={t("tasks.assistant.close")}
44
45
  onConfirm={noop}
45
46
  testId="assistant-dialog"
46
47
  />
@@ -13,6 +13,7 @@ import {
13
13
  SidebarBrand,
14
14
  ThemeMenuItem,
15
15
  ThemeToggle,
16
+ useTranslation,
16
17
  } from "@cosmicdrift/kumiko-renderer-web";
17
18
  import { MoonStar, Sun } from "lucide-react";
18
19
  import type { ReactNode } from "react";
@@ -20,7 +21,6 @@ import { AssistantAction } from "./assistant-action";
20
21
  import { BETA_TENANT_ID, DEV_TENANT_ID } from "./auth-constants";
21
22
 
22
23
  const APP_NAME = "Kumiko Walkthrough";
23
- const APP_TAGLINE = "Design-Referenz";
24
24
 
25
25
  const tenantName = (tenantId: string): string => {
26
26
  if (tenantId === DEV_TENANT_ID) return "Dev Tenant";
@@ -40,9 +40,10 @@ export function AppShell({
40
40
  readonly children: ReactNode;
41
41
  readonly schema: AppSchema;
42
42
  }): ReactNode {
43
+ const t = useTranslation();
43
44
  return (
44
45
  <DefaultAppShell
45
- brand={<SidebarBrand name={APP_NAME} plan={APP_TAGLINE} />}
46
+ brand={<SidebarBrand name={APP_NAME} plan={t("tasks.shell.tagline")} />}
46
47
  schema={schema}
47
48
  headerActions={
48
49
  <>
@@ -5,6 +5,10 @@ import type { TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
5
5
 
6
6
  export const tasksTranslations: TranslationsByLocale = {
7
7
  de: {
8
+ "tasks.shell.tagline": "Design-Referenz",
9
+ "tasks.assistant.label": "Assistent",
10
+ "tasks.assistant.description": "Der Assistent ist im Walkthrough nicht angebunden.",
11
+ "tasks.assistant.close": "Schließen",
8
12
  "tasks.nav.group": "Allgemein",
9
13
  "tasks.nav.list": "Aufgaben",
10
14
  "tasks.nav.new": "Neue Aufgabe",
@@ -21,6 +25,10 @@ export const tasksTranslations: TranslationsByLocale = {
21
25
  "tasks:entity:task:field:notes": "Notizen",
22
26
  },
23
27
  en: {
28
+ "tasks.shell.tagline": "Design reference",
29
+ "tasks.assistant.label": "Assistant",
30
+ "tasks.assistant.description": "The assistant is not connected in the walkthrough.",
31
+ "tasks.assistant.close": "Close",
24
32
  "tasks.nav.group": "General",
25
33
  "tasks.nav.list": "Tasks",
26
34
  "tasks.nav.new": "New task",
@@ -7,6 +7,6 @@
7
7
  "@cosmicdrift/kumiko-framework": "workspace:*"
8
8
  },
9
9
  "devDependencies": {
10
- "sharp": "^0.35.3"
10
+ "sharp": "^0.35.5"
11
11
  }
12
12
  }
@@ -5,7 +5,7 @@ File-based migrations for Event-Sourcing operations — like `kumiko schema appl
5
5
  ## What it shows
6
6
 
7
7
  - **`seedsDir`-Option** in `runProdApp({ seedsDir: "./seeds" })` — beim Boot werden pending Files in chronologischer Reihenfolge angewendet und in `kumiko_es_operations` markiert.
8
- - **`SeedMigration`-Interface** — default-Export einer seed-File mit `description` + `run(ctx)`. ctx liefert `systemWriteAs` (System-User bypassed Access-Check) + Read-Helpers (`findUserByEmail`, `findMembershipsOfUser`, `findTenants`).
8
+ - **`SeedMigration`-Interface** — default-Export einer seed-File mit `description` + `run(ctx)`. ctx liefert `systemWriteAs` (System-User bypassed Access-Check) + Read-Helpers (`findUserByEmail`, `findMembershipsOfUser`, `findTenants`, `findTemplateResources`).
9
9
  - **Idempotency** — Marker landet nach Erfolg in der Tracking-Tabelle, zweiter Boot skipped applied Seeds.
10
10
  - **Tx-Atomicity** — Jede Migration läuft in eigener Transaction; Failure rollt zurück + bricht Boot ab (kein Partial-Apply).
11
11
  - **Chronologische File-IDs** — Filename `<date>-<slug>.ts` (z.B. `2026-05-20-fix-admin-roles.ts`) ist die ID.
@@ -35,6 +35,18 @@ seed: 2026-05-20-fix-admin-roles.ts
35
35
 
36
36
  Bei typo / drift fail-t mit klarer message + exit-code 1 — CI nutzt es als prä-build-step. App-Author muss in `smoke.ts` den `features`-Array gegen die eigene App-Feature-Set tauschen (siehe TODO im File).
37
37
 
38
+ ### Archive template rows
39
+
40
+ `findTemplateResources({ slug?, kind?, status?, locale?, tenantId? })` replaces a raw `SELECT … FROM read_template_resources`. It defaults to the system tenant and returns `[]` when template-resolver is not mounted:
41
+
42
+ ```ts
43
+ for (const t of await ctx.findTemplateResources({ kind: "notification", status: "active" })) {
44
+ await ctx.systemWriteAs("template-resolver:write:archive", { id: t.id }, SYSTEM_TENANT_ID, [
45
+ "SystemAdmin",
46
+ ]);
47
+ }
48
+ ```
49
+
38
50
  ## When to reach for it
39
51
 
40
52
  Du hast einen idempotent-Seeder der bei initialer Erstellung „Insert wenn nicht existiert" macht (z.B. `auth.admin.memberships`), und dann ändern sich die Soll-Daten — neue Rolle, anderer Tier, korrigierte Bezeichnung. Idempotent-Seeder skippen die existing Rows → DB driftet vom Code-Stand ab.