@happyvertical/smrt-timesheets 0.55.0 → 0.55.2

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 (34) hide show
  1. package/AGENTS.md +8 -0
  2. package/dist/attendance.js +2 -2
  3. package/dist/chunks/{attendance-kUM0ANfE.js → attendance-4_GFyiq5.js} +3 -3
  4. package/dist/chunks/{attendance-kUM0ANfE.js.map → attendance-4_GFyiq5.js.map} +1 -1
  5. package/dist/chunks/{models-DNbDLJCb.js → models-C8pv3ICs.js} +2 -2
  6. package/dist/chunks/{models-DNbDLJCb.js.map → models-C8pv3ICs.js.map} +1 -1
  7. package/dist/chunks/{rollup-D18ToLCo.js → rollup-BvUuTKOe.js} +3 -3
  8. package/dist/chunks/{rollup-D18ToLCo.js.map → rollup-BvUuTKOe.js.map} +1 -1
  9. package/dist/chunks/{service-time-entry-BAkx99ks.js → service-time-entry-NSayW3DB.js} +2 -2
  10. package/dist/chunks/service-time-entry-NSayW3DB.js.map +1 -0
  11. package/dist/index.js +3 -3
  12. package/dist/manifest.json +26 -5
  13. package/dist/rollup.js +1 -1
  14. package/dist/smrt-knowledge.json +5 -5
  15. package/dist/svelte/components/TimeEntryApprovalQueue.svelte +21 -11
  16. package/dist/svelte/components/TimeEntryApprovalQueue.svelte.d.ts +8 -0
  17. package/dist/svelte/components/TimeEntryApprovalQueue.svelte.d.ts.map +1 -1
  18. package/dist/svelte/components/TimeEntryCard.svelte +10 -1
  19. package/dist/svelte/components/TimeEntryCard.svelte.d.ts +5 -1
  20. package/dist/svelte/components/TimeEntryCard.svelte.d.ts.map +1 -1
  21. package/dist/svelte/components/TimeEntryList.svelte +11 -1
  22. package/dist/svelte/components/TimeEntryList.svelte.d.ts +6 -1
  23. package/dist/svelte/components/TimeEntryList.svelte.d.ts.map +1 -1
  24. package/dist/svelte/components/TimeSummary.svelte +12 -4
  25. package/dist/svelte/components/TimeSummary.svelte.d.ts +3 -1
  26. package/dist/svelte/components/TimeSummary.svelte.d.ts.map +1 -1
  27. package/dist/svelte/components/utils.d.ts +6 -1
  28. package/dist/svelte/components/utils.d.ts.map +1 -1
  29. package/dist/svelte/components/utils.js +41 -9
  30. package/dist/svelte/index.d.ts +1 -1
  31. package/dist/svelte/index.d.ts.map +1 -1
  32. package/dist/svelte/index.js +1 -1
  33. package/package.json +7 -7
  34. package/dist/chunks/service-time-entry-BAkx99ks.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-time-entry-NSayW3DB.js","names":[],"sources":["../../src/__smrt-register__.ts","../../src/models/json.ts","../../src/models/service-time-entry.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"packageVersion\\\":\\\"0.55.2\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-timesheets:AttendancePunch\\\":{\\\"name\\\":\\\"attendancepunch\\\",\\\"className\\\":\\\"AttendancePunch\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:AttendancePunch\\\",\\\"collection\\\":\\\"attendancepunches\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"profileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\"},\\\"startedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"endedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"durationSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"unpaidBreakSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"reviewRequired\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":true,\\\"default\\\":false},\\\"recordedOffline\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":true,\\\"default\\\":false},\\\"serviceTimeEntryId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"ServiceTimeEntry\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"openSlot\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"attendance_punches\\\",\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_punches_open_owner_key\\\",\\\"columns\\\":[\\\"tenantId\\\",\\\"profileId\\\",\\\"openSlot\\\"],\\\"unique\\\":true}],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AttendancePunch\\\",\\\"collectionExportName\\\":\\\"AttendancePunchCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"durationSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"},{\\\"field\\\":\\\"unpaidBreakSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"},{\\\"field\\\":\\\"reviewRequired\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"boolean\\\"},{\\\"field\\\":\\\"recordedOffline\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"boolean\\\"},{\\\"field\\\":\\\"openSlot\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"attendance_punches\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"attendance_punches\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"duration_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"unpaid_break_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"review_required\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"recorded_offline\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"service_time_entry_id\\\\\\\" UUID,\\\\n \\\\\\\"open_slot\\\\\\\" TEXT NOT NULL\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"duration_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"unpaid_break_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"review_required\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"recorded_offline\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"service_time_entry_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"open_slot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_punches_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_punches_open_owner_key\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"profile_id\\\",\\\"open_slot\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_punches_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"attendance_punches_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"attendance_punches_service_time_entry_id_idx\\\",\\\"columns\\\":[\\\"service_time_entry_id\\\"]}],\\\"version\\\":\\\"eeca63b1\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/attendance\\\"},\\\"@happyvertical/smrt-timesheets:AttendanceBreak\\\":{\\\"name\\\":\\\"attendancebreak\\\",\\\"className\\\":\\\"AttendanceBreak\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:AttendanceBreak\\\",\\\"collection\\\":\\\"attendancebreaks\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"punchId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AttendancePunch\\\"},\\\"startedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"endedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"paid\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":true,\\\"default\\\":false},\\\"openSlot\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"attendance_breaks\\\",\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_breaks_open_punch_key\\\",\\\"columns\\\":[\\\"tenantId\\\",\\\"punchId\\\",\\\"openSlot\\\"],\\\"unique\\\":true}],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AttendanceBreak\\\",\\\"collectionExportName\\\":\\\"AttendanceBreakCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"paid\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"boolean\\\"},{\\\"field\\\":\\\"openSlot\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"attendance_breaks\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"attendance_breaks\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"punch_id\\\\\\\" UUID,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"paid\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"open_slot\\\\\\\" TEXT NOT NULL\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"punch_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"attendance_punches\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"paid\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"open_slot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_breaks_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_breaks_open_punch_key\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"punch_id\\\",\\\"open_slot\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_breaks_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"attendance_breaks_punch_id_idx\\\",\\\"columns\\\":[\\\"punch_id\\\"]}],\\\"version\\\":\\\"00cb739e\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/attendance\\\"},\\\"@happyvertical/smrt-timesheets:AttendanceReplay\\\":{\\\"name\\\":\\\"attendancereplay\\\",\\\"className\\\":\\\"AttendanceReplay\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:AttendanceReplay\\\",\\\"collection\\\":\\\"attendancereplays\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"replayKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true,\\\"unique\\\":true}},\\\"content\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"outcome\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}}},\\\"methods\\\":{\\\"getOutcome\\\":{\\\"name\\\":\\\"getOutcome\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"AttendanceReplayOutcome\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setOutcome\\\":{\\\"name\\\":\\\"setOutcome\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"AttendanceReplayOutcome\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"attendance_replays\\\",\\\"sensitive\\\":true,\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AttendanceReplay\\\",\\\"collectionExportName\\\":\\\"AttendanceReplayCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"replayKey\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"attendance_replays\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"attendance_replays\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"replay_key\\\\\\\" TEXT NOT NULL UNIQUE,\\\\n \\\\\\\"content\\\\\\\" TEXT,\\\\n \\\\\\\"outcome\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"replay_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":true},\\\"content\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"outcome\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_replays_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_replays_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"f051b7b6\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/attendance\\\"},\\\"@happyvertical/smrt-timesheets:AttendancePunchCollection\\\":{\\\"name\\\":\\\"attendancepunchcollection\\\",\\\"className\\\":\\\"AttendancePunchCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:AttendancePunchCollection\\\",\\\"collection\\\":\\\"attendancepunches\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"attendance_punches\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AttendancePunch\\\",\\\"exportName\\\":\\\"AttendancePunchCollection\\\",\\\"collectionExportName\\\":\\\"AttendancePunchCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"attendance_punches\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"attendance_punches\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"duration_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"unpaid_break_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"review_required\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"recorded_offline\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"service_time_entry_id\\\\\\\" UUID,\\\\n \\\\\\\"open_slot\\\\\\\" TEXT NOT NULL\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"duration_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"unpaid_break_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"review_required\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"recorded_offline\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"service_time_entry_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"open_slot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_punches_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_punches_open_owner_key\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"profile_id\\\",\\\"open_slot\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_punches_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"attendance_punches_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"attendance_punches_service_time_entry_id_idx\\\",\\\"columns\\\":[\\\"service_time_entry_id\\\"]}],\\\"version\\\":\\\"eeca63b1\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/attendance\\\"},\\\"@happyvertical/smrt-timesheets:AttendanceBreakCollection\\\":{\\\"name\\\":\\\"attendancebreakcollection\\\",\\\"className\\\":\\\"AttendanceBreakCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:AttendanceBreakCollection\\\",\\\"collection\\\":\\\"attendancebreaks\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"attendance_breaks\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AttendanceBreak\\\",\\\"exportName\\\":\\\"AttendanceBreakCollection\\\",\\\"collectionExportName\\\":\\\"AttendanceBreakCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"attendance_breaks\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"attendance_breaks\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"punch_id\\\\\\\" UUID,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"paid\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"open_slot\\\\\\\" TEXT NOT NULL\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"punch_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"attendance_punches\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"paid\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"open_slot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_breaks_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_breaks_open_punch_key\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"punch_id\\\",\\\"open_slot\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_breaks_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"attendance_breaks_punch_id_idx\\\",\\\"columns\\\":[\\\"punch_id\\\"]}],\\\"version\\\":\\\"00cb739e\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/attendance\\\"},\\\"@happyvertical/smrt-timesheets:AttendanceReplayCollection\\\":{\\\"name\\\":\\\"attendancereplaycollection\\\",\\\"className\\\":\\\"AttendanceReplayCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:AttendanceReplayCollection\\\",\\\"collection\\\":\\\"attendancereplays\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"attendance_replays\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AttendanceReplay\\\",\\\"exportName\\\":\\\"AttendanceReplayCollection\\\",\\\"collectionExportName\\\":\\\"AttendanceReplayCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"attendance_replays\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"attendance_replays\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"replay_key\\\\\\\" TEXT NOT NULL UNIQUE,\\\\n \\\\\\\"content\\\\\\\" TEXT,\\\\n \\\\\\\"outcome\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"replay_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":true},\\\"content\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"outcome\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"attendance_replays_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"attendance_replays_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"f051b7b6\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/attendance\\\"},\\\"@happyvertical/smrt-timesheets:ServiceChargeSnapshot\\\":{\\\"name\\\":\\\"servicechargesnapshot\\\",\\\"className\\\":\\\"ServiceChargeSnapshot\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:ServiceChargeSnapshot\\\",\\\"collection\\\":\\\"servicechargesnapshots\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-snapshots.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"timeEntryId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ServiceTimeEntry\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"amount\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0},\\\"currency\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"pricingVersion\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"strategy\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"rateSnapshot\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"sourceChargeRef\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"createdAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"initialize\\\":{\\\"name\\\":\\\"initialize\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"service_charge_snapshots\\\",\\\"previousQualifiedNames\\\":[\\\"@happyvertical/smrt-projects:ServiceChargeSnapshot\\\"],\\\"conflictColumns\\\":[\\\"time_entry_id\\\"],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ServiceChargeSnapshot\\\",\\\"collectionExportName\\\":\\\"ServiceChargeSnapshotCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"timeEntryId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"service_charge_snapshots\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"service_charge_snapshots\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"time_entry_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"amount\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"currency\\\\\\\" TEXT,\\\\n \\\\\\\"pricing_version\\\\\\\" TEXT,\\\\n \\\\\\\"strategy\\\\\\\" TEXT,\\\\n \\\\\\\"rate_snapshot\\\\\\\" TEXT,\\\\n \\\\\\\"source_charge_ref\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"time_entry_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"amount\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"currency\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"pricing_version\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"strategy\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rate_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"source_charge_ref\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"service_charge_snapshots_time_entry_id_idx\\\",\\\"columns\\\":[\\\"time_entry_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"service_charge_snapshots_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"service_charge_snapshots_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"1393a1e2\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets\\\"},\\\"@happyvertical/smrt-timesheets:ServiceCompensationSnapshot\\\":{\\\"name\\\":\\\"servicecompensationsnapshot\\\",\\\"className\\\":\\\"ServiceCompensationSnapshot\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:ServiceCompensationSnapshot\\\",\\\"collection\\\":\\\"servicecompensationsnapshots\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-snapshots.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"timeEntryId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ServiceTimeEntry\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"amount\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0},\\\"currency\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"termsVersion\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"rateSnapshot\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"createdAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"initialize\\\":{\\\"name\\\":\\\"initialize\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"service_compensation_snapshots\\\",\\\"previousQualifiedNames\\\":[\\\"@happyvertical/smrt-projects:ServiceCompensationSnapshot\\\"],\\\"conflictColumns\\\":[\\\"time_entry_id\\\"],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ServiceCompensationSnapshot\\\",\\\"collectionExportName\\\":\\\"ServiceCompensationSnapshotCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"timeEntryId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"service_compensation_snapshots\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"service_compensation_snapshots\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"time_entry_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"amount\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"currency\\\\\\\" TEXT,\\\\n \\\\\\\"terms_version\\\\\\\" TEXT,\\\\n \\\\\\\"rate_snapshot\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"time_entry_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"amount\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"currency\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"terms_version\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rate_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"service_compensation_snapshots_time_entry_id_idx\\\",\\\"columns\\\":[\\\"time_entry_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"service_compensation_snapshots_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"service_compensation_snapshots_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"cd8670e5\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets\\\"},\\\"@happyvertical/smrt-timesheets:ServiceChargeSnapshotCollection\\\":{\\\"name\\\":\\\"servicechargesnapshotcollection\\\",\\\"className\\\":\\\"ServiceChargeSnapshotCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:ServiceChargeSnapshotCollection\\\",\\\"collection\\\":\\\"servicechargesnapshots\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-snapshots.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"service_charge_snapshots\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ServiceChargeSnapshot\\\",\\\"exportName\\\":\\\"ServiceChargeSnapshotCollection\\\",\\\"collectionExportName\\\":\\\"ServiceChargeSnapshotCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"service_charge_snapshots\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"service_charge_snapshots\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"time_entry_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"amount\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"currency\\\\\\\" TEXT,\\\\n \\\\\\\"pricing_version\\\\\\\" TEXT,\\\\n \\\\\\\"strategy\\\\\\\" TEXT,\\\\n \\\\\\\"rate_snapshot\\\\\\\" TEXT,\\\\n \\\\\\\"source_charge_ref\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"time_entry_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"amount\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"currency\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"pricing_version\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"strategy\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rate_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"source_charge_ref\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"service_charge_snapshots_time_entry_id_idx\\\",\\\"columns\\\":[\\\"time_entry_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"service_charge_snapshots_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"service_charge_snapshots_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"1393a1e2\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets\\\"},\\\"@happyvertical/smrt-timesheets:ServiceCompensationSnapshotCollection\\\":{\\\"name\\\":\\\"servicecompensationsnapshotcollection\\\",\\\"className\\\":\\\"ServiceCompensationSnapshotCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:ServiceCompensationSnapshotCollection\\\",\\\"collection\\\":\\\"servicecompensationsnapshots\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-snapshots.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"service_compensation_snapshots\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ServiceCompensationSnapshot\\\",\\\"exportName\\\":\\\"ServiceCompensationSnapshotCollection\\\",\\\"collectionExportName\\\":\\\"ServiceCompensationSnapshotCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"service_compensation_snapshots\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"service_compensation_snapshots\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"time_entry_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"amount\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"currency\\\\\\\" TEXT,\\\\n \\\\\\\"terms_version\\\\\\\" TEXT,\\\\n \\\\\\\"rate_snapshot\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"time_entry_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"amount\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"currency\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"terms_version\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rate_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"service_compensation_snapshots_time_entry_id_idx\\\",\\\"columns\\\":[\\\"time_entry_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"service_compensation_snapshots_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"service_compensation_snapshots_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"cd8670e5\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets\\\"},\\\"@happyvertical/smrt-timesheets:ServiceTimeEntry\\\":{\\\"name\\\":\\\"servicetimeentry\\\",\\\"className\\\":\\\"ServiceTimeEntry\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:ServiceTimeEntry\\\",\\\"collection\\\":\\\"servicetimeentries\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-time-entry.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"workRefType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"workRefId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"participantKind\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{},\\\"enum\\\":[\\\"human\\\",\\\"agent\\\"]},\\\"participantProfileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"agentRef\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"source\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{},\\\"enum\\\":[\\\"timer\\\",\\\"manual\\\",\\\"import\\\",\\\"agent\\\"]},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"startedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"endedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"durationSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"evidence\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{},\\\"enum\\\":[\\\"draft\\\",\\\"submitted\\\",\\\"approved\\\",\\\"rejected\\\",\\\"corrected\\\"]},\\\"submittedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"submittedByProfileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"approvedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"approvedByProfileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"approvalPath\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"rejectedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"rejectedByProfileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"rejectionReason\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"correctionOfId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"ServiceTimeEntry\\\"},\\\"metadata\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}}},\\\"methods\\\":{\\\"getEvidence\\\":{\\\"name\\\":\\\"getEvidence\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"ServiceEvidence[]\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setEvidence\\\":{\\\"name\\\":\\\"setEvidence\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"ServiceEvidence[]\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Record<string, unknown>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setMetadata\\\":{\\\"name\\\":\\\"setMetadata\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"durationHoursExact\\\":{\\\"name\\\":\\\"durationHoursExact\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"string | null\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"durationHours\\\":{\\\"name\\\":\\\"durationHours\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"number\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"requireDurationSeconds\\\":{\\\"name\\\":\\\"requireDurationSeconds\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"number\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"initialize\\\":{\\\"name\\\":\\\"initialize\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"service_time_entries\\\",\\\"previousQualifiedNames\\\":[\\\"@happyvertical/smrt-projects:ServiceTimeEntry\\\"],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ServiceTimeEntry\\\",\\\"collectionExportName\\\":\\\"ServiceTimeEntryCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"service_time_entries\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"service_time_entries\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"work_ref_type\\\\\\\" TEXT,\\\\n \\\\\\\"work_ref_id\\\\\\\" TEXT,\\\\n \\\\\\\"participant_kind\\\\\\\" TEXT,\\\\n \\\\\\\"participant_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"agent_ref\\\\\\\" TEXT,\\\\n \\\\\\\"source\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"duration_seconds\\\\\\\" INTEGER,\\\\n \\\\\\\"evidence\\\\\\\" TEXT,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"submitted_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"submitted_by_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"approved_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"approved_by_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"approval_path\\\\\\\" TEXT,\\\\n \\\\\\\"rejected_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"rejected_by_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"rejection_reason\\\\\\\" TEXT,\\\\n \\\\\\\"correction_of_id\\\\\\\" UUID,\\\\n \\\\\\\"metadata\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"work_ref_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"work_ref_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"participant_kind\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"participant_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"agent_ref\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"source\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"duration_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"evidence\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"submitted_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"submitted_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"approved_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"approved_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"approval_path\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rejected_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rejected_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rejection_reason\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"correction_of_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"metadata\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"service_time_entries_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"service_time_entries_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"service_time_entries_participant_profile_id_idx\\\",\\\"columns\\\":[\\\"participant_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_submitted_by_profile_id_idx\\\",\\\"columns\\\":[\\\"submitted_by_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_approved_by_profile_id_idx\\\",\\\"columns\\\":[\\\"approved_by_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_rejected_by_profile_id_idx\\\",\\\"columns\\\":[\\\"rejected_by_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_correction_of_id_idx\\\",\\\"columns\\\":[\\\"correction_of_id\\\"]}],\\\"version\\\":\\\"05578ed7\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets\\\"},\\\"@happyvertical/smrt-timesheets:ServiceTimeEntryCollection\\\":{\\\"name\\\":\\\"servicetimeentrycollection\\\",\\\"className\\\":\\\"ServiceTimeEntryCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:ServiceTimeEntryCollection\\\",\\\"collection\\\":\\\"servicetimeentries\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-time-entry.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"forWork\\\":{\\\"name\\\":\\\"forWork\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"workRefType\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"workRefId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ServiceTimeEntry[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"pendingApproval\\\":{\\\"name\\\":\\\"pendingApproval\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ServiceTimeEntry[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"service_time_entries\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ServiceTimeEntry\\\",\\\"exportName\\\":\\\"ServiceTimeEntryCollection\\\",\\\"collectionExportName\\\":\\\"ServiceTimeEntryCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"service_time_entries\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"service_time_entries\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"work_ref_type\\\\\\\" TEXT,\\\\n \\\\\\\"work_ref_id\\\\\\\" TEXT,\\\\n \\\\\\\"participant_kind\\\\\\\" TEXT,\\\\n \\\\\\\"participant_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"agent_ref\\\\\\\" TEXT,\\\\n \\\\\\\"source\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"duration_seconds\\\\\\\" INTEGER,\\\\n \\\\\\\"evidence\\\\\\\" TEXT,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"submitted_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"submitted_by_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"approved_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"approved_by_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"approval_path\\\\\\\" TEXT,\\\\n \\\\\\\"rejected_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"rejected_by_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"rejection_reason\\\\\\\" TEXT,\\\\n \\\\\\\"correction_of_id\\\\\\\" UUID,\\\\n \\\\\\\"metadata\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"work_ref_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"work_ref_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"participant_kind\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"participant_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"agent_ref\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"source\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"duration_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"evidence\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"submitted_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"submitted_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"approved_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"approved_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"approval_path\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rejected_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rejected_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rejection_reason\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"correction_of_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"service_time_entries\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"metadata\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"service_time_entries_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"service_time_entries_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"service_time_entries_participant_profile_id_idx\\\",\\\"columns\\\":[\\\"participant_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_submitted_by_profile_id_idx\\\",\\\"columns\\\":[\\\"submitted_by_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_approved_by_profile_id_idx\\\",\\\"columns\\\":[\\\"approved_by_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_rejected_by_profile_id_idx\\\",\\\"columns\\\":[\\\"rejected_by_profile_id\\\"]},{\\\"name\\\":\\\"service_time_entries_correction_of_id_idx\\\",\\\"columns\\\":[\\\"correction_of_id\\\"]}],\\\"version\\\":\\\"05578ed7\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets\\\"},\\\"@happyvertical/smrt-timesheets:PeriodTimecard\\\":{\\\"name\\\":\\\"periodtimecard\\\",\\\"className\\\":\\\"PeriodTimecard\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:PeriodTimecard\\\",\\\"collection\\\":\\\"periodtimecards\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"profileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"RESTRICT\\\"}},\\\"startsAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"endsAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"timezone\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"rulesVersion\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"rulesSnapshot\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"sourceSnapshot\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"regularSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"overtimeSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"totalSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{},\\\"enum\\\":[\\\"open\\\",\\\"confirmed\\\"]},\\\"confirmedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"confirmedByProfileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"nullable\\\":true,\\\"onDelete\\\":\\\"RESTRICT\\\"}}},\\\"methods\\\":{\\\"getSources\\\":{\\\"name\\\":\\\"getSources\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"TimecardSource[]\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRules\\\":{\\\"name\\\":\\\"getRules\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Record<string, unknown>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"period_timecards\\\",\\\"sensitive\\\":true,\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"PeriodTimecard\\\",\\\"collectionExportName\\\":\\\"PeriodTimecardCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"regularSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"},{\\\"field\\\":\\\"overtimeSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"},{\\\"field\\\":\\\"totalSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"period_timecards\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"period_timecards\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"starts_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ends_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"timezone\\\\\\\" TEXT,\\\\n \\\\\\\"rules_version\\\\\\\" TEXT,\\\\n \\\\\\\"rules_snapshot\\\\\\\" TEXT,\\\\n \\\\\\\"source_snapshot\\\\\\\" TEXT,\\\\n \\\\\\\"regular_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"overtime_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"total_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"confirmed_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"confirmed_by_profile_id\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"starts_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ends_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"timezone\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rules_version\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rules_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"source_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"regular_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"overtime_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"total_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"confirmed_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"confirmed_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"period_timecards_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"period_timecards_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"period_timecards_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"period_timecards_confirmed_by_profile_id_idx\\\",\\\"columns\\\":[\\\"confirmed_by_profile_id\\\"]}],\\\"version\\\":\\\"8153dc2a\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/rollup\\\"},\\\"@happyvertical/smrt-timesheets:TimecardAdjustment\\\":{\\\"name\\\":\\\"timecardadjustment\\\",\\\"className\\\":\\\"TimecardAdjustment\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:TimecardAdjustment\\\",\\\"collection\\\":\\\"timecardadjustments\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"timecardId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"PeriodTimecard\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"RESTRICT\\\"}},\\\"profileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"RESTRICT\\\"}},\\\"actorProfileId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"RESTRICT\\\"}},\\\"operationId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"regularSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"overtimeSeconds\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0},\\\"reason\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"timecard_adjustments\\\",\\\"sensitive\\\":true,\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"TimecardAdjustment\\\",\\\"collectionExportName\\\":\\\"TimecardAdjustmentCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"regularSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"},{\\\"field\\\":\\\"overtimeSeconds\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"timecard_adjustments\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"timecard_adjustments\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"timecard_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"actor_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"operation_id\\\\\\\" TEXT,\\\\n \\\\\\\"regular_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"overtime_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"reason\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"timecard_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"period_timecards\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"actor_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"operation_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"regular_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"overtime_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"reason\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"timecard_adjustments_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"timecard_adjustments_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"timecard_adjustments_timecard_id_idx\\\",\\\"columns\\\":[\\\"timecard_id\\\"]},{\\\"name\\\":\\\"timecard_adjustments_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"timecard_adjustments_actor_profile_id_idx\\\",\\\"columns\\\":[\\\"actor_profile_id\\\"]}],\\\"version\\\":\\\"582afe16\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/rollup\\\"},\\\"@happyvertical/smrt-timesheets:PeriodTimecardCollection\\\":{\\\"name\\\":\\\"periodtimecardcollection\\\",\\\"className\\\":\\\"PeriodTimecardCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:PeriodTimecardCollection\\\",\\\"collection\\\":\\\"periodtimecards\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"period_timecards\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"PeriodTimecard\\\",\\\"exportName\\\":\\\"PeriodTimecardCollection\\\",\\\"collectionExportName\\\":\\\"PeriodTimecardCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"period_timecards\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"period_timecards\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"starts_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ends_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"timezone\\\\\\\" TEXT,\\\\n \\\\\\\"rules_version\\\\\\\" TEXT,\\\\n \\\\\\\"rules_snapshot\\\\\\\" TEXT,\\\\n \\\\\\\"source_snapshot\\\\\\\" TEXT,\\\\n \\\\\\\"regular_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"overtime_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"total_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"confirmed_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"confirmed_by_profile_id\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"starts_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ends_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"timezone\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rules_version\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"rules_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"source_snapshot\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"regular_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"overtime_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"total_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"confirmed_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"confirmed_by_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"period_timecards_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"period_timecards_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"period_timecards_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"period_timecards_confirmed_by_profile_id_idx\\\",\\\"columns\\\":[\\\"confirmed_by_profile_id\\\"]}],\\\"version\\\":\\\"8153dc2a\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/rollup\\\"},\\\"@happyvertical/smrt-timesheets:TimecardAdjustmentCollection\\\":{\\\"name\\\":\\\"timecardadjustmentcollection\\\",\\\"className\\\":\\\"TimecardAdjustmentCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-timesheets:TimecardAdjustmentCollection\\\",\\\"collection\\\":\\\"timecardadjustments\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-timesheets\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"timecard_adjustments\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"TimecardAdjustment\\\",\\\"exportName\\\":\\\"TimecardAdjustmentCollection\\\",\\\"collectionExportName\\\":\\\"TimecardAdjustmentCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"timecard_adjustments\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"timecard_adjustments\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"timecard_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"actor_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"operation_id\\\\\\\" TEXT,\\\\n \\\\\\\"regular_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"overtime_seconds\\\\\\\" INTEGER NOT NULL DEFAULT 0,\\\\n \\\\\\\"reason\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"timecard_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"period_timecards\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"actor_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"operation_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"regular_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"overtime_seconds\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0},\\\"reason\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"timecard_adjustments_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"timecard_adjustments_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"timecard_adjustments_timecard_id_idx\\\",\\\"columns\\\":[\\\"timecard_id\\\"]},{\\\"name\\\":\\\"timecard_adjustments_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"timecard_adjustments_actor_profile_id_idx\\\",\\\"columns\\\":[\\\"actor_profile_id\\\"]}],\\\"version\\\":\\\"582afe16\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-timesheets/rollup\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"stampsConstructors\\\":true}\"));\n","/**\n * Parse a JSON value stored as text, returning `fallback` on malformed input.\n * Stored JSON may predate a schema change, so reads never throw.\n */\nexport function parseTimesheetJson<T>(value: string, fallback: T): T {\n try {\n return JSON.parse(value) as T;\n } catch {\n return fallback;\n }\n}\n","import {\n crossPackageRef,\n field,\n foreignKey,\n SmrtCollection,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n SERVICE_TIME_ENTRY_STATUS_TRANSITIONS,\n type ServiceEvidence,\n type ServiceParticipantKind,\n type ServiceTimeEntrySource,\n type ServiceTimeEntryStatus,\n} from '../types.js';\nimport { parseTimesheetJson } from './json.js';\n\n/**\n * Fields that may not change once an entry is approved (or corrected). A\n * subtype that adds its own work context extends the list through\n * {@link ServiceTimeEntry.frozenFieldNames}.\n */\nexport const SERVICE_TIME_ENTRY_FROZEN_FIELDS = [\n 'tenantId',\n 'workRefType',\n 'workRefId',\n 'participantKind',\n 'participantProfileId',\n 'agentRef',\n 'source',\n 'description',\n 'startedAt',\n 'endedAt',\n 'durationSeconds',\n 'evidence',\n 'correctionOfId',\n] as const;\n\nfunction toColumn(key: string): string {\n return key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n}\n\nfunction frozenView(\n source: Record<string, unknown>,\n fields: readonly string[],\n): string {\n const result: Record<string, unknown> = {};\n for (const key of fields) {\n let value = source[key] ?? null;\n if ((key === 'startedAt' || key === 'endedAt') && value) {\n const date = value instanceof Date ? value : new Date(String(value));\n value = Number.isNaN(date.getTime()) ? String(value) : date.toISOString();\n }\n if (key === 'durationSeconds' && value !== null) value = Number(value);\n result[key] = value === '' ? null : value;\n }\n return JSON.stringify(result);\n}\n\nconst loadedStatus = new WeakMap<ServiceTimeEntry, ServiceTimeEntryStatus>();\n\n/**\n * A person or agent worked this long on this thing, and someone approved it.\n *\n * The base entry carries a generic work reference (`workRefType` qualified\n * class name + `workRefId`) and no domain-specific foreign key; a domain adds\n * its own context by subclassing over the same `service_time_entries` table\n * (smrt-support's subtype adds `caseId` / `specialistId`). Entries carry no\n * rate: charge and compensation live on the immutable snapshot models.\n *\n * Status moves `draft → submitted → approved | rejected`; an approved entry\n * never changes, and a correction is a new row whose `correctionOfId` points\n * at the entry it corrects, which flips to `corrected`.\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableName: 'service_time_entries',\n // Moved from smrt-projects in #3288; stored references keep resolving.\n previousQualifiedNames: ['@happyvertical/smrt-projects:ServiceTimeEntry'],\n api: { include: ['list', 'get'] },\n cli: { include: ['list', 'get'] },\n mcp: { include: ['list', 'get'] },\n})\nexport class ServiceTimeEntry extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-timesheets\";\n @tenantId({ nullable: true }) tenantId: string | null = null;\n @field({ type: 'text', nullable: true }) workRefType: string | null = null;\n @field({ type: 'text', nullable: true }) workRefId: string | null = null;\n @field({ type: 'text' }) participantKind: ServiceParticipantKind = 'human';\n @crossPackageRef('@happyvertical/smrt-profiles:Profile', { nullable: true })\n participantProfileId: string | null = null;\n @field({ type: 'text' }) agentRef: string = '';\n @field({ type: 'text' }) source: ServiceTimeEntrySource = 'manual';\n @field({ type: 'text' }) description: string = '';\n startedAt: Date | null = null;\n endedAt: Date | null = null;\n /** Integer seconds, or null for an explicit decimal-hours-only source. */\n @field({ type: 'integer', nullable: true })\n durationSeconds: number | null = 0;\n @field({ type: 'text' }) evidence: string = '[]';\n @field({ type: 'text' }) status: ServiceTimeEntryStatus = 'draft';\n submittedAt: Date | null = null;\n @crossPackageRef('@happyvertical/smrt-profiles:Profile', { nullable: true })\n submittedByProfileId: string | null = null;\n approvedAt: Date | null = null;\n @crossPackageRef('@happyvertical/smrt-profiles:Profile', { nullable: true })\n approvedByProfileId: string | null = null;\n @field({ type: 'text' }) approvalPath: string = '';\n rejectedAt: Date | null = null;\n @crossPackageRef('@happyvertical/smrt-profiles:Profile', { nullable: true })\n rejectedByProfileId: string | null = null;\n @field({ type: 'text' }) rejectionReason: string = '';\n @foreignKey('ServiceTimeEntry') correctionOfId: string | null = null;\n @field({ type: 'text' }) metadata: string = '{}';\n\n getEvidence(): ServiceEvidence[] {\n return parseTimesheetJson(this.evidence, []);\n }\n setEvidence(value: ServiceEvidence[]): void {\n this.evidence = JSON.stringify(value ?? []);\n }\n getMetadata(): Record<string, unknown> {\n return parseTimesheetJson(this.metadata, {});\n }\n setMetadata(value: Record<string, unknown>): void {\n this.metadata = JSON.stringify(value ?? {});\n }\n /** Original decimal-hours text, without binary floating-point conversion. */\n durationHoursExact(): string | null {\n const evidence = this.getEvidence();\n const quantities = (Array.isArray(evidence) ? evidence : []).filter(\n (item) => item?.kind === SERVICE_DURATION_HOURS_EVIDENCE,\n );\n if (quantities.length === 0) return null;\n if (quantities.length !== 1)\n throw new Error(\n 'Service time requires exactly one decimal-hours quantity.',\n );\n return validateDurationHours(quantities[0].hours);\n }\n\n /** Numeric convenience for display; use durationHoursExact() for exact terms. */\n durationHours(): number {\n if (this.durationSeconds !== null) return this.durationSeconds / 3600;\n const hours = this.durationHoursExact();\n if (hours === null)\n throw new Error('Service time has no supported duration quantity.');\n return Number(hours);\n }\n\n /** Guard for consumers whose policies require independently supplied seconds. */\n requireDurationSeconds(): number {\n if (this.durationSeconds === null)\n throw new Error(\n 'Decimal-hours-only service time has no measured durationSeconds; use durationHoursExact() with an hours-aware policy.',\n );\n return this.durationSeconds;\n }\n\n /**\n * Fields frozen once the entry is approved. Subtypes that add work context\n * (e.g. a support case) return `[...super.frozenFieldNames(), ...]`.\n */\n protected frozenFieldNames(): readonly string[] {\n return SERVICE_TIME_ENTRY_FROZEN_FIELDS;\n }\n\n override async initialize(): Promise<this> {\n await super.initialize();\n if (await this.isSaved()) loadedStatus.set(this, this.status);\n return this;\n }\n\n override async save(): Promise<this> {\n const hours = this.durationHoursExact();\n if (hours !== null) {\n if (\n this.durationSeconds !== null ||\n this.startedAt ||\n this.endedAt ||\n this.source === 'timer'\n )\n throw new Error(\n 'Decimal-hours-only service time cannot also supply seconds or timestamps.',\n );\n } else if (this.durationSeconds === null) {\n throw new Error(\n 'Null durationSeconds requires explicit decimal-hours evidence.',\n );\n }\n const prior = await this.readPrior();\n if (\n prior &&\n prior.status !== this.status &&\n !SERVICE_TIME_ENTRY_STATUS_TRANSITIONS[prior.status].includes(this.status)\n ) {\n throw new Error(\n `ServiceTimeEntry ${this.id}: illegal status transition '${prior.status}' → '${this.status}'.`,\n );\n }\n if (\n prior &&\n (prior.status === 'approved' || prior.status === 'corrected')\n ) {\n const current = frozenView(\n this as unknown as Record<string, unknown>,\n this.frozenFieldNames(),\n );\n if (current !== prior.frozen) {\n throw new Error(\n 'Approved ServiceTimeEntry evidence is immutable; create a correction instead.',\n );\n }\n }\n const result = (await super.save()) as this;\n loadedStatus.set(this, this.status);\n return result;\n }\n\n private async readPrior(): Promise<{\n status: ServiceTimeEntryStatus;\n frozen: string;\n } | null> {\n if (!this.id) return null;\n const fields = this.frozenFieldNames();\n try {\n const row = await this.db.get(this.tableName, { id: this.id });\n if (!row?.status) return null;\n const values: Record<string, unknown> = {};\n for (const key of fields) {\n values[key] = row[toColumn(key)];\n }\n return {\n status: row.status as ServiceTimeEntryStatus,\n frozen: frozenView(values, fields),\n };\n } catch {\n const status = loadedStatus.get(this);\n return status\n ? {\n status,\n frozen: frozenView(\n this as unknown as Record<string, unknown>,\n fields,\n ),\n }\n : null;\n }\n }\n}\n\n/** Collection over `service_time_entries`. */\nexport class ServiceTimeEntryCollection extends SmrtCollection<ServiceTimeEntry> {\n static readonly _itemClass = ServiceTimeEntry;\n async forWork(\n workRefType: string,\n workRefId: string,\n ): Promise<ServiceTimeEntry[]> {\n return this.list({\n where: { workRefType, workRefId },\n orderBy: 'created_at ASC',\n });\n }\n async pendingApproval(): Promise<ServiceTimeEntry[]> {\n return this.list({\n where: { status: 'submitted' },\n orderBy: 'submitted_at ASC',\n });\n }\n}\n\n/** Reserved evidence kind for a source quantity with no measured elapsed seconds. */\nexport const SERVICE_DURATION_HOURS_EVIDENCE =\n '@happyvertical/smrt-timesheets:duration-hours';\n\n/** Validate without normalizing the original accepted decimal text. */\nexport function validateDurationHours(value: unknown): string {\n if (\n typeof value !== 'string' ||\n !/^\\d+(?:\\.\\d+)?$/.test(value) ||\n !Number.isFinite(Number(value)) ||\n Number(value) <= 0 ||\n Number(value) >= Number.MAX_SAFE_INTEGER\n )\n throw new Error(\n 'Service time durationHours must be positive plain decimal text within the supported numeric range.',\n );\n return value;\n}\n"],"mappings":";;;;AAOA,eAAe,wBAAwB,KAAK,MAAM,wl2DAAo4kE,CAAC;;;ACHh7kE,SAAS,mBAAsB,OAAe,UAAgB;CACnE,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;ACaO,IAAM,mCAAmC;CAC9C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,SAAS,KAAqB;CACrC,OAAO,IAAI,QAAQ,WAAW,MAAM,IAAI,EAAE,YAAY,GAAG;AAC3D;AAEA,SAAS,WACP,QACA,QACQ;CACR,MAAM,SAAkC,CAAC;CACzC,KAAA,MAAW,OAAO,QAAQ;EACxB,IAAI,QAAQ,OAAO,QAAQ;EAC3B,KAAK,QAAQ,eAAe,QAAQ,cAAc,OAAO;GACvD,MAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,OAAO,KAAK,CAAC;GACnE,QAAQ,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO,KAAK,IAAI,KAAK,YAAY;EAC1E;EACA,IAAI,QAAQ,qBAAqB,UAAU,MAAM,QAAQ,OAAO,KAAK;EACrE,OAAO,OAAO,UAAU,KAAK,OAAO;CACtC;CACA,OAAO,KAAK,UAAU,MAAM;AAC9B;AAEA,IAAM,+BAAe,IAAI,QAAkD;AAwBpE,IAAM,mBAAN,cAA+B,WAAW;CACjB,WAA0B;CACf,cAA6B;CAC7B,YAA2B;CAC3C,kBAA0C;CAEnE,uBAAsC;CACb,WAAmB;CACnB,SAAiC;CACjC,cAAsB;CAC/C,YAAyB;CACzB,UAAuB;CAGvB,kBAAiC;CACR,WAAmB;CACnB,SAAiC;CAC1D,cAA2B;CAE3B,uBAAsC;CACtC,aAA0B;CAE1B,sBAAqC;CACZ,eAAuB;CAChD,aAA0B;CAE1B,sBAAqC;CACZ,kBAA0B;CACnB,iBAAgC;CACvC,WAAmB;CAE5C,cAAiC;EAC/B,OAAO,mBAAmB,KAAK,UAAU,CAAC,CAAC;CAC7C;CACA,YAAY,OAAgC;EAC1C,KAAK,WAAW,KAAK,UAAU,SAAS,CAAC,CAAC;CAC5C;CACA,cAAuC;EACrC,OAAO,mBAAmB,KAAK,UAAU,CAAC,CAAC;CAC7C;CACA,YAAY,OAAsC;EAChD,KAAK,WAAW,KAAK,UAAU,SAAS,CAAC,CAAC;CAC5C;;CAEA,qBAAoC;EAClC,MAAM,WAAW,KAAK,YAAY;EAClC,MAAM,cAAc,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,EAAA,CAAG,QAC1D,SAAS,MAAM,SAAS,+BAC3B;EACA,IAAI,WAAW,WAAW,GAAG,OAAO;EACpC,IAAI,WAAW,WAAW,GACxB,MAAM,IAAI,MACR,2DACF;EACF,OAAO,sBAAsB,WAAW,EAAC,CAAE,KAAK;CAClD;;CAGA,gBAAwB;EACtB,IAAI,KAAK,oBAAoB,MAAM,OAAO,KAAK,kBAAkB;EACjE,MAAM,QAAQ,KAAK,mBAAmB;EACtC,IAAI,UAAU,MACZ,MAAM,IAAI,MAAM,kDAAkD;EACpE,OAAO,OAAO,KAAK;CACrB;;CAGA,yBAAiC;EAC/B,IAAI,KAAK,oBAAoB,MAC3B,MAAM,IAAI,MACR,uHACF;EACF,OAAO,KAAK;CACd;;;;;CAMU,mBAAsC;EAC9C,OAAO;CACT;CAEA,MAAe,aAA4B;EACzC,MAAM,MAAM,WAAW;EACvB,IAAI,MAAM,KAAK,QAAQ,GAAG,aAAa,IAAI,MAAM,KAAK,MAAM;EAC5D,OAAO;CACT;CAEA,MAAe,OAAsB;EAEnC,IADc,KAAK,mBACf,MAAU;OAEV,KAAK,oBAAoB,QACzB,KAAK,aACL,KAAK,WACL,KAAK,WAAW,SAEhB,MAAM,IAAI,MACR,2EACF;EAAA,OACJ,IAAW,KAAK,oBAAoB,MAClC,MAAM,IAAI,MACR,gEACF;EAEF,MAAM,QAAQ,MAAM,KAAK,UAAU;EACnC,IACE,SACA,MAAM,WAAW,KAAK,UACtB,CAAC,sCAAsC,MAAM,OAAM,CAAE,SAAS,KAAK,MAAM,GAEzE,MAAM,IAAI,MACR,oBAAoB,KAAK,GAAE,+BAAgC,MAAM,OAAM,YAAQ,KAAK,OAAM,GAC5F;EAEF,IACE,UACC,MAAM,WAAW,cAAc,MAAM,WAAW;OAEjC,WACd,MACA,KAAK,iBAAiB,CAEpB,MAAY,MAAM,QACpB,MAAM,IAAI,MACR,+EACF;EAAA;EAGJ,MAAM,SAAU,MAAM,MAAM,KAAK;EACjC,aAAa,IAAI,MAAM,KAAK,MAAM;EAClC,OAAO;CACT;CAEA,MAAc,YAGJ;EACR,IAAI,CAAC,KAAK,IAAI,OAAO;EACrB,MAAM,SAAS,KAAK,iBAAiB;EACrC,IAAI;GACF,MAAM,MAAM,MAAM,KAAK,GAAG,IAAI,KAAK,WAAW,EAAE,IAAI,KAAK,GAAG,CAAC;GAC7D,IAAI,CAAC,KAAK,QAAQ,OAAO;GACzB,MAAM,SAAkC,CAAC;GACzC,KAAA,MAAW,OAAO,QAChB,OAAO,OAAO,IAAI,SAAS,GAAG;GAEhC,OAAO;IACL,QAAQ,IAAI;IACZ,QAAQ,WAAW,QAAQ,MAAM;GACnC;EACF,QAAQ;GACN,MAAM,SAAS,aAAa,IAAI,IAAI;GACpC,OAAO,SACH;IACE;IACA,QAAQ,WACN,MACA,MACF;GACF,IACA;EACN;CACF;AACF;AArKmD,cAAtC,kBAA6C,mBAAkB,gCAAA;AAC5C,gBAAA,CAA7B,SAAS,EAAE,UAAU,KAAK,CAAC,CAAA,GADjB,iBACmB,WAAA,YAAA,CAAA;AACW,gBAAA,CAAxC,MAAM;CAAE,MAAM;CAAQ,UAAU;AAAK,CAAC,CAAA,GAF5B,iBAE8B,WAAA,eAAA,CAAA;AACA,gBAAA,CAAxC,MAAM;CAAE,MAAM;CAAQ,UAAU;AAAK,CAAC,CAAA,GAH5B,iBAG8B,WAAA,aAAA,CAAA;AAChB,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GAJZ,iBAIc,WAAA,mBAAA,CAAA;AAEzB,gBAAA,CADC,gBAAgB,wCAAwC,EAAE,UAAU,KAAK,CAAC,CAAA,GALhE,iBAMX,WAAA,wBAAA,CAAA;AACyB,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GAPZ,iBAOc,WAAA,YAAA,CAAA;AACA,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GARZ,iBAQc,WAAA,UAAA,CAAA;AACA,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GATZ,iBASc,WAAA,eAAA,CAAA;AAKzB,gBAAA,CADC,MAAM;CAAE,MAAM;CAAW,UAAU;AAAK,CAAC,CAAA,GAb/B,iBAcX,WAAA,mBAAA,CAAA;AACyB,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GAfZ,iBAec,WAAA,YAAA,CAAA;AACA,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GAhBZ,iBAgBc,WAAA,UAAA,CAAA;AAGzB,gBAAA,CADC,gBAAgB,wCAAwC,EAAE,UAAU,KAAK,CAAC,CAAA,GAlBhE,iBAmBX,WAAA,wBAAA,CAAA;AAGA,gBAAA,CADC,gBAAgB,wCAAwC,EAAE,UAAU,KAAK,CAAC,CAAA,GArBhE,iBAsBX,WAAA,uBAAA,CAAA;AACyB,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GAvBZ,iBAuBc,WAAA,gBAAA,CAAA;AAGzB,gBAAA,CADC,gBAAgB,wCAAwC,EAAE,UAAU,KAAK,CAAC,CAAA,GAzBhE,iBA0BX,WAAA,uBAAA,CAAA;AACyB,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GA3BZ,iBA2Bc,WAAA,mBAAA,CAAA;AACO,gBAAA,CAA/B,WAAW,kBAAkB,CAAA,GA5BnB,iBA4BqB,WAAA,kBAAA,CAAA;AACP,gBAAA,CAAxB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAA,GA7BZ,iBA6Bc,WAAA,YAAA,CAAA;AA7Bd,mBAAN,gBAAA,CATN,aAAa,EAAE,MAAM,WAAW,CAAC,GACjC,KAAK;CACJ,WAAW;CAEX,wBAAwB,CAAC,+CAA+C;CACxE,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAE;CAChC,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAE;CAChC,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAE;AAClC,CAAC,CAAA,GACY,gBAAA;AAwKN,IAAM,6BAAN,cAAyC,eAAiC;CAC/E,OAAgB,aAAa;CAC7B,MAAM,QACJ,aACA,WAC6B;EAC7B,OAAO,KAAK,KAAK;GACf,OAAO;IAAE;IAAa;GAAU;GAChC,SAAS;EACX,CAAC;CACH;CACA,MAAM,kBAA+C;EACnD,OAAO,KAAK,KAAK;GACf,OAAO,EAAE,QAAQ,YAAY;GAC7B,SAAS;EACX,CAAC;CACH;AACF;AAGO,IAAM,kCACX;AAGK,SAAS,sBAAsB,OAAwB;CAC5D,IACE,OAAO,UAAU,YACjB,CAAC,kBAAkB,KAAK,KAAK,KAC7B,CAAC,OAAO,SAAS,OAAO,KAAK,CAAC,KAC9B,OAAO,KAAK,KAAK,KACjB,OAAO,KAAK,KAAK,OAAO,kBAExB,MAAM,IAAI,MACR,oGACF;CACF,OAAO;AACT"}
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { a as validateDurationHours, i as ServiceTimeEntryCollection, n as SERVICE_TIME_ENTRY_FROZEN_FIELDS, r as ServiceTimeEntry, t as SERVICE_DURATION_HOURS_EVIDENCE } from "./chunks/service-time-entry-BAkx99ks.js";
2
- import { a as AttendanceReplay, i as AttendancePunchCollection, n as AttendanceBreakCollection, o as AttendanceReplayCollection, r as AttendancePunch, t as AttendanceBreak } from "./chunks/models-DNbDLJCb.js";
1
+ import { a as validateDurationHours, i as ServiceTimeEntryCollection, n as SERVICE_TIME_ENTRY_FROZEN_FIELDS, r as ServiceTimeEntry, t as SERVICE_DURATION_HOURS_EVIDENCE } from "./chunks/service-time-entry-NSayW3DB.js";
2
+ import { a as AttendanceReplay, i as AttendancePunchCollection, n as AttendanceBreakCollection, o as AttendanceReplayCollection, r as AttendancePunch, t as AttendanceBreak } from "./chunks/models-C8pv3ICs.js";
3
3
  import { SERVICE_TIME_ENTRY_STATUS_TRANSITIONS } from "./types.js";
4
4
  import { AttendanceConflict, AttendanceService } from "./attendance.js";
5
- import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-D18ToLCo.js";
5
+ import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-BvUuTKOe.js";
6
6
  import { TIMESHEETS_MODULE_META, TIMESHEETS_UI_SLOTS } from "./ui.js";
7
7
  import { SmrtCollection, SmrtObject, ValidationError, field, foreignKey, smrt } from "@happyvertical/smrt-core";
8
8
  import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-timesheets",
5
- "packageVersion": "0.55.0",
5
+ "packageVersion": "0.55.2",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-timesheets:AttendancePunch": {
8
8
  "name": "attendancepunch",
@@ -1782,7 +1782,11 @@
1782
1782
  "participantKind": {
1783
1783
  "type": "text",
1784
1784
  "required": false,
1785
- "_meta": {}
1785
+ "_meta": {},
1786
+ "enum": [
1787
+ "human",
1788
+ "agent"
1789
+ ]
1786
1790
  },
1787
1791
  "participantProfileId": {
1788
1792
  "type": "crossPackageRef",
@@ -1800,7 +1804,13 @@
1800
1804
  "source": {
1801
1805
  "type": "text",
1802
1806
  "required": false,
1803
- "_meta": {}
1807
+ "_meta": {},
1808
+ "enum": [
1809
+ "timer",
1810
+ "manual",
1811
+ "import",
1812
+ "agent"
1813
+ ]
1804
1814
  },
1805
1815
  "description": {
1806
1816
  "type": "text",
@@ -1830,7 +1840,14 @@
1830
1840
  "status": {
1831
1841
  "type": "text",
1832
1842
  "required": false,
1833
- "_meta": {}
1843
+ "_meta": {},
1844
+ "enum": [
1845
+ "draft",
1846
+ "submitted",
1847
+ "approved",
1848
+ "rejected",
1849
+ "corrected"
1850
+ ]
1834
1851
  },
1835
1852
  "submittedAt": {
1836
1853
  "type": "datetime",
@@ -2551,7 +2568,11 @@
2551
2568
  "status": {
2552
2569
  "type": "text",
2553
2570
  "required": false,
2554
- "_meta": {}
2571
+ "_meta": {},
2572
+ "enum": [
2573
+ "open",
2574
+ "confirmed"
2575
+ ]
2555
2576
  },
2556
2577
  "confirmedAt": {
2557
2578
  "type": "datetime",
package/dist/rollup.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-D18ToLCo.js";
1
+ import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-BvUuTKOe.js";
2
2
  export { PeriodRollupService, PeriodTimecard, PeriodTimecardCollection, TimecardAdjustment, TimecardAdjustmentCollection };
@@ -3,13 +3,13 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-timesheets",
6
- "packageVersion": "0.55.0",
6
+ "packageVersion": "0.55.2",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "a1db2927423cf41f9d57864a27b4fa04a318a4fae740b22c7aad0746ce3f80c5",
11
- "packageJson": "77c0866af008e6a558aca88a4544737677eae52f67f0a84a5728d1abd7621c14",
12
- "agents": "21421ad5f02335e4c994227122c13b881d10e9f9d55ae09c3ac8ffa4bc2a7e09",
10
+ "manifest": "43adfee44ef490fac35f3c4a8da0fbd9c31ac266dcd005162226dd784711f8ae",
11
+ "packageJson": "fb01e196720f92c69288a8a3f9e7c73e13547fedc9732703c4ce77849a2fc136",
12
+ "agents": "46a4e8437424b494645e90ce4a4869be04956c5da6a42f89697cbd3ab2199a7e",
13
13
  "moduleDoc:agents/period-rollup.md": "5fb741659d81dbef2e4850c10c2d65f09e3f5a83e8a88e2e0f19585f25158a6a"
14
14
  },
15
15
  "exports": [
@@ -1914,7 +1914,7 @@
1914
1914
  "polymorphicAssociations": 0,
1915
1915
  "uuidColumns": 62
1916
1916
  },
1917
- "agentDoc": "# smrt-timesheets\n\nShared time entries: who (a `smrt-profiles` Profile, or an agent) worked how\nlong on what (a generic work reference), whether it was approved, and the\nimmutable charge / compensation snapshots taken at approval. Moved out of\n`smrt-projects` / `smrt-support` in #3288 so shops, builders, and service\ndesks share one model instead of re-implementing it.\n\nThis package contains **layer 1 (entry)**, **layer 2 (attendance)**, and\n**layer 3 (period rollup)**.\n`src/attendance/` owns punches, breaks, atomic transitions and durable offline\nreceipts; `./attendance` is the public subpath. Period rollup belongs in this\npackage too, never projects or support. See the README attendance contract.\nAttendance services accept trusted session actors, serialize mutations per\nactor, and bind every write to one executor. The new tables use non-null unique\nopen slots, not nullable unique keys. A linked entry is draft evidence, and\nrollups must deduplicate `AttendancePunch.serviceTimeEntryId`.\n\n## Models\n\n| Model | Table | Notes |\n|---|---|---|\n| `ServiceTimeEntry` | `service_time_entries` | `workRefType` + `workRefId`, `participantKind` (`human` \\| `agent`), `participantProfileId` / `agentRef`, `source`, `startedAt` / `endedAt` / `durationSeconds`, status machine, `correctionOfId` |\n| `ServiceChargeSnapshot` | `service_charge_snapshots` | Client charge, integer minor units (#2401), one per entry |\n| `ServiceCompensationSnapshot` | `service_compensation_snapshots` | Provider earning, integer minor units, one per entry |\n\n`ServiceEvidenceService` records, submits, approves (writing both snapshots\nthrough a `ServiceCommercialResolver`), and corrects. `smrt-projects` supplies\n`SubscriptionServiceCommercialResolver` for #1925 pricing.\n\n## Invariants\n\n- **No domain foreign key on the base.** Work context is the generic\n `workRefType` (qualified class name) + `workRefId`. A domain adds its own\n context by subclassing over the same table — smrt-support's\n `ServiceTimeEntry` adds `caseId` / `specialistId` and extends\n `frozenFieldNames()` so they freeze on approval.\n- **Entries carry no rate.** Money lives only on the snapshots, `= 0`\n integer initializers (INTEGER columns). Never `= 0.0`. Snapshot `save()`\n rejects an `amount` that is not a safe integer (`VALIDATION_INVALID_VALUE`),\n so SQLite cannot silently store `19.99`; fix a fractional resolver at its\n source rather than rounding here.\n- **Approved evidence never changes.** `save()` enforces\n `SERVICE_TIME_ENTRY_STATUS_TRANSITIONS` and compares the frozen fields with\n the stored row. A correction is a new row (`correctionOfId`), the original\n flips to `corrected`. Snapshots are immutable after their first save.\n- **Old qualified names are aliases.** Each model declares its pre-#3288\n `@happyvertical/smrt-projects:*` name in `previousQualifiedNames` (#3338;\n `packages/core/agents/model-moves.md`). smrt-projects must never list these\n classes in its manifests again (`CONFIG_QUALIFIED_NAME_ALIAS_COLLISION`),\n and no subtype (smrt-support's, or a consumer's closing subclass) may\n redeclare an alias (two claimants). Known gap: a same-named subtype that\n replaces a moved class drops that class's alias, and the replaced class's\n own `@happyvertical/smrt-timesheets:*` name stops resolving too — guidance\n for apps with smrt-support must name `@happyvertical/smrt-support:ServiceTimeEntry`.\n Support's vitest environment keeps both classes registered, so verify this\n against built packages, not package tests. `projects/src/__tests__/legacy-qualified-identity.test.ts` pins\n the projects-only contract.\n- **Table names are a compatibility contract.** `service_time_entries` and the\n two snapshot tables hold existing production rows from smrt-projects /\n smrt-support; renaming any of them, or adding a discriminator, is a data\n migration.\n\n## One table family\n\nClasses may share a table only as one inheritance chain. Core resolves\nsame-named subclasses by constructor ancestry at runtime and qualified manifest\nancestry at build registration; the deepest subtype wins across N levels.\nSibling or unrelated types cannot share the table. `smrt-projects` re-exports\nthe base; `smrt-support` subclasses it directly.\n\nConsumers closing package routes should call\n`ObjectRegistry.registerOverride(qualifiedName, { api: false, mcp: false,\ncli: false, tenancy: { mode: 'required' } })` after importing the model and before\nconstructing transports. This tightens the existing registration without a new\nsubtype. See core's README for startup order, static route generation, and reset\nsemantics. `src/__tests__/consumer-closed-surface.test.ts` also covers existing\nmanifest subclass consumers. The snapshots' explicit `time_entry_id` conflict\nkey is not rewritten when a consumer requires tenancy; widening it remains a\nconsumer schema change.\n\nSubclasses restate their fields: package-isolated manifest scanning does not\nread dependency sources, so an unrestated subclass manifest has no columns.\n\n## Svelte UI\n\n`./svelte` exports `TimeEntryCard`, `TimeEntryList`, `TimeSummary`,\n`DurationDisplay`, and `TimeEntryApprovalQueue` (props-driven, plain view\nobjects, `smrt-ui` primitives, `smrtRawPrimitives: \"strict\"`). smrt-projects\nand smrt-support re-export them from their own `./svelte` subpaths.\nCard/list/summary message keys keep their `projects.*` namespace: tenant\nlanguage overrides are stored by key, and renaming would orphan them. New\nkeys use `timesheets.*`.\n\n## Validation\n\n```sh\npnpm --filter @happyvertical/smrt-timesheets test\npnpm --filter @happyvertical/smrt-timesheets test:postgres\npnpm --filter @happyvertical/smrt-timesheets typecheck\npnpm --filter @happyvertical/smrt-timesheets build\npnpm --filter @happyvertical/smrt-projects test\npnpm --filter @happyvertical/smrt-support test\n```\n\nSchema-affecting edits must keep `service-time-entry-compat.test.ts` (projects,\nsupport) and `service-time-entry-migration-plan.test.ts` (support) green: a\npre-move table must plan no DDL.\n\n## Period rollup\n\nLayer 3 lives under `src/rollup/` and the `./rollup` subpath. See\n[period-rollup.md](agents/period-rollup.md) for resolver, source clipping,\nconfirmation, attributed adjustments, isolation, and transaction contracts.\nTimecards and adjustments have closed generated surfaces and service-only\nmodel writes; never bypass the instance capability with generic persistence.\n",
1917
+ "agentDoc": "# smrt-timesheets\n\nShared time entries: who (a `smrt-profiles` Profile, or an agent) worked how\nlong on what (a generic work reference), whether it was approved, and the\nimmutable charge / compensation snapshots taken at approval. Moved out of\n`smrt-projects` / `smrt-support` in #3288 so shops, builders, and service\ndesks share one model instead of re-implementing it.\n\nThis package contains **layer 1 (entry)**, **layer 2 (attendance)**, and\n**layer 3 (period rollup)**.\n`src/attendance/` owns punches, breaks, atomic transitions and durable offline\nreceipts; `./attendance` is the public subpath. Period rollup belongs in this\npackage too, never projects or support. See the README attendance contract.\nAttendance services accept trusted session actors, serialize mutations per\nactor, and bind every write to one executor. The new tables use non-null unique\nopen slots, not nullable unique keys. A linked entry is draft evidence, and\nrollups must deduplicate `AttendancePunch.serviceTimeEntryId`.\n\n## Models\n\n| Model | Table | Notes |\n|---|---|---|\n| `ServiceTimeEntry` | `service_time_entries` | `workRefType` + `workRefId`, `participantKind` (`human` \\| `agent`), `participantProfileId` / `agentRef`, `source`, `startedAt` / `endedAt` / `durationSeconds`, status machine, `correctionOfId` |\n| `ServiceChargeSnapshot` | `service_charge_snapshots` | Client charge, integer minor units (#2401), one per entry |\n| `ServiceCompensationSnapshot` | `service_compensation_snapshots` | Provider earning, integer minor units, one per entry |\n\n`ServiceEvidenceService` records, submits, approves (writing both snapshots\nthrough a `ServiceCommercialResolver`), and corrects. `smrt-projects` supplies\n`SubscriptionServiceCommercialResolver` for #1925 pricing.\n\n## Invariants\n\n- **No domain foreign key on the base.** Work context is the generic\n `workRefType` (qualified class name) + `workRefId`. A domain adds its own\n context by subclassing over the same table — smrt-support's\n `ServiceTimeEntry` adds `caseId` / `specialistId` and extends\n `frozenFieldNames()` so they freeze on approval.\n- **Entries carry no rate.** Money lives only on the snapshots, `= 0`\n integer initializers (INTEGER columns). Never `= 0.0`. Snapshot `save()`\n rejects an `amount` that is not a safe integer (`VALIDATION_INVALID_VALUE`),\n so SQLite cannot silently store `19.99`; fix a fractional resolver at its\n source rather than rounding here.\n- **Approved evidence never changes.** `save()` enforces\n `SERVICE_TIME_ENTRY_STATUS_TRANSITIONS` and compares the frozen fields with\n the stored row. A correction is a new row (`correctionOfId`), the original\n flips to `corrected`. Snapshots are immutable after their first save.\n- **Old qualified names are aliases.** Each model declares its pre-#3288\n `@happyvertical/smrt-projects:*` name in `previousQualifiedNames` (#3338;\n `packages/core/agents/model-moves.md`). smrt-projects must never list these\n classes in its manifests again (`CONFIG_QUALIFIED_NAME_ALIAS_COLLISION`),\n and no subtype (smrt-support's, or a consumer's closing subclass) may\n redeclare an alias (two claimants). Known gap: a same-named subtype that\n replaces a moved class drops that class's alias, and the replaced class's\n own `@happyvertical/smrt-timesheets:*` name stops resolving too — guidance\n for apps with smrt-support must name `@happyvertical/smrt-support:ServiceTimeEntry`.\n Support's vitest environment keeps both classes registered, so verify this\n against built packages, not package tests. `projects/src/__tests__/legacy-qualified-identity.test.ts` pins\n the projects-only contract.\n- **Table names are a compatibility contract.** `service_time_entries` and the\n two snapshot tables hold existing production rows from smrt-projects /\n smrt-support; renaming any of them, or adding a discriminator, is a data\n migration.\n\n## One table family\n\nClasses may share a table only as one inheritance chain. Core resolves\nsame-named subclasses by constructor ancestry at runtime and qualified manifest\nancestry at build registration; the deepest subtype wins across N levels.\nSibling or unrelated types cannot share the table. `smrt-projects` re-exports\nthe base; `smrt-support` subclasses it directly.\n\nConsumers closing package routes should call\n`ObjectRegistry.registerOverride(qualifiedName, { api: false, mcp: false,\ncli: false, tenancy: { mode: 'required' } })` after importing the model and before\nconstructing transports. This tightens the existing registration without a new\nsubtype. See core's README for startup order, static route generation, and reset\nsemantics. `src/__tests__/consumer-closed-surface.test.ts` also covers existing\nmanifest subclass consumers. The snapshots' explicit `time_entry_id` conflict\nkey is not rewritten when a consumer requires tenancy; widening it remains a\nconsumer schema change.\n\nSubclasses restate their fields: package-isolated manifest scanning does not\nread dependency sources, so an unrestated subclass manifest has no columns.\n\n## Svelte UI\n\n`./svelte` exports `TimeEntryCard`, `TimeEntryList`, `TimeSummary`,\n`DurationDisplay`, and `TimeEntryApprovalQueue` (props-driven, plain view\nobjects, `smrt-ui` primitives, `smrtRawPrimitives: \"strict\"`). smrt-projects\nand smrt-support re-export them from their own `./svelte` subpaths.\nCard/list/summary message keys keep their `projects.*` namespace: tenant\nlanguage overrides are stored by key, and renaming would orphan them. New\nkeys use `timesheets.*`.\n\nDisplay components keep the legacy one-decimal hours format by default. A\nconsumer that retains more precise source evidence supplies `hoursFormatter`;\ncard/list/queue detail snippets carry domain evidence without widening the base\nview. ApprovalQueue's optional action snippet replaces its callback controls so\nthe host can own a native form, request identity, authorization and retry flow.\nDisplay currency codes are open ISO strings and amounts remain integer minor\nunits; never put private rates into a view that should not expose them.\n\n## Validation\n\n```sh\npnpm --filter @happyvertical/smrt-timesheets test\npnpm --filter @happyvertical/smrt-timesheets test:postgres\npnpm --filter @happyvertical/smrt-timesheets typecheck\npnpm --filter @happyvertical/smrt-timesheets build\npnpm --filter @happyvertical/smrt-projects test\npnpm --filter @happyvertical/smrt-support test\n```\n\nSchema-affecting edits must keep `service-time-entry-compat.test.ts` (projects,\nsupport) and `service-time-entry-migration-plan.test.ts` (support) green: a\npre-move table must plan no DDL.\n\n## Period rollup\n\nLayer 3 lives under `src/rollup/` and the `./rollup` subpath. See\n[period-rollup.md](agents/period-rollup.md) for resolver, source clipping,\nconfirmation, attributed adjustments, isolation, and transaction contracts.\nTimecards and adjustments have closed generated surfaces and service-only\nmodel writes; never bypass the instance capability with generic persistence.\n",
1918
1918
  "moduleDocs": [
1919
1919
  {
1920
1920
  "path": "agents/period-rollup.md",
@@ -13,12 +13,18 @@
13
13
  import { Button, StatusBadge } from '@happyvertical/smrt-ui';
14
14
  import { Input } from '@happyvertical/smrt-ui/forms';
15
15
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
16
+ import type { Snippet } from 'svelte';
16
17
  import { M } from '../i18n.js';
17
18
  import {
18
19
  humanizeTimeEntryStatus,
19
20
  type TimeEntryApprovalView,
20
21
  timeEntryStatusBadgeKey,
21
22
  } from '../types.js';
23
+ import {
24
+ currencyMinorUnitExponent,
25
+ formatHours,
26
+ type HoursFormatter,
27
+ } from './utils.js';
22
28
 
23
29
  const { t } = useI18n();
24
30
 
@@ -31,6 +37,12 @@ export interface TimeEntryApprovalQueueProps {
31
37
  onreject?: (id: string, reason: string) => void;
32
38
  /** Message displayed when the approval queue is empty. */
33
39
  emptyMessage?: string;
40
+ /** Formats decimal hours; defaults to the legacy one-decimal display. */
41
+ hoursFormatter?: HoursFormatter;
42
+ /** Renders caller-owned evidence for each entry. */
43
+ details?: Snippet<[TimeEntryApprovalView]>;
44
+ /** Replaces callback actions with caller-owned controls, including native forms. */
45
+ actions?: Snippet<[TimeEntryApprovalView]>;
34
46
  }
35
47
 
36
48
  const {
@@ -38,6 +50,9 @@ const {
38
50
  onapprove,
39
51
  onreject,
40
52
  emptyMessage,
53
+ hoursFormatter = formatHours,
54
+ details,
55
+ actions,
41
56
  }: TimeEntryApprovalQueueProps = $props();
42
57
 
43
58
  /** The entry currently collecting a rejection reason (one at a time). */
@@ -61,10 +76,6 @@ function confirmReject(id: string): void {
61
76
  cancelReject();
62
77
  }
63
78
 
64
- function formatHours(hours: number): string {
65
- return `${hours.toFixed(1)}h`;
66
- }
67
-
68
79
  /**
69
80
  * Render a minor-units charge for display.
70
81
  *
@@ -76,11 +87,7 @@ function formatHours(hours: number): string {
76
87
  * and the host app supplies the label.
77
88
  */
78
89
  function formatAmount(amount: number, currency = 'USD'): string {
79
- const digits =
80
- new Intl.NumberFormat(undefined, {
81
- style: 'currency',
82
- currency,
83
- }).resolvedOptions().maximumFractionDigits ?? 2;
90
+ const digits = currencyMinorUnitExponent(currency);
84
91
  return (amount / 10 ** digits).toFixed(digits);
85
92
  }
86
93
  </script>
@@ -102,7 +109,7 @@ function formatAmount(amount: number, currency = 'USD'): string {
102
109
  {/if}
103
110
  </span>
104
111
  <span class="time-approval-meta">
105
- <span class="time-approval-hours">{formatHours(entry.hours)}</span>
112
+ <span class="time-approval-hours">{hoursFormatter(entry.hours)}</span>
106
113
  <StatusBadge
107
114
  status={timeEntryStatusBadgeKey(entry.status)}
108
115
  label={humanizeTimeEntryStatus(entry.status)}
@@ -115,9 +122,12 @@ function formatAmount(amount: number, currency = 'USD'): string {
115
122
  {/if}
116
123
  </span>
117
124
  </div>
125
+ {@render details?.(entry)}
118
126
  {#if entry.status === 'submitted'}
119
127
  <div class="time-approval-actions">
120
- {#if rejectingId === entry.id}
128
+ {#if actions}
129
+ {@render actions(entry)}
130
+ {:else if rejectingId === entry.id}
121
131
  <Input
122
132
  bind:value={rejectReason}
123
133
  placeholder={t(M['timesheets.approval_queue.reason_placeholder'])}
@@ -1,4 +1,6 @@
1
+ import type { Snippet } from 'svelte';
1
2
  import { type TimeEntryApprovalView } from '../types.js';
3
+ import { type HoursFormatter } from './utils.js';
2
4
  export interface TimeEntryApprovalQueueProps {
3
5
  /** Array of time entries awaiting approval review. */
4
6
  entries: TimeEntryApprovalView[];
@@ -8,6 +10,12 @@ export interface TimeEntryApprovalQueueProps {
8
10
  onreject?: (id: string, reason: string) => void;
9
11
  /** Message displayed when the approval queue is empty. */
10
12
  emptyMessage?: string;
13
+ /** Formats decimal hours; defaults to the legacy one-decimal display. */
14
+ hoursFormatter?: HoursFormatter;
15
+ /** Renders caller-owned evidence for each entry. */
16
+ details?: Snippet<[TimeEntryApprovalView]>;
17
+ /** Replaces callback actions with caller-owned controls, including native forms. */
18
+ actions?: Snippet<[TimeEntryApprovalView]>;
11
19
  }
12
20
  declare const TimeEntryApprovalQueue: import("svelte").Component<TimeEntryApprovalQueueProps, {}, "">;
13
21
  type TimeEntryApprovalQueue = ReturnType<typeof TimeEntryApprovalQueue>;
@@ -1 +1 @@
1
- {"version":3,"file":"TimeEntryApprovalQueue.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/TimeEntryApprovalQueue.svelte.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAwHD,QAAA,MAAM,sBAAsB,iEAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"TimeEntryApprovalQueue.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/TimeEntryApprovalQueue.svelte.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC3C,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;CAC5C;AAwHD,QAAA,MAAM,sBAAsB,iEAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}