Fundament: atomare Mandanten-Transaktionen, iframe-Vorschau, Uploads bis 25 MB, DSGVO-Felder
- db.ts: tenantTransaction() – atomar auch bei RLS_ENFORCED=true (AsyncLocalStorage bindet Operationen an eine craftvia_app-Transaktion, Kontext einmal gesetzt, verschachtelte Aufrufe treten bei, fremder Mandant wird abgewiesen) - services/context.ts: inTransaction(ctx, fn); imports/confirm.ts umgestellt - next.config.ts: EMBEDDABLE_FILE_ROUTES mit frame-ancestors 'self'/SAMEORIGIN (PDF-Vorschau Prüfmaske), proxyClientMaxBodySize 26mb (Import bis 25 MB) - test-rls-enforcement: RLS-URL-Default aus DATABASE_URL (Lane-DBs) - dsgvo/pii-fields: 26 Personenreferenzen des Craftvia-Domänenmodells - ARCHITEKTUR §4.8: Transaktions-, Header-, Upload-, Versions- und PII-Regeln - Test test-tenant-transaction (Commit/Rollback/Fremdmandant/Verschachtelung), grün im Owner- und im RLS-Modus Gate: tsc, lint, build, 31/31 Tests grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,4 +20,33 @@ export interface PiiReference {
|
||||
export const PII_REFERENCE_FIELDS: readonly PiiReference[] = [
|
||||
{ model: "AuditLog", field: "actorId" },
|
||||
{ model: "NotificationPreference", field: "userId" },
|
||||
// ── Craftvia domain (0002_craftvia_domain) ──
|
||||
{ model: "Customer", field: "createdById" },
|
||||
{ model: "Team", field: "leaderUserId" },
|
||||
{ model: "TeamMember", field: "userId" },
|
||||
{ model: "WorkOrder", field: "createdById" },
|
||||
{ model: "WorkOrder", field: "teamLeadUserId" },
|
||||
{ model: "WorkOrderAssignee", field: "userId" },
|
||||
{ model: "WorkOrderStatusChange", field: "actorId" },
|
||||
{ model: "ChecklistItem", field: "checkedById" },
|
||||
{ model: "MaterialUsage", field: "recordedById" },
|
||||
{ model: "WorkSession", field: "userId" },
|
||||
{ model: "TimeEntry", field: "userId" },
|
||||
{ model: "TimeEntry", field: "correctedById" },
|
||||
{ model: "ActivityNote", field: "authorId" },
|
||||
{ model: "Document", field: "uploadedById" },
|
||||
{ model: "Photo", field: "takenById" },
|
||||
{ model: "VoiceNote", field: "recordedById" },
|
||||
{ model: "Report", field: "createdById" },
|
||||
{ model: "Report", field: "teamApprovedById" },
|
||||
{ model: "Report", field: "approvedById" },
|
||||
{ model: "Signature", field: "capturedById" },
|
||||
{ model: "ImportJob", field: "importedById" },
|
||||
{ model: "ImportJob", field: "confirmedById" },
|
||||
{ model: "Notification", field: "userId" },
|
||||
{ model: "SyncOperation", field: "userId" },
|
||||
{ model: "SyncOperation", field: "resolvedById" },
|
||||
{ model: "AiGeneration", field: "createdById" },
|
||||
// Free-text person data of END CUSTOMERS (Customer/Contact/Site/Signature.signerName) is
|
||||
// tenant business data under data processing — not part of the employee subject export.
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user