@happyvertical/smrt-timesheets 0.57.0 → 0.57.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 (43) hide show
  1. package/AGENTS.md +9 -3
  2. package/README.md +34 -5
  3. package/agents/period-rollup.md +13 -0
  4. package/dist/attendance/correction-service.d.ts +50 -9
  5. package/dist/attendance/correction-service.d.ts.map +1 -1
  6. package/dist/attendance/models.d.ts +6 -0
  7. package/dist/attendance/models.d.ts.map +1 -1
  8. package/dist/attendance/segments.d.ts.map +1 -1
  9. package/dist/attendance/service.d.ts +7 -1
  10. package/dist/attendance/service.d.ts.map +1 -1
  11. package/dist/attendance.js +2 -2
  12. package/dist/chunks/{attendance-Cmk-6dTV.js → attendance-CRhYpFij.js} +192 -38
  13. package/dist/chunks/attendance-CRhYpFij.js.map +1 -0
  14. package/dist/chunks/{attendance-CfIgcl26.js → attendance-NMy9n6Yz.js} +6 -6
  15. package/dist/chunks/attendance-NMy9n6Yz.js.map +1 -0
  16. package/dist/chunks/{models-BCrk0kZQ.js → models-CSNK96yj.js} +14 -3
  17. package/dist/chunks/models-CSNK96yj.js.map +1 -0
  18. package/dist/chunks/{rollup-CII9Hl1R.js → rollup-BfJ0Rx8A.js} +15 -7
  19. package/dist/chunks/rollup-BfJ0Rx8A.js.map +1 -0
  20. package/dist/chunks/service-time-entry-D-b03hMX.js +286 -0
  21. package/dist/chunks/service-time-entry-D-b03hMX.js.map +1 -0
  22. package/dist/chunks/{time-entry-actions-Lb8OYIS8.js → time-entry-actions-CFvxmB3J.js} +2 -2
  23. package/dist/chunks/{time-entry-actions-Lb8OYIS8.js.map → time-entry-actions-CFvxmB3J.js.map} +1 -1
  24. package/dist/index.js +5 -5
  25. package/dist/manifest.json +58 -5
  26. package/dist/rollup/attendance.d.ts +2 -2
  27. package/dist/rollup/attendance.d.ts.map +1 -1
  28. package/dist/rollup/calculation.d.ts +7 -1
  29. package/dist/rollup/calculation.d.ts.map +1 -1
  30. package/dist/rollup/service.d.ts.map +1 -1
  31. package/dist/rollup/types.d.ts +10 -0
  32. package/dist/rollup/types.d.ts.map +1 -1
  33. package/dist/rollup.d.ts +1 -1
  34. package/dist/rollup.d.ts.map +1 -1
  35. package/dist/rollup.js +1 -1
  36. package/dist/smrt-knowledge.json +25 -10
  37. package/package.json +7 -7
  38. package/dist/chunks/attendance-CfIgcl26.js.map +0 -1
  39. package/dist/chunks/attendance-Cmk-6dTV.js.map +0 -1
  40. package/dist/chunks/models-BCrk0kZQ.js.map +0 -1
  41. package/dist/chunks/rollup-CII9Hl1R.js.map +0 -1
  42. package/dist/chunks/service-time-entry-DzQsRZc_.js +0 -286
  43. package/dist/chunks/service-time-entry-DzQsRZc_.js.map +0 -1
@@ -1,286 +0,0 @@
1
- import { SERVICE_TIME_ENTRY_STATUS_TRANSITIONS } from "../types.js";
2
- import { ObjectRegistry, SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, method, smrt } from "@happyvertical/smrt-core";
3
- import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
4
- //#region src/__smrt-register__.ts
5
- ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-timesheets","packageVersion":"0.57.0","objects":{"@happyvertical/smrt-timesheets:AttendanceCorrection":{"name":"attendancecorrection","className":"AttendanceCorrection","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceCorrection","collection":"attendancecorrections","description":"One append-only change to closed attendance: who changed whose time, why, and the before/after values as JSON (null for an addition's before or a removal's after).","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/correction-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}}},"subjectProfileId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-profiles:Profile"},"actorProfileId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-profiles:Profile"},"kind":{"type":"text","required":false,"_meta":{}},"punchId":{"type":"foreignKey","required":false,"related":"AttendancePunch"},"targetId":{"type":"text","required":false},"beforeState":{"type":"text","required":false,"_meta":{}},"afterState":{"type":"text","required":false,"_meta":{}},"reason":{"type":"text","required":false,"_meta":{}},"acknowledgementRequired":{"type":"boolean","required":true,"default":false},"acknowledgedAt":{"type":"datetime","required":false},"acknowledgedByProfileId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-profiles:Profile","_meta":{"nullable":true}}},"methods":{"getBefore":{"name":"getBefore","async":false,"parameters":[],"returnType":"T | null","isStatic":false,"isPublic":true},"getAfter":{"name":"getAfter","async":false,"parameters":[],"returnType":"T | null","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":"attendance_corrections","sensitive":true,"indexes":[{"name":"attendance_corrections_punch_idx","columns":["tenantId","punchId"]},{"name":"attendance_corrections_subject_idx","columns":["tenantId","subjectProfileId"]}],"api":{"include":[]},"cli":{"include":[]},"mcp":{"include":[]},"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"AttendanceCorrection","collectionExportName":"AttendanceCorrectionCollection","validationRules":[{"field":"acknowledgementRequired","rule":"required","fieldType":"boolean"}],"schema":{"tableName":"attendance_corrections","ddl":"CREATE TABLE IF NOT EXISTS \\"attendance_corrections\\" (\\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 \\"subject_profile_id\\" UUID,\\n \\"actor_profile_id\\" UUID,\\n \\"kind\\" TEXT,\\n \\"punch_id\\" UUID,\\n \\"target_id\\" TEXT,\\n \\"before_state\\" TEXT,\\n \\"after_state\\" TEXT,\\n \\"reason\\" TEXT,\\n \\"acknowledgement_required\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"acknowledged_at\\" TIMESTAMP,\\n \\"acknowledged_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},"subject_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"actor_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"kind":{"type":"TEXT","notNull":false,"unique":false},"punch_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"attendance_punches","column":"id","onDelete":"NO ACTION","onUpdate":"CASCADE"}},"target_id":{"type":"TEXT","notNull":false,"unique":false},"before_state":{"type":"TEXT","notNull":false,"unique":false},"after_state":{"type":"TEXT","notNull":false,"unique":false},"reason":{"type":"TEXT","notNull":false,"unique":false},"acknowledgement_required":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"acknowledged_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"acknowledged_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false}},"indexes":[{"name":"attendance_corrections_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"attendance_corrections_punch_idx","columns":["tenant_id","punch_id"]},{"name":"attendance_corrections_subject_idx","columns":["tenant_id","subject_profile_id"]},{"name":"attendance_corrections_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"attendance_corrections_subject_profile_id_idx","columns":["subject_profile_id"]},{"name":"attendance_corrections_actor_profile_id_idx","columns":["actor_profile_id"]},{"name":"attendance_corrections_punch_id_idx","columns":["punch_id"]},{"name":"attendance_corrections_acknowledged_by_profile_id_idx","columns":["acknowledged_by_profile_id"]}],"version":"19e8de69"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceCorrectionCollection":{"name":"attendancecorrectioncollection","className":"AttendanceCorrectionCollection","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceCorrectionCollection","collection":"attendancecorrections","description":"The correction ledger.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/correction-models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"attendance_corrections","api":{"include":[]},"mcp":{"include":[]},"cli":{"include":[]}},"extends":"SmrtCollection","extendsTypeArg":"AttendanceCorrection","exportName":"AttendanceCorrectionCollection","collectionExportName":"AttendanceCorrectionCollectionCollection","schema":{"tableName":"attendance_corrections","ddl":"CREATE TABLE IF NOT EXISTS \\"attendance_corrections\\" (\\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 \\"subject_profile_id\\" UUID,\\n \\"actor_profile_id\\" UUID,\\n \\"kind\\" TEXT,\\n \\"punch_id\\" UUID,\\n \\"target_id\\" TEXT,\\n \\"before_state\\" TEXT,\\n \\"after_state\\" TEXT,\\n \\"reason\\" TEXT,\\n \\"acknowledgement_required\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"acknowledged_at\\" TIMESTAMP,\\n \\"acknowledged_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},"subject_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"actor_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false},"kind":{"type":"TEXT","notNull":false,"unique":false},"punch_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"attendance_punches","column":"id","onDelete":"NO ACTION","onUpdate":"CASCADE"}},"target_id":{"type":"TEXT","notNull":false,"unique":false},"before_state":{"type":"TEXT","notNull":false,"unique":false},"after_state":{"type":"TEXT","notNull":false,"unique":false},"reason":{"type":"TEXT","notNull":false,"unique":false},"acknowledgement_required":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"acknowledged_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"acknowledged_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":false,"unique":false}},"indexes":[{"name":"attendance_corrections_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"attendance_corrections_punch_idx","columns":["tenant_id","punch_id"]},{"name":"attendance_corrections_subject_idx","columns":["tenant_id","subject_profile_id"]},{"name":"attendance_corrections_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"attendance_corrections_subject_profile_id_idx","columns":["subject_profile_id"]},{"name":"attendance_corrections_actor_profile_id_idx","columns":["actor_profile_id"]},{"name":"attendance_corrections_punch_id_idx","columns":["punch_id"]},{"name":"attendance_corrections_acknowledged_by_profile_id_idx","columns":["acknowledged_by_profile_id"]}],"version":"19e8de69"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendancePunch":{"name":"attendancepunch","className":"AttendancePunch","qualifiedName":"@happyvertical/smrt-timesheets:AttendancePunch","collection":"attendancepunches","description":"A tenant-scoped interval of attendance, independent of billable work.","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},"autoCloseReason":{"type":"text","required":false},"recordedOffline":{"type":"boolean","required":true,"default":false},"source":{"type":"text","required":false},"deviceRefType":{"type":"text","required":false},"deviceRefId":{"type":"text","required":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},{"name":"attendance_punches_source_idx","columns":["tenantId","source"]},{"name":"attendance_punches_device_idx","columns":["tenantId","deviceRefType","deviceRefId"]}],"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 \\"auto_close_reason\\" TEXT,\\n \\"recorded_offline\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"source\\" TEXT,\\n \\"device_ref_type\\" TEXT,\\n \\"device_ref_id\\" TEXT,\\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},"auto_close_reason":{"type":"TEXT","notNull":false,"unique":false},"recorded_offline":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"source":{"type":"TEXT","notNull":false,"unique":false},"device_ref_type":{"type":"TEXT","notNull":false,"unique":false},"device_ref_id":{"type":"TEXT","notNull":false,"unique":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_source_idx","columns":["tenant_id","source"]},{"name":"attendance_punches_device_idx","columns":["tenant_id","device_ref_type","device_ref_id"]},{"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":"6fa5db50"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceBreak":{"name":"attendancebreak","className":"AttendanceBreak","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceBreak","collection":"attendancebreaks","description":"A paid or unpaid break inside one attendance punch.","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},"kind":{"type":"text","required":false},"openSlot":{"type":"text","required":true,"_meta":{"required":true}}},"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":"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 \\"kind\\" TEXT,\\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},"kind":{"type":"TEXT","notNull":false,"unique":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":"1f6b2ddc"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceSegment":{"name":"attendancesegment","className":"AttendanceSegment","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceSegment","collection":"attendancesegments","description":"A running unit of work inside one attendance punch: a work reference plus an optional second (task) reference as queryable columns, so job costing can index and join them.","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"},"workRefType":{"type":"text","required":false},"workRefId":{"type":"text","required":false},"taskRefType":{"type":"text","required":false},"taskRefId":{"type":"text","required":false},"kind":{"type":"text","required":false},"description":{"type":"text","required":false},"startedAt":{"type":"datetime","required":false},"endedAt":{"type":"datetime","required":false},"durationSeconds":{"type":"integer","required":true,"default":0},"closedReason":{"type":"text","required":false,"default":""},"reviewRequired":{"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},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"attendance_segments","indexes":[{"name":"attendance_segments_open_punch_key","columns":["tenantId","punchId","openSlot"],"unique":true},{"name":"attendance_segments_work_idx","columns":["tenantId","workRefType","workRefId"]},{"name":"attendance_segments_task_idx","columns":["tenantId","taskRefType","taskRefId"]}],"api":{"include":["list","get"]},"cli":{"include":["list","get"]},"mcp":{"include":["list","get"]},"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"AttendanceSegment","collectionExportName":"AttendanceSegmentCollection","validationRules":[{"field":"durationSeconds","rule":"required","fieldType":"integer"},{"field":"reviewRequired","rule":"required","fieldType":"boolean"},{"field":"openSlot","rule":"required","fieldType":"text"}],"schema":{"tableName":"attendance_segments","ddl":"CREATE TABLE IF NOT EXISTS \\"attendance_segments\\" (\\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 \\"work_ref_type\\" TEXT,\\n \\"work_ref_id\\" TEXT,\\n \\"task_ref_type\\" TEXT,\\n \\"task_ref_id\\" TEXT,\\n \\"kind\\" TEXT,\\n \\"description\\" TEXT,\\n \\"started_at\\" TIMESTAMP,\\n \\"ended_at\\" TIMESTAMP,\\n \\"duration_seconds\\" INTEGER NOT NULL DEFAULT 0,\\n \\"closed_reason\\" TEXT DEFAULT '',\\n \\"review_required\\" 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"}},"work_ref_type":{"type":"TEXT","notNull":false,"unique":false},"work_ref_id":{"type":"TEXT","notNull":false,"unique":false},"task_ref_type":{"type":"TEXT","notNull":false,"unique":false},"task_ref_id":{"type":"TEXT","notNull":false,"unique":false},"kind":{"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":true,"unique":false,"default":0},"closed_reason":{"type":"TEXT","notNull":false,"unique":false,"default":""},"review_required":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"open_slot":{"type":"TEXT","notNull":true,"unique":false}},"indexes":[{"name":"attendance_segments_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"attendance_segments_open_punch_key","columns":["tenant_id","punch_id","open_slot"],"unique":true},{"name":"attendance_segments_work_idx","columns":["tenant_id","work_ref_type","work_ref_id"]},{"name":"attendance_segments_task_idx","columns":["tenant_id","task_ref_type","task_ref_id"]},{"name":"attendance_segments_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"attendance_segments_punch_id_idx","columns":["punch_id"]}],"version":"6e1c6c80"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceReplay":{"name":"attendancereplay","className":"AttendanceReplay","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceReplay","collection":"attendancereplays","description":"Durable offline-tap outcome; never exposed through generated operations.","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","description":"Punches for attendance and period rollup.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"attendance_punches","api":{"include":["list","get"]},"mcp":{"include":["list","get"]},"cli":{"include":["list","get"]}},"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 \\"auto_close_reason\\" TEXT,\\n \\"recorded_offline\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"source\\" TEXT,\\n \\"device_ref_type\\" TEXT,\\n \\"device_ref_id\\" TEXT,\\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},"auto_close_reason":{"type":"TEXT","notNull":false,"unique":false},"recorded_offline":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"source":{"type":"TEXT","notNull":false,"unique":false},"device_ref_type":{"type":"TEXT","notNull":false,"unique":false},"device_ref_id":{"type":"TEXT","notNull":false,"unique":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_source_idx","columns":["tenant_id","source"]},{"name":"attendance_punches_device_idx","columns":["tenant_id","device_ref_type","device_ref_id"]},{"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":"6fa5db50"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceBreakCollection":{"name":"attendancebreakcollection","className":"AttendanceBreakCollection","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceBreakCollection","collection":"attendancebreaks","description":"Break intervals for net duration and period clipping.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"attendance_breaks","api":{"include":["list","get"]},"mcp":{"include":["list","get"]},"cli":{"include":["list","get"]}},"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 \\"kind\\" TEXT,\\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},"kind":{"type":"TEXT","notNull":false,"unique":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":"1f6b2ddc"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceSegmentCollection":{"name":"attendancesegmentcollection","className":"AttendanceSegmentCollection","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceSegmentCollection","collection":"attendancesegments","description":"Work segments for job costing and attendance review.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"attendance_segments","api":{"include":["list","get"]},"mcp":{"include":["list","get"]},"cli":{"include":["list","get"]}},"extends":"SmrtCollection","extendsTypeArg":"AttendanceSegment","exportName":"AttendanceSegmentCollection","collectionExportName":"AttendanceSegmentCollectionCollection","schema":{"tableName":"attendance_segments","ddl":"CREATE TABLE IF NOT EXISTS \\"attendance_segments\\" (\\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 \\"work_ref_type\\" TEXT,\\n \\"work_ref_id\\" TEXT,\\n \\"task_ref_type\\" TEXT,\\n \\"task_ref_id\\" TEXT,\\n \\"kind\\" TEXT,\\n \\"description\\" TEXT,\\n \\"started_at\\" TIMESTAMP,\\n \\"ended_at\\" TIMESTAMP,\\n \\"duration_seconds\\" INTEGER NOT NULL DEFAULT 0,\\n \\"closed_reason\\" TEXT DEFAULT '',\\n \\"review_required\\" 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"}},"work_ref_type":{"type":"TEXT","notNull":false,"unique":false},"work_ref_id":{"type":"TEXT","notNull":false,"unique":false},"task_ref_type":{"type":"TEXT","notNull":false,"unique":false},"task_ref_id":{"type":"TEXT","notNull":false,"unique":false},"kind":{"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":true,"unique":false,"default":0},"closed_reason":{"type":"TEXT","notNull":false,"unique":false,"default":""},"review_required":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"open_slot":{"type":"TEXT","notNull":true,"unique":false}},"indexes":[{"name":"attendance_segments_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"attendance_segments_open_punch_key","columns":["tenant_id","punch_id","open_slot"],"unique":true},{"name":"attendance_segments_work_idx","columns":["tenant_id","work_ref_type","work_ref_id"]},{"name":"attendance_segments_task_idx","columns":["tenant_id","task_ref_type","task_ref_id"]},{"name":"attendance_segments_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"attendance_segments_punch_id_idx","columns":["punch_id"]}],"version":"6e1c6c80"},"importPath":"@happyvertical/smrt-timesheets/attendance"},"@happyvertical/smrt-timesheets:AttendanceReplayCollection":{"name":"attendancereplaycollection","className":"AttendanceReplayCollection","qualifiedName":"@happyvertical/smrt-timesheets:AttendanceReplayCollection","collection":"attendancereplays","description":"Internal durable replay ledger.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/attendance/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"attendance_replays","api":{"include":[]},"mcp":{"include":[]},"cli":{"include":[]}},"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","description":"Immutable client-charge snapshot for one approved time entry. Money is integer minor units, consistent with smrt-commerce (#2401).","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","description":"Immutable provider-compensation snapshot for one approved time entry, kept separate from the client charge so the margin is charge - compensation.","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":{"mcp":{"include":["list","get"]},"cli":false,"tableName":"service_charge_snapshots","api":{"include":["list","get"]}},"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":{"mcp":{"include":["list","get"]},"cli":false,"tableName":"service_compensation_snapshots","api":{"include":["list","get"]}},"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","description":"A person or agent worked this long on this thing, and someone approved it.","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","record","submit","approve"]},"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","description":"Collection over service_time_entries.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/models/service-time-entry.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{"record":{"name":"record","async":true,"parameters":[{"name":"options","type":"RecordServiceTimeActionInput","optional":false}],"returnType":"Promise<ServiceTimeEntry>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"record","effect":"write","idempotent":false,"openWorld":false,"description":"Record a draft time entry for the signed-in person (service-backed)."}},"submit":{"name":"submit","async":true,"parameters":[{"name":"options","type":"ServiceTimeEntryActionTarget","optional":false}],"returnType":"Promise<ServiceTimeEntry>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"submit","effect":"write","idempotent":false,"openWorld":false,"description":"Submit a time entry for approval (service-backed)."}},"approve":{"name":"approve","async":true,"parameters":[{"name":"options","type":"ServiceTimeEntryActionTarget","optional":false}],"returnType":"Promise<ServiceTimeEntry>","isStatic":false,"isPublic":true,"decoratorConfig":{"httpMethod":"POST","path":"approve","effect":"write","idempotent":true,"openWorld":false,"description":"Approve a submitted time entry and snapshot its charge and compensation (service-backed)."}},"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":{"api":{"include":["forWork","pendingApproval","record","submit","approve"]},"mcp":{"include":["list","get","forWork","pendingApproval"]},"cli":false,"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","description":"One person's immutable-on-confirmation period snapshot, in integer seconds.","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","submitted","confirmed"]},"submittedAt":{"type":"datetime","required":false},"submittedByProfileId":{"type":"crossPackageRef","required":false,"related":"@happyvertical/smrt-profiles:Profile","_meta":{"nullable":true,"onDelete":"RESTRICT"}},"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 \\"submitted_at\\" TIMESTAMP,\\n \\"submitted_by_profile_id\\" UUID,\\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},"submitted_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"submitted_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","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_submitted_by_profile_id_idx","columns":["submitted_by_profile_id"]},{"name":"period_timecards_confirmed_by_profile_id_idx","columns":["confirmed_by_profile_id"]}],"version":"00299335"},"importPath":"@happyvertical/smrt-timesheets/rollup"},"@happyvertical/smrt-timesheets:TimecardAdjustment":{"name":"timecardadjustment","className":"TimecardAdjustment","qualifiedName":"@happyvertical/smrt-timesheets:TimecardAdjustment","collection":"timecardadjustments","description":"Attributed append-only signed seconds; the confirmed base card never changes.","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:TimecardReopening":{"name":"timecardreopening","className":"TimecardReopening","qualifiedName":"@happyvertical/smrt-timesheets:TimecardReopening","collection":"timecardreopenings","description":"Append-only audit row for one reopening of a submitted or confirmed card: who reopened whose period, why, and the totals it had at that moment (base, adjustments and effective, in integer seconds).","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},"fromStatus":{"type":"text","required":false,"_meta":{},"enum":["open","submitted","confirmed"]},"reason":{"type":"text","required":false,"_meta":{}},"previousState":{"type":"text","required":false,"_meta":{}}},"methods":{"getPrevious":{"name":"getPrevious","async":false,"parameters":[],"returnType":"T","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":"timecard_reopenings","sensitive":true,"indexes":[{"name":"timecard_reopenings_card_idx","columns":["tenantId","timecardId"]}],"api":{"include":[]},"cli":{"include":[]},"mcp":{"include":[]},"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"TimecardReopening","collectionExportName":"TimecardReopeningCollection","validationRules":[],"schema":{"tableName":"timecard_reopenings","ddl":"CREATE TABLE IF NOT EXISTS \\"timecard_reopenings\\" (\\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 \\"from_status\\" TEXT,\\n \\"reason\\" TEXT,\\n \\"previous_state\\" 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},"from_status":{"type":"TEXT","notNull":false,"unique":false},"reason":{"type":"TEXT","notNull":false,"unique":false},"previous_state":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"timecard_reopenings_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"timecard_reopenings_card_idx","columns":["tenant_id","timecard_id"]},{"name":"timecard_reopenings_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"timecard_reopenings_timecard_id_idx","columns":["timecard_id"]},{"name":"timecard_reopenings_profile_id_idx","columns":["profile_id"]},{"name":"timecard_reopenings_actor_profile_id_idx","columns":["actor_profile_id"]}],"version":"0498ec40"},"importPath":"@happyvertical/smrt-timesheets/rollup"},"@happyvertical/smrt-timesheets:PeriodTimecardCollection":{"name":"periodtimecardcollection","className":"PeriodTimecardCollection","qualifiedName":"@happyvertical/smrt-timesheets:PeriodTimecardCollection","collection":"periodtimecards","description":"Scoped persistence collection; mutations must use PeriodRollupService.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"period_timecards","api":{"include":[]},"mcp":{"include":[]},"cli":{"include":[]}},"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 \\"submitted_at\\" TIMESTAMP,\\n \\"submitted_by_profile_id\\" UUID,\\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},"submitted_at":{"type":"TIMESTAMP","notNull":false,"unique":false},"submitted_by_profile_id":{"type":"UUID","referenceKind":"crossPackageRef","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_submitted_by_profile_id_idx","columns":["submitted_by_profile_id"]},{"name":"period_timecards_confirmed_by_profile_id_idx","columns":["confirmed_by_profile_id"]}],"version":"00299335"},"importPath":"@happyvertical/smrt-timesheets/rollup"},"@happyvertical/smrt-timesheets:TimecardAdjustmentCollection":{"name":"timecardadjustmentcollection","className":"TimecardAdjustmentCollection","qualifiedName":"@happyvertical/smrt-timesheets:TimecardAdjustmentCollection","collection":"timecardadjustments","description":"Scoped append-only adjustment collection.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"timecard_adjustments","api":{"include":[]},"mcp":{"include":[]},"cli":{"include":[]}},"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"},"@happyvertical/smrt-timesheets:TimecardReopeningCollection":{"name":"timecardreopeningcollection","className":"TimecardReopeningCollection","qualifiedName":"@happyvertical/smrt-timesheets:TimecardReopeningCollection","collection":"timecardreopenings","description":"Scoped append-only reopening ledger.","filePath":"/home/runner/work/smrt/smrt/packages/timesheets/src/rollup/models.ts","packageName":"@happyvertical/smrt-timesheets","fields":{},"methods":{},"decoratorConfig":{"tableName":"timecard_reopenings","api":{"include":[]},"mcp":{"include":[]},"cli":{"include":[]}},"extends":"SmrtCollection","extendsTypeArg":"TimecardReopening","exportName":"TimecardReopeningCollection","collectionExportName":"TimecardReopeningCollectionCollection","schema":{"tableName":"timecard_reopenings","ddl":"CREATE TABLE IF NOT EXISTS \\"timecard_reopenings\\" (\\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 \\"from_status\\" TEXT,\\n \\"reason\\" TEXT,\\n \\"previous_state\\" 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},"from_status":{"type":"TEXT","notNull":false,"unique":false},"reason":{"type":"TEXT","notNull":false,"unique":false},"previous_state":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"timecard_reopenings_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"timecard_reopenings_card_idx","columns":["tenant_id","timecard_id"]},{"name":"timecard_reopenings_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"timecard_reopenings_timecard_id_idx","columns":["timecard_id"]},{"name":"timecard_reopenings_profile_id_idx","columns":["profile_id"]},{"name":"timecard_reopenings_actor_profile_id_idx","columns":["actor_profile_id"]}],"version":"0498ec40"},"importPath":"@happyvertical/smrt-timesheets/rollup"}},"moduleType":"smrt","recipes":[{"id":"timesheets.time-entries","className":"TimeEntriesRecipe","label":"Time entries","summary":"Record who worked how long on what, for approval.","synonyms":["timesheets","time tracking","hours","billable hours","timecards"],"models":["@happyvertical/smrt-timesheets:ServiceTimeEntry"],"nav":[{"label":"Time entries","model":"@happyvertical/smrt-timesheets:ServiceTimeEntry","icon":"fileText","description":"Hours worked, by person and by job, from draft to approved."}],"requires":[],"section":{"id":"work","label":"Work","icon":"wrench","description":"Time and costs: the work behind each job."},"options":{"@happyvertical/smrt-timesheets:ServiceTimeEntry":{"fields":{"participantProfileId":{"label":"Person","order":1},"description":{"order":2,"help":"What the time was spent on, in a few words."},"startedAt":{"label":"Started","order":3},"endedAt":{"label":"Ended","order":4},"durationSeconds":{"label":"Duration (seconds)","order":5,"help":"Whole seconds: 3600 is one hour."},"workRefId":{"label":"Work reference","order":6,"help":"The job, project or case this time belongs to."},"workRefType":{"visibility":"hidden"},"participantKind":{"default":"human","visibility":"hidden"},"agentRef":{"visibility":"hidden"},"source":{"default":"manual","visibility":"hidden"},"evidence":{"visibility":"hidden"},"status":{"visibility":"hidden","locked":true},"submittedAt":{"visibility":"hidden","locked":true},"submittedByProfileId":{"visibility":"hidden","locked":true},"approvedAt":{"visibility":"hidden","locked":true},"approvedByProfileId":{"visibility":"hidden","locked":true},"approvalPath":{"visibility":"hidden","locked":true},"rejectedAt":{"visibility":"hidden","locked":true},"rejectedByProfileId":{"visibility":"hidden","locked":true},"rejectionReason":{"visibility":"hidden","locked":true},"correctionOfId":{"visibility":"hidden","locked":true},"metadata":{"visibility":"hidden"}}}},"help":{"markdown":"## Overview\\n\\nTime entries record who worked how long on what. Each entry names the person,\\nwhat they did and when, and moves from draft to submitted to approved.\\n\\n## Tasks\\n\\n### Record time\\n\\n1. Create a new time entry.\\n2. Pick the **{field:participantProfileId}** who did the work.\\n3. Write a short **{field:description}** of what was done.\\n4. Enter when it **{field:startedAt}** and **{field:endedAt}**, or type the\\n **{field:durationSeconds}** directly (3600 is one hour).\\n\\n### Send it for approval\\n\\nApproval is not something you change on this form. It runs through your\\napp's approval screen, which records who did each step and when.\\n\\n1. When an entry is ready to check, the person who did the work submits it.\\n2. An approver, someone your app allows to approve time, approves it or sends\\n it back with a reason. Approving fixes what the hours are charged and paid\\n at, so an approved entry never changes; correct it with a new entry.\\n3. If your app has no approval screen yet, entries stay as drafts until one is\\n added.\\n","fieldRefs":["description","durationSeconds","endedAt","participantProfileId","startedAt"]},"demo":{"mode":"server","reasons":["Needs a server because its package does not build for a browser: node:crypto; and its package depends on @happyvertical/smrt-profiles, @happyvertical/smrt-tenancy, @happyvertical/smrt-users, which do not build for a browser (#3617, #3624, #3626)."]}}],"smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-tenancy","@happyvertical/smrt-users"],"browser":{"status":"server-only","issues":["#3617","#3624","#3626"],"reason":"node:crypto","via":["@happyvertical/smrt-profiles","@happyvertical/smrt-tenancy","@happyvertical/smrt-users"]},"stampsConstructors":true}`));
6
- //#endregion
7
- //#region src/models/json.ts
8
- function parseTimesheetJson(value, fallback) {
9
- try {
10
- return JSON.parse(value);
11
- } catch {
12
- return fallback;
13
- }
14
- }
15
- //#endregion
16
- //#region src/models/service-time-entry.ts
17
- var __defProp = Object.defineProperty;
18
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
19
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
20
- enumerable: true,
21
- configurable: true,
22
- writable: true,
23
- value
24
- }) : obj[key] = value;
25
- var __decorateClass = (decorators, target, key, kind) => {
26
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
27
- for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
28
- if (kind && result) __defProp(target, key, result);
29
- return result;
30
- };
31
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
- var SERVICE_TIME_ENTRY_FROZEN_FIELDS = [
33
- "tenantId",
34
- "workRefType",
35
- "workRefId",
36
- "participantKind",
37
- "participantProfileId",
38
- "agentRef",
39
- "source",
40
- "description",
41
- "startedAt",
42
- "endedAt",
43
- "durationSeconds",
44
- "evidence",
45
- "correctionOfId"
46
- ];
47
- function toColumn(key) {
48
- return key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
49
- }
50
- function frozenView(source, fields) {
51
- const result = {};
52
- for (const key of fields) {
53
- let value = source[key] ?? null;
54
- if ((key === "startedAt" || key === "endedAt") && value) {
55
- const date = value instanceof Date ? value : new Date(String(value));
56
- value = Number.isNaN(date.getTime()) ? String(value) : date.toISOString();
57
- }
58
- if (key === "durationSeconds" && value !== null) value = Number(value);
59
- result[key] = value === "" ? null : value;
60
- }
61
- return JSON.stringify(result);
62
- }
63
- var loadedStatus = /* @__PURE__ */ new WeakMap();
64
- var ServiceTimeEntry = class extends SmrtObject {
65
- tenantId = null;
66
- workRefType = null;
67
- workRefId = null;
68
- participantKind = "human";
69
- participantProfileId = null;
70
- agentRef = "";
71
- source = "manual";
72
- description = "";
73
- startedAt = null;
74
- endedAt = null;
75
- durationSeconds = 0;
76
- evidence = "[]";
77
- status = "draft";
78
- submittedAt = null;
79
- submittedByProfileId = null;
80
- approvedAt = null;
81
- approvedByProfileId = null;
82
- approvalPath = "";
83
- rejectedAt = null;
84
- rejectedByProfileId = null;
85
- rejectionReason = "";
86
- correctionOfId = null;
87
- metadata = "{}";
88
- getEvidence() {
89
- return parseTimesheetJson(this.evidence, []);
90
- }
91
- setEvidence(value) {
92
- this.evidence = JSON.stringify(value ?? []);
93
- }
94
- getMetadata() {
95
- return parseTimesheetJson(this.metadata, {});
96
- }
97
- setMetadata(value) {
98
- this.metadata = JSON.stringify(value ?? {});
99
- }
100
- /** Original decimal-hours text, without binary floating-point conversion. */
101
- durationHoursExact() {
102
- const evidence = this.getEvidence();
103
- const quantities = (Array.isArray(evidence) ? evidence : []).filter((item) => item?.kind === SERVICE_DURATION_HOURS_EVIDENCE);
104
- if (quantities.length === 0) return null;
105
- if (quantities.length !== 1) throw new Error("Service time requires exactly one decimal-hours quantity.");
106
- return validateDurationHours(quantities[0].hours);
107
- }
108
- /** Numeric convenience for display; use durationHoursExact() for exact terms. */
109
- durationHours() {
110
- if (this.durationSeconds !== null) return this.durationSeconds / 3600;
111
- const hours = this.durationHoursExact();
112
- if (hours === null) throw new Error("Service time has no supported duration quantity.");
113
- return Number(hours);
114
- }
115
- /** Guard for consumers whose policies require independently supplied seconds. */
116
- requireDurationSeconds() {
117
- if (this.durationSeconds === null) throw new Error("Decimal-hours-only service time has no measured durationSeconds; use durationHoursExact() with an hours-aware policy.");
118
- return this.durationSeconds;
119
- }
120
- /**
121
- * Fields frozen once the entry is approved. Subtypes that add work context
122
- * (e.g. a support case) return `[...super.frozenFieldNames(), ...]`.
123
- */
124
- frozenFieldNames() {
125
- return SERVICE_TIME_ENTRY_FROZEN_FIELDS;
126
- }
127
- async initialize() {
128
- await super.initialize();
129
- if (await this.isSaved()) loadedStatus.set(this, this.status);
130
- return this;
131
- }
132
- async save() {
133
- if (this.durationHoursExact() !== null) {
134
- if (this.durationSeconds !== null || this.startedAt || this.endedAt || this.source === "timer") throw new Error("Decimal-hours-only service time cannot also supply seconds or timestamps.");
135
- } else if (this.durationSeconds === null) throw new Error("Null durationSeconds requires explicit decimal-hours evidence.");
136
- const prior = await this.readPrior();
137
- if (prior && prior.status !== this.status && !SERVICE_TIME_ENTRY_STATUS_TRANSITIONS[prior.status].includes(this.status)) throw new Error(`ServiceTimeEntry ${this.id}: illegal status transition '${prior.status}' \u2192 '${this.status}'.`);
138
- if (prior && (prior.status === "approved" || prior.status === "corrected")) {
139
- if (frozenView(this, this.frozenFieldNames()) !== prior.frozen) throw new Error("Approved ServiceTimeEntry evidence is immutable; create a correction instead.");
140
- }
141
- const result = await super.save();
142
- loadedStatus.set(this, this.status);
143
- return result;
144
- }
145
- async readPrior() {
146
- if (!this.id) return null;
147
- const fields = this.frozenFieldNames();
148
- try {
149
- const row = await this.db.get(this.tableName, { id: this.id });
150
- if (!row?.status) return null;
151
- const values = {};
152
- for (const key of fields) values[key] = row[toColumn(key)];
153
- return {
154
- status: row.status,
155
- frozen: frozenView(values, fields)
156
- };
157
- } catch {
158
- const status = loadedStatus.get(this);
159
- return status ? {
160
- status,
161
- frozen: frozenView(this, fields)
162
- } : null;
163
- }
164
- }
165
- };
166
- __publicField(ServiceTimeEntry, "__smrtPackage__", "@happyvertical/smrt-timesheets");
167
- __decorateClass([tenantId({ nullable: true })], ServiceTimeEntry.prototype, "tenantId", 2);
168
- __decorateClass([field({
169
- type: "text",
170
- nullable: true
171
- })], ServiceTimeEntry.prototype, "workRefType", 2);
172
- __decorateClass([field({
173
- type: "text",
174
- nullable: true
175
- })], ServiceTimeEntry.prototype, "workRefId", 2);
176
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "participantKind", 2);
177
- __decorateClass([crossPackageRef("@happyvertical/smrt-profiles:Profile", { nullable: true })], ServiceTimeEntry.prototype, "participantProfileId", 2);
178
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "agentRef", 2);
179
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "source", 2);
180
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "description", 2);
181
- __decorateClass([field({
182
- type: "integer",
183
- nullable: true
184
- })], ServiceTimeEntry.prototype, "durationSeconds", 2);
185
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "evidence", 2);
186
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "status", 2);
187
- __decorateClass([crossPackageRef("@happyvertical/smrt-profiles:Profile", { nullable: true })], ServiceTimeEntry.prototype, "submittedByProfileId", 2);
188
- __decorateClass([crossPackageRef("@happyvertical/smrt-profiles:Profile", { nullable: true })], ServiceTimeEntry.prototype, "approvedByProfileId", 2);
189
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "approvalPath", 2);
190
- __decorateClass([crossPackageRef("@happyvertical/smrt-profiles:Profile", { nullable: true })], ServiceTimeEntry.prototype, "rejectedByProfileId", 2);
191
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "rejectionReason", 2);
192
- __decorateClass([foreignKey("ServiceTimeEntry")], ServiceTimeEntry.prototype, "correctionOfId", 2);
193
- __decorateClass([field({ type: "text" })], ServiceTimeEntry.prototype, "metadata", 2);
194
- ServiceTimeEntry = __decorateClass([TenantScoped({ mode: "optional" }), smrt({
195
- tableName: "service_time_entries",
196
- previousQualifiedNames: ["@happyvertical/smrt-projects:ServiceTimeEntry"],
197
- api: { include: [
198
- "list",
199
- "get",
200
- "record",
201
- "submit",
202
- "approve"
203
- ] },
204
- cli: { include: ["list", "get"] },
205
- mcp: { include: ["list", "get"] }
206
- })], ServiceTimeEntry);
207
- var ServiceTimeEntryCollection = class extends SmrtCollection {
208
- async record(options) {
209
- const { recordServiceTimeAction } = await import("./time-entry-actions-Lb8OYIS8.js").then((n) => n.s);
210
- return recordServiceTimeAction(this, options);
211
- }
212
- async submit(options) {
213
- const { submitServiceTimeAction } = await import("./time-entry-actions-Lb8OYIS8.js").then((n) => n.s);
214
- return submitServiceTimeAction(this, options);
215
- }
216
- async approve(options) {
217
- const { approveServiceTimeAction } = await import("./time-entry-actions-Lb8OYIS8.js").then((n) => n.s);
218
- return approveServiceTimeAction(this, options);
219
- }
220
- async forWork(workRefType, workRefId) {
221
- return this.list({
222
- where: {
223
- workRefType,
224
- workRefId
225
- },
226
- orderBy: "created_at ASC"
227
- });
228
- }
229
- async pendingApproval() {
230
- return this.list({
231
- where: { status: "submitted" },
232
- orderBy: "submitted_at ASC"
233
- });
234
- }
235
- };
236
- __publicField(ServiceTimeEntryCollection, "__smrtPackage__", "@happyvertical/smrt-timesheets");
237
- __publicField(ServiceTimeEntryCollection, "_itemClass", ServiceTimeEntry);
238
- __decorateClass([method({
239
- httpMethod: "POST",
240
- path: "record",
241
- effect: "write",
242
- idempotent: false,
243
- openWorld: false,
244
- description: "Record a draft time entry for the signed-in person (service-backed)."
245
- })], ServiceTimeEntryCollection.prototype, "record", 1);
246
- __decorateClass([method({
247
- httpMethod: "POST",
248
- path: "submit",
249
- effect: "write",
250
- idempotent: false,
251
- openWorld: false,
252
- description: "Submit a time entry for approval (service-backed)."
253
- })], ServiceTimeEntryCollection.prototype, "submit", 1);
254
- __decorateClass([method({
255
- httpMethod: "POST",
256
- path: "approve",
257
- effect: "write",
258
- idempotent: true,
259
- openWorld: false,
260
- description: "Approve a submitted time entry and snapshot its charge and compensation (service-backed)."
261
- })], ServiceTimeEntryCollection.prototype, "approve", 1);
262
- ServiceTimeEntryCollection = __decorateClass([smrt({
263
- api: { include: [
264
- "forWork",
265
- "pendingApproval",
266
- "record",
267
- "submit",
268
- "approve"
269
- ] },
270
- mcp: { include: [
271
- "list",
272
- "get",
273
- "forWork",
274
- "pendingApproval"
275
- ] },
276
- cli: false
277
- })], ServiceTimeEntryCollection);
278
- var SERVICE_DURATION_HOURS_EVIDENCE = "@happyvertical/smrt-timesheets:duration-hours";
279
- function validateDurationHours(value) {
280
- if (typeof value !== "string" || !/^\d+(?:\.\d+)?$/.test(value) || !Number.isFinite(Number(value)) || Number(value) <= 0 || Number(value) >= Number.MAX_SAFE_INTEGER) throw new Error("Service time durationHours must be positive plain decimal text within the supported numeric range.");
281
- return value;
282
- }
283
- //#endregion
284
- export { validateDurationHours as a, ServiceTimeEntryCollection as i, SERVICE_TIME_ENTRY_FROZEN_FIELDS as n, parseTimesheetJson as o, ServiceTimeEntry as r, SERVICE_DURATION_HOURS_EVIDENCE as t };
285
-
286
- //# sourceMappingURL=service-time-entry-DzQsRZc_.js.map