@cosmicdrift/kumiko-bundled-features 0.21.0 → 0.22.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.
@@ -12,10 +12,12 @@
12
12
 
13
13
  import { afterAll, beforeAll, describe, expect, test } from "bun:test";
14
14
  import { asRawClient, insertOne } from "@cosmicdrift/kumiko-framework/bun-db";
15
+ import { fileRefsTable } from "@cosmicdrift/kumiko-framework/files";
15
16
  import {
16
17
  setupTestStack,
17
18
  type TestStack,
18
19
  unsafeCreateEntityTable,
20
+ unsafePushTables,
19
21
  } from "@cosmicdrift/kumiko-framework/stack";
20
22
  import { createComplianceProfilesFeature } from "../../compliance-profiles";
21
23
  import { createDataRetentionFeature } from "../../data-retention";
@@ -53,24 +55,10 @@ beforeAll(async () => {
53
55
  // Drizzle-Generated-Queries kollidieren).
54
56
  await unsafeCreateEntityTable(stack.db, userEntity);
55
57
 
56
- // file_refs ist framework-pgTable (nicht entity-getrieben, S1.5 hat
57
- // die Schema-Sicht ohne buildEntityTable-Auto-Generation). Manuelle
58
- // CREATE matched die Spalten aus framework/src/files/file-ref-table.ts
59
- await asRawClient(stack.db).unsafe(`
60
- CREATE TABLE IF NOT EXISTS file_refs (
61
- id UUID PRIMARY KEY,
62
- tenant_id UUID NOT NULL,
63
- storage_key TEXT NOT NULL,
64
- file_name TEXT NOT NULL,
65
- mime_type TEXT NOT NULL,
66
- size INTEGER NOT NULL,
67
- entity_type TEXT,
68
- entity_id TEXT,
69
- field_name TEXT,
70
- inserted_at TIMESTAMPTZ DEFAULT now() NOT NULL,
71
- inserted_by_id TEXT
72
- )
73
- `);
58
+ // file_refs ist jetzt das buildEntityTable-getriebene fileRef-Entity
59
+ // (softDelete is_deleted/deleted_at/deleted_by_id). Echte Entity-Tabelle
60
+ // pushen statt hand-CREATE, damit der is_deleted-Filter der Hooks greift.
61
+ await unsafePushTables(stack.db, { fileRefsTable });
74
62
  });
75
63
 
76
64
  afterAll(async () => {
@@ -30,9 +30,12 @@ import { fileRefsTable } from "@cosmicdrift/kumiko-framework/files";
30
30
  // Cleanup als TODO und faellen das in S2.U5 nochmal an.
31
31
 
32
32
  export const fileRefExportHook: UserDataExportHook = async (ctx) => {
33
+ // isDeleted:false — soft-deleted (trashed) Files gehören nicht ins
34
+ // Auskunfts-Bundle. Forget (delete-Hook unten) erfasst sie trotzdem.
33
35
  const rawRows = await selectMany(ctx.db, fileRefsTable, {
34
36
  tenantId: ctx.tenantId,
35
37
  insertedById: ctx.userId,
38
+ isDeleted: false,
36
39
  });
37
40
 
38
41
  // @cast-boundary db-row: drizzle liefert insertedAt als Instant
@@ -1,58 +0,0 @@
1
- import {
2
- createEntity,
3
- createNumberField,
4
- createTextField,
5
- createTimestampField,
6
- } from "@cosmicdrift/kumiko-framework/engine";
7
-
8
- // fileRef — Schema-Sicht der File-Metadata-Tabelle aus dem Framework.
9
- //
10
- // Architektur-Entscheidung (Sprint 1.5):
11
- //
12
- // Die DB-Tabelle `file_refs` lebt weiterhin in
13
- // `framework/src/files/file-ref-table.ts` als drizzle pgTable, weil
14
- // die Hono-Upload-/Download-Routes (`createFileRoutes` in
15
- // `framework/src/api/server.ts`) sie direkt nutzen. Multipart-Upload
16
- // und Binary-Streaming passen nicht in das Write/Query-Handler-Pattern
17
- // — Routes bleiben framework-internal.
18
- //
19
- // Was hier passiert: dieselbe DB-Tabelle wird zusätzlich als
20
- // `r.entity("fileRef")` in einem bundled-feature deklariert. Das
21
- // ermoeglicht:
22
- // 1. r.useExtension(EXT_USER_DATA, "fileRef", { export, delete })
23
- // in Sprint 2 — Forget-Flow + Daten-Export erkennen die Entity.
24
- // 2. r.useExtension(EXT_TENANT_DATA, "fileRef", { destroy })
25
- // in Sprint 5 — Tenant-Lifecycle löscht alle FileRefs.
26
- // 3. Boot-Validation für PII-Annotations greift (fileName, originalName).
27
- //
28
- // Kein buildEntityTable hier — die Mapping-Tabelle existiert schon im
29
- // Framework. Drizzle-Reads in den Sprint-2+-Hooks gehen direkt über
30
- // `fileRefsTable` aus `@cosmicdrift/kumiko-framework/files`.
31
- //
32
- // PII-Annotations (Sprint 0.1+0.7+1.7):
33
- // - fileName → pii: true (Originalname enthält oft Personen-Bezug:
34
- // "Marc-Lebenslauf.pdf", "Krankheitsattest-Mai.pdf")
35
- //
36
- // Andere Felder brauchen KEINE Annotation:
37
- // - storageKey, mimeType, size, entityType, entityId, fieldName,
38
- // insertedById → keine PII-typischen Field-Namen, PII-Heuristik
39
- // greift nicht (siehe boot-validator.ts PII_DIRECT_NAME_HINTS).
40
- // Ein allowPlaintext-Marker wäre Über-Annotation ohne Effekt.
41
- // - insertedAt → Audit-Timestamp, framework-managed.
42
- //
43
- // Tabellenname matched die Framework-pgTable damit r.entity-Reads über
44
- // dieselbe Postgres-Tabelle laufen.
45
- export const fileRefEntity = createEntity({
46
- table: "file_refs",
47
- fields: {
48
- storageKey: createTextField({ required: true }),
49
- fileName: createTextField({ required: true, pii: true }),
50
- mimeType: createTextField({ required: true }),
51
- size: createNumberField({ required: true }),
52
- entityType: createTextField(),
53
- entityId: createTextField(),
54
- fieldName: createTextField(),
55
- insertedAt: createTimestampField({ sortable: true, filterable: true }),
56
- insertedById: createTextField(),
57
- },
58
- });