@happyvertical/smrt-timesheets 0.0.0-stage → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/AGENTS.md +105 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +242 -2
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/index.d.ts +20 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +495 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/manifest.json +1412 -0
  12. package/dist/models/index.d.ts +3 -0
  13. package/dist/models/index.d.ts.map +1 -0
  14. package/dist/models/json.d.ts +6 -0
  15. package/dist/models/json.d.ts.map +1 -0
  16. package/dist/models/service-snapshots.d.ts +66 -0
  17. package/dist/models/service-snapshots.d.ts.map +1 -0
  18. package/dist/models/service-time-entry.d.ts +66 -0
  19. package/dist/models/service-time-entry.d.ts.map +1 -0
  20. package/dist/services/index.d.ts +2 -0
  21. package/dist/services/index.d.ts.map +1 -0
  22. package/dist/services/service-evidence-service.d.ts +67 -0
  23. package/dist/services/service-evidence-service.d.ts.map +1 -0
  24. package/dist/smrt-knowledge.json +1016 -0
  25. package/dist/svelte/components/DurationDisplay.svelte +81 -0
  26. package/dist/svelte/components/DurationDisplay.svelte.d.ts +20 -0
  27. package/dist/svelte/components/DurationDisplay.svelte.d.ts.map +1 -0
  28. package/dist/svelte/components/TimeEntryApprovalQueue.svelte +253 -0
  29. package/dist/svelte/components/TimeEntryApprovalQueue.svelte.d.ts +15 -0
  30. package/dist/svelte/components/TimeEntryApprovalQueue.svelte.d.ts.map +1 -0
  31. package/dist/svelte/components/TimeEntryCard.svelte +304 -0
  32. package/dist/svelte/components/TimeEntryCard.svelte.d.ts +25 -0
  33. package/dist/svelte/components/TimeEntryCard.svelte.d.ts.map +1 -0
  34. package/dist/svelte/components/TimeEntryList.svelte +360 -0
  35. package/dist/svelte/components/TimeEntryList.svelte.d.ts +24 -0
  36. package/dist/svelte/components/TimeEntryList.svelte.d.ts.map +1 -0
  37. package/dist/svelte/components/TimeSummary.svelte +176 -0
  38. package/dist/svelte/components/TimeSummary.svelte.d.ts +30 -0
  39. package/dist/svelte/components/TimeSummary.svelte.d.ts.map +1 -0
  40. package/dist/svelte/components/__tests__/DurationDisplay.test.js +57 -0
  41. package/dist/svelte/components/__tests__/TimeEntryApprovalQueue.test.js +114 -0
  42. package/dist/svelte/components/__tests__/TimeEntryCard.test.js +45 -0
  43. package/dist/svelte/components/__tests__/TimeEntryList.test.js +50 -0
  44. package/dist/svelte/components/__tests__/TimeSummary.test.js +39 -0
  45. package/dist/svelte/components/utils.d.ts +51 -0
  46. package/dist/svelte/components/utils.d.ts.map +1 -0
  47. package/dist/svelte/components/utils.js +58 -0
  48. package/dist/svelte/i18n.d.ts +31 -0
  49. package/dist/svelte/i18n.d.ts.map +1 -0
  50. package/dist/svelte/i18n.js +31 -0
  51. package/dist/svelte/index.d.ts +25 -0
  52. package/dist/svelte/index.d.ts.map +1 -0
  53. package/dist/svelte/index.js +27 -0
  54. package/dist/svelte/types.d.ts +41 -0
  55. package/dist/svelte/types.d.ts.map +1 -0
  56. package/dist/svelte/types.js +28 -0
  57. package/dist/types.d.ts +29 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +16 -0
  60. package/dist/types.js.map +1 -0
  61. package/dist/ui.d.ts +17 -0
  62. package/dist/ui.d.ts.map +1 -0
  63. package/dist/ui.js +68 -0
  64. package/dist/ui.js.map +1 -0
  65. package/package.json +85 -3
@@ -0,0 +1,1016 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "sensitiveFieldsExcluded": true,
4
+ "generatedAt": "1970-01-01T00:00:00.000Z",
5
+ "packageName": "@happyvertical/smrt-timesheets",
6
+ "packageVersion": "0.53.0",
7
+ "sourceManifestPath": "dist/manifest.json",
8
+ "agentDocPath": "AGENTS.md",
9
+ "sourceHashes": {
10
+ "manifest": "9ab8a3566995e1aadad62efd9bd41d85c298b3a9656183e54ca90a9765af3f0c",
11
+ "packageJson": "f350ffbdccff7d292fc3bdf8b226361f4ababb3b95af41d195d810778872d332",
12
+ "agents": "a6b055ef3df46c1dc653d96c8fc5983f223fbfcfd9a6b3c5be8382068c515096"
13
+ },
14
+ "exports": [
15
+ ".",
16
+ "./manifest",
17
+ "./manifest.json",
18
+ "./svelte",
19
+ "./ui"
20
+ ],
21
+ "dependencies": {
22
+ "@happyvertical/smrt-core": "workspace:*",
23
+ "@happyvertical/smrt-tenancy": "workspace:*",
24
+ "@happyvertical/smrt-types": "workspace:*",
25
+ "@happyvertical/smrt-ui": "workspace:*",
26
+ "@happyvertical/smrt-vitest": "workspace:*",
27
+ "@happyvertical/sql": "catalog:",
28
+ "@sveltejs/package": "^2.5.8",
29
+ "@sveltejs/vite-plugin-svelte": "^7.3.0",
30
+ "@types/node": "24.13.6",
31
+ "svelte": "^5.57.0",
32
+ "svelte-check": "^4.7.6",
33
+ "typescript": "6.0.3",
34
+ "vite": "8.1.4",
35
+ "vitest": "4.1.10"
36
+ },
37
+ "smrtDependencies": [
38
+ "@happyvertical/smrt-core",
39
+ "@happyvertical/smrt-tenancy",
40
+ "@happyvertical/smrt-types",
41
+ "@happyvertical/smrt-ui",
42
+ "@happyvertical/smrt-vitest"
43
+ ],
44
+ "sdkDependencies": [
45
+ "@happyvertical/sql"
46
+ ],
47
+ "tags": [
48
+ "approval",
49
+ "cross-package",
50
+ "multi-tenant",
51
+ "smrt",
52
+ "time-entries",
53
+ "time-tracking",
54
+ "timesheets"
55
+ ],
56
+ "risks": [
57
+ "cross-package-refs:4",
58
+ "sensitive-fields-excluded"
59
+ ],
60
+ "objects": [
61
+ {
62
+ "name": "ServiceChargeSnapshot",
63
+ "qualifiedName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot",
64
+ "previousQualifiedNames": [
65
+ "@happyvertical/smrt-projects:ServiceChargeSnapshot"
66
+ ],
67
+ "collection": "servicechargesnapshots",
68
+ "tableName": "service_charge_snapshots",
69
+ "packageName": "@happyvertical/smrt-timesheets",
70
+ "extends": "SmrtObject",
71
+ "fields": [
72
+ {
73
+ "name": "tenantId",
74
+ "type": "text",
75
+ "required": false,
76
+ "columnType": "UUID"
77
+ },
78
+ {
79
+ "name": "timeEntryId",
80
+ "type": "foreignKey",
81
+ "required": true,
82
+ "related": "ServiceTimeEntry",
83
+ "columnType": "UUID"
84
+ },
85
+ {
86
+ "name": "amount",
87
+ "type": "integer",
88
+ "required": false,
89
+ "columnType": "INTEGER",
90
+ "default": 0
91
+ },
92
+ {
93
+ "name": "currency",
94
+ "type": "text",
95
+ "required": false,
96
+ "columnType": "TEXT"
97
+ },
98
+ {
99
+ "name": "pricingVersion",
100
+ "type": "text",
101
+ "required": false,
102
+ "columnType": "TEXT"
103
+ },
104
+ {
105
+ "name": "strategy",
106
+ "type": "text",
107
+ "required": false,
108
+ "columnType": "TEXT"
109
+ },
110
+ {
111
+ "name": "rateSnapshot",
112
+ "type": "text",
113
+ "required": false,
114
+ "columnType": "TEXT"
115
+ },
116
+ {
117
+ "name": "sourceChargeRef",
118
+ "type": "text",
119
+ "required": false,
120
+ "columnType": "TEXT"
121
+ },
122
+ {
123
+ "name": "createdAt",
124
+ "type": "datetime",
125
+ "required": false,
126
+ "columnType": "TIMESTAMP"
127
+ }
128
+ ],
129
+ "relationships": [
130
+ {
131
+ "name": "timeEntryId",
132
+ "type": "foreignKey",
133
+ "required": true,
134
+ "related": "ServiceTimeEntry",
135
+ "columnType": "UUID"
136
+ }
137
+ ],
138
+ "methods": [
139
+ "initialize",
140
+ "save"
141
+ ],
142
+ "methodSignatures": [
143
+ {
144
+ "name": "initialize",
145
+ "async": true,
146
+ "returns": "Promise<this>"
147
+ },
148
+ {
149
+ "name": "save",
150
+ "async": true,
151
+ "returns": "Promise<this>"
152
+ }
153
+ ],
154
+ "tenant": {
155
+ "scoped": true,
156
+ "mode": "optional",
157
+ "field": "tenantId"
158
+ },
159
+ "conflictColumns": [
160
+ "time_entry_id"
161
+ ],
162
+ "surfaces": [
163
+ {
164
+ "kind": "api",
165
+ "name": "servicechargesnapshots.list",
166
+ "operation": "list",
167
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot",
168
+ "path": "/servicechargesnapshots",
169
+ "method": "GET"
170
+ },
171
+ {
172
+ "kind": "api",
173
+ "name": "servicechargesnapshots.get",
174
+ "operation": "get",
175
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot",
176
+ "path": "/servicechargesnapshots/[id]",
177
+ "method": "GET"
178
+ },
179
+ {
180
+ "kind": "cli",
181
+ "name": "servicechargesnapshot_list",
182
+ "operation": "list",
183
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
184
+ },
185
+ {
186
+ "kind": "cli",
187
+ "name": "servicechargesnapshot_get",
188
+ "operation": "get",
189
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
190
+ },
191
+ {
192
+ "kind": "mcp",
193
+ "name": "servicechargesnapshot_list",
194
+ "operation": "list",
195
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
196
+ },
197
+ {
198
+ "kind": "mcp",
199
+ "name": "servicechargesnapshot_get",
200
+ "operation": "get",
201
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
202
+ }
203
+ ],
204
+ "withheldSurfaces": [
205
+ {
206
+ "kind": "api",
207
+ "operation": "initialize",
208
+ "code": "lifecycle-method",
209
+ "reason": "`initialize` is a framework lifecycle method, not a distinct operation",
210
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
211
+ },
212
+ {
213
+ "kind": "api",
214
+ "operation": "save",
215
+ "code": "lifecycle-method",
216
+ "reason": "`save` is a framework lifecycle method, not a distinct operation",
217
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
218
+ }
219
+ ],
220
+ "relationshipFeatures": [
221
+ "foreignKey",
222
+ "uuidColumns"
223
+ ],
224
+ "tags": [],
225
+ "risks": []
226
+ },
227
+ {
228
+ "name": "ServiceCompensationSnapshot",
229
+ "qualifiedName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot",
230
+ "previousQualifiedNames": [
231
+ "@happyvertical/smrt-projects:ServiceCompensationSnapshot"
232
+ ],
233
+ "collection": "servicecompensationsnapshots",
234
+ "tableName": "service_compensation_snapshots",
235
+ "packageName": "@happyvertical/smrt-timesheets",
236
+ "extends": "SmrtObject",
237
+ "fields": [
238
+ {
239
+ "name": "tenantId",
240
+ "type": "text",
241
+ "required": false,
242
+ "columnType": "UUID"
243
+ },
244
+ {
245
+ "name": "timeEntryId",
246
+ "type": "foreignKey",
247
+ "required": true,
248
+ "related": "ServiceTimeEntry",
249
+ "columnType": "UUID"
250
+ },
251
+ {
252
+ "name": "amount",
253
+ "type": "integer",
254
+ "required": false,
255
+ "columnType": "INTEGER",
256
+ "default": 0
257
+ },
258
+ {
259
+ "name": "currency",
260
+ "type": "text",
261
+ "required": false,
262
+ "columnType": "TEXT"
263
+ },
264
+ {
265
+ "name": "termsVersion",
266
+ "type": "text",
267
+ "required": false,
268
+ "columnType": "TEXT"
269
+ },
270
+ {
271
+ "name": "rateSnapshot",
272
+ "type": "text",
273
+ "required": false,
274
+ "columnType": "TEXT"
275
+ },
276
+ {
277
+ "name": "createdAt",
278
+ "type": "datetime",
279
+ "required": false,
280
+ "columnType": "TIMESTAMP"
281
+ }
282
+ ],
283
+ "relationships": [
284
+ {
285
+ "name": "timeEntryId",
286
+ "type": "foreignKey",
287
+ "required": true,
288
+ "related": "ServiceTimeEntry",
289
+ "columnType": "UUID"
290
+ }
291
+ ],
292
+ "methods": [
293
+ "initialize",
294
+ "save"
295
+ ],
296
+ "methodSignatures": [
297
+ {
298
+ "name": "initialize",
299
+ "async": true,
300
+ "returns": "Promise<this>"
301
+ },
302
+ {
303
+ "name": "save",
304
+ "async": true,
305
+ "returns": "Promise<this>"
306
+ }
307
+ ],
308
+ "tenant": {
309
+ "scoped": true,
310
+ "mode": "optional",
311
+ "field": "tenantId"
312
+ },
313
+ "conflictColumns": [
314
+ "time_entry_id"
315
+ ],
316
+ "surfaces": [
317
+ {
318
+ "kind": "api",
319
+ "name": "servicecompensationsnapshots.list",
320
+ "operation": "list",
321
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot",
322
+ "path": "/servicecompensationsnapshots",
323
+ "method": "GET"
324
+ },
325
+ {
326
+ "kind": "api",
327
+ "name": "servicecompensationsnapshots.get",
328
+ "operation": "get",
329
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot",
330
+ "path": "/servicecompensationsnapshots/[id]",
331
+ "method": "GET"
332
+ },
333
+ {
334
+ "kind": "cli",
335
+ "name": "servicecompensationsnapshot_list",
336
+ "operation": "list",
337
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
338
+ },
339
+ {
340
+ "kind": "cli",
341
+ "name": "servicecompensationsnapshot_get",
342
+ "operation": "get",
343
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
344
+ },
345
+ {
346
+ "kind": "mcp",
347
+ "name": "servicecompensationsnapshot_list",
348
+ "operation": "list",
349
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
350
+ },
351
+ {
352
+ "kind": "mcp",
353
+ "name": "servicecompensationsnapshot_get",
354
+ "operation": "get",
355
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
356
+ }
357
+ ],
358
+ "withheldSurfaces": [
359
+ {
360
+ "kind": "api",
361
+ "operation": "initialize",
362
+ "code": "lifecycle-method",
363
+ "reason": "`initialize` is a framework lifecycle method, not a distinct operation",
364
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
365
+ },
366
+ {
367
+ "kind": "api",
368
+ "operation": "save",
369
+ "code": "lifecycle-method",
370
+ "reason": "`save` is a framework lifecycle method, not a distinct operation",
371
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
372
+ }
373
+ ],
374
+ "relationshipFeatures": [
375
+ "foreignKey",
376
+ "uuidColumns"
377
+ ],
378
+ "tags": [],
379
+ "risks": []
380
+ },
381
+ {
382
+ "name": "ServiceChargeSnapshotCollection",
383
+ "qualifiedName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshotCollection",
384
+ "collection": "servicechargesnapshots",
385
+ "tableName": "service_charge_snapshots",
386
+ "packageName": "@happyvertical/smrt-timesheets",
387
+ "extends": "SmrtCollection",
388
+ "fields": [],
389
+ "relationships": [],
390
+ "methods": [],
391
+ "surfaces": [],
392
+ "relationshipFeatures": [
393
+ "uuidColumns"
394
+ ],
395
+ "tags": [],
396
+ "risks": []
397
+ },
398
+ {
399
+ "name": "ServiceCompensationSnapshotCollection",
400
+ "qualifiedName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshotCollection",
401
+ "collection": "servicecompensationsnapshots",
402
+ "tableName": "service_compensation_snapshots",
403
+ "packageName": "@happyvertical/smrt-timesheets",
404
+ "extends": "SmrtCollection",
405
+ "fields": [],
406
+ "relationships": [],
407
+ "methods": [],
408
+ "surfaces": [],
409
+ "relationshipFeatures": [
410
+ "uuidColumns"
411
+ ],
412
+ "tags": [],
413
+ "risks": []
414
+ },
415
+ {
416
+ "name": "ServiceTimeEntry",
417
+ "qualifiedName": "@happyvertical/smrt-timesheets:ServiceTimeEntry",
418
+ "previousQualifiedNames": [
419
+ "@happyvertical/smrt-projects:ServiceTimeEntry"
420
+ ],
421
+ "collection": "servicetimeentries",
422
+ "tableName": "service_time_entries",
423
+ "packageName": "@happyvertical/smrt-timesheets",
424
+ "extends": "SmrtObject",
425
+ "fields": [
426
+ {
427
+ "name": "tenantId",
428
+ "type": "text",
429
+ "required": false,
430
+ "columnType": "UUID"
431
+ },
432
+ {
433
+ "name": "workRefType",
434
+ "type": "text",
435
+ "required": false,
436
+ "columnType": "TEXT"
437
+ },
438
+ {
439
+ "name": "workRefId",
440
+ "type": "text",
441
+ "required": false,
442
+ "columnType": "TEXT"
443
+ },
444
+ {
445
+ "name": "participantKind",
446
+ "type": "text",
447
+ "required": false,
448
+ "columnType": "TEXT"
449
+ },
450
+ {
451
+ "name": "participantProfileId",
452
+ "type": "crossPackageRef",
453
+ "required": false,
454
+ "related": "@happyvertical/smrt-profiles:Profile",
455
+ "columnType": "UUID"
456
+ },
457
+ {
458
+ "name": "agentRef",
459
+ "type": "text",
460
+ "required": false,
461
+ "columnType": "TEXT"
462
+ },
463
+ {
464
+ "name": "source",
465
+ "type": "text",
466
+ "required": false,
467
+ "columnType": "TEXT"
468
+ },
469
+ {
470
+ "name": "description",
471
+ "type": "text",
472
+ "required": false,
473
+ "columnType": "TEXT"
474
+ },
475
+ {
476
+ "name": "startedAt",
477
+ "type": "datetime",
478
+ "required": false,
479
+ "columnType": "TIMESTAMP"
480
+ },
481
+ {
482
+ "name": "endedAt",
483
+ "type": "datetime",
484
+ "required": false,
485
+ "columnType": "TIMESTAMP"
486
+ },
487
+ {
488
+ "name": "durationSeconds",
489
+ "type": "integer",
490
+ "required": false,
491
+ "columnType": "INTEGER",
492
+ "default": 0
493
+ },
494
+ {
495
+ "name": "evidence",
496
+ "type": "text",
497
+ "required": false,
498
+ "columnType": "TEXT"
499
+ },
500
+ {
501
+ "name": "status",
502
+ "type": "text",
503
+ "required": false,
504
+ "columnType": "TEXT"
505
+ },
506
+ {
507
+ "name": "submittedAt",
508
+ "type": "datetime",
509
+ "required": false,
510
+ "columnType": "TIMESTAMP"
511
+ },
512
+ {
513
+ "name": "submittedByProfileId",
514
+ "type": "crossPackageRef",
515
+ "required": false,
516
+ "related": "@happyvertical/smrt-profiles:Profile",
517
+ "columnType": "UUID"
518
+ },
519
+ {
520
+ "name": "approvedAt",
521
+ "type": "datetime",
522
+ "required": false,
523
+ "columnType": "TIMESTAMP"
524
+ },
525
+ {
526
+ "name": "approvedByProfileId",
527
+ "type": "crossPackageRef",
528
+ "required": false,
529
+ "related": "@happyvertical/smrt-profiles:Profile",
530
+ "columnType": "UUID"
531
+ },
532
+ {
533
+ "name": "approvalPath",
534
+ "type": "text",
535
+ "required": false,
536
+ "columnType": "TEXT"
537
+ },
538
+ {
539
+ "name": "rejectedAt",
540
+ "type": "datetime",
541
+ "required": false,
542
+ "columnType": "TIMESTAMP"
543
+ },
544
+ {
545
+ "name": "rejectedByProfileId",
546
+ "type": "crossPackageRef",
547
+ "required": false,
548
+ "related": "@happyvertical/smrt-profiles:Profile",
549
+ "columnType": "UUID"
550
+ },
551
+ {
552
+ "name": "rejectionReason",
553
+ "type": "text",
554
+ "required": false,
555
+ "columnType": "TEXT"
556
+ },
557
+ {
558
+ "name": "correctionOfId",
559
+ "type": "foreignKey",
560
+ "required": false,
561
+ "related": "ServiceTimeEntry",
562
+ "columnType": "UUID"
563
+ },
564
+ {
565
+ "name": "metadata",
566
+ "type": "text",
567
+ "required": false,
568
+ "columnType": "TEXT"
569
+ }
570
+ ],
571
+ "relationships": [
572
+ {
573
+ "name": "participantProfileId",
574
+ "type": "crossPackageRef",
575
+ "required": false,
576
+ "related": "@happyvertical/smrt-profiles:Profile",
577
+ "columnType": "UUID"
578
+ },
579
+ {
580
+ "name": "submittedByProfileId",
581
+ "type": "crossPackageRef",
582
+ "required": false,
583
+ "related": "@happyvertical/smrt-profiles:Profile",
584
+ "columnType": "UUID"
585
+ },
586
+ {
587
+ "name": "approvedByProfileId",
588
+ "type": "crossPackageRef",
589
+ "required": false,
590
+ "related": "@happyvertical/smrt-profiles:Profile",
591
+ "columnType": "UUID"
592
+ },
593
+ {
594
+ "name": "rejectedByProfileId",
595
+ "type": "crossPackageRef",
596
+ "required": false,
597
+ "related": "@happyvertical/smrt-profiles:Profile",
598
+ "columnType": "UUID"
599
+ },
600
+ {
601
+ "name": "correctionOfId",
602
+ "type": "foreignKey",
603
+ "required": false,
604
+ "related": "ServiceTimeEntry",
605
+ "columnType": "UUID"
606
+ }
607
+ ],
608
+ "methods": [
609
+ "durationHours",
610
+ "getEvidence",
611
+ "getMetadata",
612
+ "initialize",
613
+ "save",
614
+ "setEvidence",
615
+ "setMetadata"
616
+ ],
617
+ "methodSignatures": [
618
+ {
619
+ "name": "durationHours",
620
+ "returns": "number"
621
+ },
622
+ {
623
+ "name": "getEvidence",
624
+ "returns": "ServiceEvidence[]"
625
+ },
626
+ {
627
+ "name": "getMetadata",
628
+ "returns": "Record<string, unknown>"
629
+ },
630
+ {
631
+ "name": "initialize",
632
+ "async": true,
633
+ "returns": "Promise<this>"
634
+ },
635
+ {
636
+ "name": "save",
637
+ "async": true,
638
+ "returns": "Promise<this>"
639
+ },
640
+ {
641
+ "name": "setEvidence",
642
+ "params": [
643
+ "value: ServiceEvidence[]"
644
+ ],
645
+ "returns": "void"
646
+ },
647
+ {
648
+ "name": "setMetadata",
649
+ "params": [
650
+ "value: Record<string, unknown>"
651
+ ],
652
+ "returns": "void"
653
+ }
654
+ ],
655
+ "tenant": {
656
+ "scoped": true,
657
+ "mode": "optional",
658
+ "field": "tenantId"
659
+ },
660
+ "conflictColumns": [
661
+ "tenant_id",
662
+ "slug",
663
+ "context"
664
+ ],
665
+ "surfaces": [
666
+ {
667
+ "kind": "api",
668
+ "name": "servicetimeentries.list",
669
+ "operation": "list",
670
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry",
671
+ "path": "/servicetimeentries",
672
+ "method": "GET"
673
+ },
674
+ {
675
+ "kind": "api",
676
+ "name": "servicetimeentries.get",
677
+ "operation": "get",
678
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry",
679
+ "path": "/servicetimeentries/[id]",
680
+ "method": "GET"
681
+ },
682
+ {
683
+ "kind": "cli",
684
+ "name": "servicetimeentry_list",
685
+ "operation": "list",
686
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
687
+ },
688
+ {
689
+ "kind": "cli",
690
+ "name": "servicetimeentry_get",
691
+ "operation": "get",
692
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
693
+ },
694
+ {
695
+ "kind": "mcp",
696
+ "name": "servicetimeentry_list",
697
+ "operation": "list",
698
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
699
+ },
700
+ {
701
+ "kind": "mcp",
702
+ "name": "servicetimeentry_get",
703
+ "operation": "get",
704
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
705
+ }
706
+ ],
707
+ "withheldSurfaces": [
708
+ {
709
+ "kind": "api",
710
+ "operation": "durationHours",
711
+ "code": "not-included",
712
+ "reason": "not listed in api.include",
713
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
714
+ },
715
+ {
716
+ "kind": "api",
717
+ "operation": "getEvidence",
718
+ "code": "not-included",
719
+ "reason": "not listed in api.include",
720
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
721
+ },
722
+ {
723
+ "kind": "api",
724
+ "operation": "getMetadata",
725
+ "code": "not-included",
726
+ "reason": "not listed in api.include",
727
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
728
+ },
729
+ {
730
+ "kind": "api",
731
+ "operation": "initialize",
732
+ "code": "lifecycle-method",
733
+ "reason": "`initialize` is a framework lifecycle method, not a distinct operation",
734
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
735
+ },
736
+ {
737
+ "kind": "api",
738
+ "operation": "save",
739
+ "code": "lifecycle-method",
740
+ "reason": "`save` is a framework lifecycle method, not a distinct operation",
741
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
742
+ },
743
+ {
744
+ "kind": "api",
745
+ "operation": "setEvidence",
746
+ "code": "not-included",
747
+ "reason": "not listed in api.include",
748
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
749
+ },
750
+ {
751
+ "kind": "api",
752
+ "operation": "setMetadata",
753
+ "code": "not-included",
754
+ "reason": "not listed in api.include",
755
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
756
+ }
757
+ ],
758
+ "relationshipFeatures": [
759
+ "crossPackageRef",
760
+ "foreignKey",
761
+ "uuidColumns"
762
+ ],
763
+ "tags": [],
764
+ "risks": []
765
+ },
766
+ {
767
+ "name": "ServiceTimeEntryCollection",
768
+ "qualifiedName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection",
769
+ "collection": "servicetimeentries",
770
+ "tableName": "service_time_entries",
771
+ "packageName": "@happyvertical/smrt-timesheets",
772
+ "extends": "SmrtCollection",
773
+ "fields": [],
774
+ "relationships": [],
775
+ "methods": [
776
+ "forWork",
777
+ "pendingApproval"
778
+ ],
779
+ "methodSignatures": [
780
+ {
781
+ "name": "forWork",
782
+ "async": true,
783
+ "params": [
784
+ "workRefType: string",
785
+ "workRefId: string"
786
+ ],
787
+ "returns": "Promise<ServiceTimeEntry[]>"
788
+ },
789
+ {
790
+ "name": "pendingApproval",
791
+ "async": true,
792
+ "returns": "Promise<ServiceTimeEntry[]>"
793
+ }
794
+ ],
795
+ "surfaces": [
796
+ {
797
+ "kind": "api",
798
+ "name": "servicetimeentries.forWork",
799
+ "operation": "forWork",
800
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection",
801
+ "path": "/servicetimeentries/forWork",
802
+ "method": "POST"
803
+ },
804
+ {
805
+ "kind": "api",
806
+ "name": "servicetimeentries.pendingApproval",
807
+ "operation": "pendingApproval",
808
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection",
809
+ "path": "/servicetimeentries/pendingApproval",
810
+ "method": "POST"
811
+ },
812
+ {
813
+ "kind": "cli",
814
+ "name": "servicetimeentrycollection_forWork",
815
+ "operation": "forWork",
816
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
817
+ },
818
+ {
819
+ "kind": "cli",
820
+ "name": "servicetimeentrycollection_pendingApproval",
821
+ "operation": "pendingApproval",
822
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
823
+ },
824
+ {
825
+ "kind": "mcp",
826
+ "name": "servicetimeentrycollection_forwork",
827
+ "operation": "forWork",
828
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
829
+ },
830
+ {
831
+ "kind": "mcp",
832
+ "name": "servicetimeentrycollection_pendingapproval",
833
+ "operation": "pendingApproval",
834
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
835
+ }
836
+ ],
837
+ "relationshipFeatures": [
838
+ "uuidColumns"
839
+ ],
840
+ "tags": [],
841
+ "risks": []
842
+ }
843
+ ],
844
+ "surfaces": [
845
+ {
846
+ "kind": "api",
847
+ "name": "servicechargesnapshots.list",
848
+ "operation": "list",
849
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot",
850
+ "path": "/servicechargesnapshots",
851
+ "method": "GET"
852
+ },
853
+ {
854
+ "kind": "api",
855
+ "name": "servicechargesnapshots.get",
856
+ "operation": "get",
857
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot",
858
+ "path": "/servicechargesnapshots/[id]",
859
+ "method": "GET"
860
+ },
861
+ {
862
+ "kind": "cli",
863
+ "name": "servicechargesnapshot_list",
864
+ "operation": "list",
865
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
866
+ },
867
+ {
868
+ "kind": "cli",
869
+ "name": "servicechargesnapshot_get",
870
+ "operation": "get",
871
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
872
+ },
873
+ {
874
+ "kind": "mcp",
875
+ "name": "servicechargesnapshot_list",
876
+ "operation": "list",
877
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
878
+ },
879
+ {
880
+ "kind": "mcp",
881
+ "name": "servicechargesnapshot_get",
882
+ "operation": "get",
883
+ "objectName": "@happyvertical/smrt-timesheets:ServiceChargeSnapshot"
884
+ },
885
+ {
886
+ "kind": "api",
887
+ "name": "servicecompensationsnapshots.list",
888
+ "operation": "list",
889
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot",
890
+ "path": "/servicecompensationsnapshots",
891
+ "method": "GET"
892
+ },
893
+ {
894
+ "kind": "api",
895
+ "name": "servicecompensationsnapshots.get",
896
+ "operation": "get",
897
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot",
898
+ "path": "/servicecompensationsnapshots/[id]",
899
+ "method": "GET"
900
+ },
901
+ {
902
+ "kind": "cli",
903
+ "name": "servicecompensationsnapshot_list",
904
+ "operation": "list",
905
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
906
+ },
907
+ {
908
+ "kind": "cli",
909
+ "name": "servicecompensationsnapshot_get",
910
+ "operation": "get",
911
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
912
+ },
913
+ {
914
+ "kind": "mcp",
915
+ "name": "servicecompensationsnapshot_list",
916
+ "operation": "list",
917
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
918
+ },
919
+ {
920
+ "kind": "mcp",
921
+ "name": "servicecompensationsnapshot_get",
922
+ "operation": "get",
923
+ "objectName": "@happyvertical/smrt-timesheets:ServiceCompensationSnapshot"
924
+ },
925
+ {
926
+ "kind": "api",
927
+ "name": "servicetimeentries.list",
928
+ "operation": "list",
929
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry",
930
+ "path": "/servicetimeentries",
931
+ "method": "GET"
932
+ },
933
+ {
934
+ "kind": "api",
935
+ "name": "servicetimeentries.get",
936
+ "operation": "get",
937
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry",
938
+ "path": "/servicetimeentries/[id]",
939
+ "method": "GET"
940
+ },
941
+ {
942
+ "kind": "cli",
943
+ "name": "servicetimeentry_list",
944
+ "operation": "list",
945
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
946
+ },
947
+ {
948
+ "kind": "cli",
949
+ "name": "servicetimeentry_get",
950
+ "operation": "get",
951
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
952
+ },
953
+ {
954
+ "kind": "mcp",
955
+ "name": "servicetimeentry_list",
956
+ "operation": "list",
957
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
958
+ },
959
+ {
960
+ "kind": "mcp",
961
+ "name": "servicetimeentry_get",
962
+ "operation": "get",
963
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntry"
964
+ },
965
+ {
966
+ "kind": "api",
967
+ "name": "servicetimeentries.forWork",
968
+ "operation": "forWork",
969
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection",
970
+ "path": "/servicetimeentries/forWork",
971
+ "method": "POST"
972
+ },
973
+ {
974
+ "kind": "api",
975
+ "name": "servicetimeentries.pendingApproval",
976
+ "operation": "pendingApproval",
977
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection",
978
+ "path": "/servicetimeentries/pendingApproval",
979
+ "method": "POST"
980
+ },
981
+ {
982
+ "kind": "cli",
983
+ "name": "servicetimeentrycollection_forWork",
984
+ "operation": "forWork",
985
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
986
+ },
987
+ {
988
+ "kind": "cli",
989
+ "name": "servicetimeentrycollection_pendingApproval",
990
+ "operation": "pendingApproval",
991
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
992
+ },
993
+ {
994
+ "kind": "mcp",
995
+ "name": "servicetimeentrycollection_forwork",
996
+ "operation": "forWork",
997
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
998
+ },
999
+ {
1000
+ "kind": "mcp",
1001
+ "name": "servicetimeentrycollection_pendingapproval",
1002
+ "operation": "pendingApproval",
1003
+ "objectName": "@happyvertical/smrt-timesheets:ServiceTimeEntryCollection"
1004
+ }
1005
+ ],
1006
+ "prompts": [],
1007
+ "relationshipsV2": {
1008
+ "foreignKeyFields": 3,
1009
+ "crossPackageRefFields": 4,
1010
+ "junctionCollections": 0,
1011
+ "hierarchicalObjects": 0,
1012
+ "polymorphicAssociations": 0,
1013
+ "uuidColumns": 26
1014
+ },
1015
+ "agentDoc": "# smrt-timesheets\n\nShared time entries: who (a `smrt-profiles` Profile, or an agent) worked how\nlong on what (a generic work reference), whether it was approved, and the\nimmutable charge / compensation snapshots taken at approval. Moved out of\n`smrt-projects` / `smrt-support` in #3288 so shops, builders, and service\ndesks share one model instead of re-implementing it.\n\nThis package is **layer 1 (entry)**. Attendance (punches, breaks, offline\nreplay) and period rollup (per-person timecards) are planned as later modules\nof this same package; do not add them to projects or support.\n\n## Models\n\n| Model | Table | Notes |\n|---|---|---|\n| `ServiceTimeEntry` | `service_time_entries` | `workRefType` + `workRefId`, `participantKind` (`human` \\| `agent`), `participantProfileId` / `agentRef`, `source`, `startedAt` / `endedAt` / `durationSeconds`, status machine, `correctionOfId` |\n| `ServiceChargeSnapshot` | `service_charge_snapshots` | Client charge, integer minor units (#2401), one per entry |\n| `ServiceCompensationSnapshot` | `service_compensation_snapshots` | Provider earning, integer minor units, one per entry |\n\n`ServiceEvidenceService` records, submits, approves (writing both snapshots\nthrough a `ServiceCommercialResolver`), and corrects. `smrt-projects` supplies\n`SubscriptionServiceCommercialResolver` for #1925 pricing.\n\n## Invariants\n\n- **No domain foreign key on the base.** Work context is the generic\n `workRefType` (qualified class name) + `workRefId`. A domain adds its own\n context by subclassing over the same table — smrt-support's\n `ServiceTimeEntry` adds `caseId` / `specialistId` and extends\n `frozenFieldNames()` so they freeze on approval.\n- **Entries carry no rate.** Money lives only on the snapshots, `= 0`\n integer initializers (INTEGER columns). Never `= 0.0`. Snapshot `save()`\n rejects an `amount` that is not a safe integer (`VALIDATION_INVALID_VALUE`),\n so SQLite cannot silently store `19.99`; fix a fractional resolver at its\n source rather than rounding here.\n- **Approved evidence never changes.** `save()` enforces\n `SERVICE_TIME_ENTRY_STATUS_TRANSITIONS` and compares the frozen fields with\n the stored row. A correction is a new row (`correctionOfId`), the original\n flips to `corrected`. Snapshots are immutable after their first save.\n- **Old qualified names are aliases.** Each model declares its pre-#3288\n `@happyvertical/smrt-projects:*` name in `previousQualifiedNames` (#3338;\n `packages/core/agents/model-moves.md`). smrt-projects must never list these\n classes in its manifests again (`CONFIG_QUALIFIED_NAME_ALIAS_COLLISION`),\n and no subtype (smrt-support's, or a consumer's closing subclass) may\n redeclare an alias (two claimants). Known gap: a same-named subtype that\n replaces a moved class drops that class's alias, and the replaced class's\n own `@happyvertical/smrt-timesheets:*` name stops resolving too — guidance\n for apps with smrt-support must name `@happyvertical/smrt-support:ServiceTimeEntry`.\n Support's vitest environment keeps both classes registered, so verify this\n against built packages, not package tests. `projects/src/__tests__/legacy-qualified-identity.test.ts` pins\n the projects-only contract.\n- **Table names are a compatibility contract.** `service_time_entries` and the\n two snapshot tables hold existing production rows from smrt-projects /\n smrt-support; renaming any of them, or adding a discriminator, is a data\n migration.\n\n## One table family\n\nClasses may share a table only as one inheritance chain, and the registry\nresolves a chain of same-named classes by \"child wins\" on the simple name.\nThat works for exactly one subtype level per table (base → subtype); a third\nsame-named level makes the middle class look like it extends its own child on\nthe manifest path (`CONFIG_TABLE_NAME_COLLISION`). Therefore:\n\n- `smrt-projects` **re-exports** these classes (no projects subclass).\n- `smrt-support` subclasses `ServiceTimeEntry` directly from this package.\n- A consumer that needs its own surface (e.g. teamworks-os closing every\n generated route with `api: { include: [] }` and\n `@TenantScoped({ mode: 'required' })`) declares a same-named subclass over\n `service_time_entries`; its manifest entry replaces the package's. It cannot\n also install smrt-support's subtype on the same table.\n The same applies to both snapshots;\n `src/__tests__/consumer-closed-surface.test.ts` holds that contract for all\n three models. The snapshots' explicit `time_entry_id` conflict key is not\n rewritten when a consumer requires tenancy; widening it is the consumer's\n schema change, never a package default.\n\nSubclasses restate their fields: package-isolated manifest scanning does not\nread dependency sources, so an unrestated subclass manifest has no columns.\n\n## Svelte UI\n\n`./svelte` exports `TimeEntryCard`, `TimeEntryList`, `TimeSummary`,\n`DurationDisplay`, and `TimeEntryApprovalQueue` (props-driven, plain view\nobjects, `smrt-ui` primitives, `smrtRawPrimitives: \"strict\"`). smrt-projects\nand smrt-support re-export them from their own `./svelte` subpaths.\nCard/list/summary message keys keep their `projects.*` namespace: tenant\nlanguage overrides are stored by key, and renaming would orphan them. New\nkeys use `timesheets.*`.\n\n## Validation\n\n```sh\npnpm --filter @happyvertical/smrt-timesheets test\npnpm --filter @happyvertical/smrt-timesheets test:postgres\npnpm --filter @happyvertical/smrt-timesheets typecheck\npnpm --filter @happyvertical/smrt-timesheets build\npnpm --filter @happyvertical/smrt-projects test\npnpm --filter @happyvertical/smrt-support test\n```\n\nSchema-affecting edits must keep `service-time-entry-compat.test.ts` (projects,\nsupport) and `service-time-entry-migration-plan.test.ts` (support) green: a\npre-move table must plan no DDL.\n"
1016
+ }