@happyvertical/smrt-timesheets 0.55.21 → 0.55.22

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 (30) hide show
  1. package/README.md +9 -0
  2. package/agents/labour-valuation.md +73 -0
  3. package/dist/attendance.js +2 -2
  4. package/dist/chunks/{attendance-OKyc1O4x.js → attendance-C-kCpZhE.js} +3 -3
  5. package/dist/chunks/{attendance-OKyc1O4x.js.map → attendance-C-kCpZhE.js.map} +1 -1
  6. package/dist/chunks/{models-B0NOh8I3.js → models-tyWxagDd.js} +2 -2
  7. package/dist/chunks/{models-B0NOh8I3.js.map → models-tyWxagDd.js.map} +1 -1
  8. package/dist/chunks/{rollup-2--s0AyP.js → rollup-BLgHT9GI.js} +3 -3
  9. package/dist/chunks/{rollup-2--s0AyP.js.map → rollup-BLgHT9GI.js.map} +1 -1
  10. package/dist/chunks/{service-time-entry-BY8UcnFk.js → service-time-entry-DY1LlZRv.js} +2 -2
  11. package/dist/chunks/{service-time-entry-BY8UcnFk.js.map → service-time-entry-DY1LlZRv.js.map} +1 -1
  12. package/dist/index.js +285 -8
  13. package/dist/index.js.map +1 -1
  14. package/dist/manifest.json +1 -1
  15. package/dist/rollup.js +1 -1
  16. package/dist/services/dated-labour-commercial-resolver.d.ts.map +1 -1
  17. package/dist/services/dated-percentage-labour-commercial-resolver.d.ts +36 -0
  18. package/dist/services/dated-percentage-labour-commercial-resolver.d.ts.map +1 -0
  19. package/dist/services/index.d.ts +2 -0
  20. package/dist/services/index.d.ts.map +1 -1
  21. package/dist/services/labour-math.d.ts +17 -0
  22. package/dist/services/labour-math.d.ts.map +1 -0
  23. package/dist/services/labour-valuation-reconciliation.d.ts +59 -0
  24. package/dist/services/labour-valuation-reconciliation.d.ts.map +1 -0
  25. package/dist/smrt-knowledge.json +3 -3
  26. package/dist/svelte/components/TimeEntryApprovalQueue.svelte +1 -1
  27. package/dist/svelte/components/TimeEntryCard.svelte +4 -4
  28. package/dist/svelte/components/TimeEntryList.svelte +3 -3
  29. package/dist/svelte/components/TimeSummary.svelte +1 -1
  30. package/package.json +6 -6
@@ -0,0 +1,36 @@
1
+ import type { ServiceTimeEntry } from '../models/service-time-entry.js';
2
+ import { type DatedLabourCommercialInput, type DatedLabourRatePeriod } from './dated-labour-commercial-resolver.js';
3
+ import type { CommercialSnapshot, ServiceCommercialResolver } from './service-evidence-service.js';
4
+ /** Explicit percentage points, not hourly minor units or a decimal fraction. */
5
+ export interface LabourBurdenPercent {
6
+ id: string;
7
+ version: string;
8
+ /** Nonnegative plain decimal text, at most 18 fractional digits. */
9
+ percent: string;
10
+ }
11
+ /** Percentage burden applied to the selected wage, without hourly rounding. */
12
+ export interface DatedPercentageLabourRatePeriod extends Omit<DatedLabourRatePeriod, 'burden'> {
13
+ burdenPercent: LabourBurdenPercent;
14
+ }
15
+ /** Host-authorized immutable terms; host owns policy selection and input precision. */
16
+ export interface DatedPercentageLabourCommercialInput extends Omit<DatedLabourCommercialInput, 'schedule'> {
17
+ schedule: readonly DatedPercentageLabourRatePeriod[];
18
+ }
19
+ /**
20
+ * Opt-in percentage calculation. Existing additive resolver semantics are unchanged.
21
+ * Copy and retain this same input for incomplete approval retries. Provider amount
22
+ * is wage only; all burden provenance stays in the private compensation snapshot.
23
+ */
24
+ export declare class DatedPercentageLabourCommercialResolver implements ServiceCommercialResolver {
25
+ private readonly delegate;
26
+ private readonly selected;
27
+ constructor(input: DatedPercentageLabourCommercialInput);
28
+ private burden;
29
+ /** Validate all private amounts before any approval mutation. */
30
+ validateEntry(entry: ServiceTimeEntry): void;
31
+ /** Customer terms remain the original additive resolver's public allowlist. */
32
+ priceClient(entry: ServiceTimeEntry): Promise<CommercialSnapshot>;
33
+ /** Exact derived hourly rational is provenance, never an intermediate rounded rate. */
34
+ compensateProvider(entry: ServiceTimeEntry): Promise<CommercialSnapshot>;
35
+ }
36
+ //# sourceMappingURL=dated-percentage-labour-commercial-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dated-percentage-labour-commercial-resolver.d.ts","sourceRoot":"","sources":["../../src/services/dated-percentage-labour-commercial-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACL,KAAK,0BAA0B,EAE/B,KAAK,qBAAqB,EAC3B,MAAM,uCAAuC,CAAC;AAS/C,OAAO,KAAK,EACV,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,+BAA+B,CAAC;AAEvC,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,+BACf,SAAQ,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC;IAC7C,aAAa,EAAE,mBAAmB,CAAC;CACpC;AAED,uFAAuF;AACvF,MAAM,WAAW,oCACf,SAAQ,IAAI,CAAC,0BAA0B,EAAE,UAAU,CAAC;IACpD,QAAQ,EAAE,SAAS,+BAA+B,EAAE,CAAC;CACtD;AAED;;;;GAIG;AACH,qBAAa,uCACX,YAAW,yBAAyB;IAEpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;gBAE/C,KAAK,EAAE,oCAAoC;IA+CvD,OAAO,CAAC,MAAM;IAuBd,iEAAiE;IACjE,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAI5C,+EAA+E;IACzE,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAKvE,uFAAuF;IACjF,kBAAkB,CACtB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,kBAAkB,CAAC;CAuB/B"}
@@ -1,3 +1,5 @@
1
1
  export * from './dated-labour-commercial-resolver.js';
2
+ export * from './dated-percentage-labour-commercial-resolver.js';
3
+ export * from './labour-valuation-reconciliation.js';
2
4
  export * from './service-evidence-service.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { DatedLabourRate } from './dated-labour-commercial-resolver.js';
2
+ export type Rational = {
3
+ numerator: bigint;
4
+ denominator: bigint;
5
+ };
6
+ export declare const MAX: bigint;
7
+ export declare function decimal(value: string, label: string): Rational;
8
+ export declare function date(value: string): void;
9
+ export declare function identity(value: string, label: string): void;
10
+ export declare function rate(value: DatedLabourRate): DatedLabourRate;
11
+ export declare function amount(hours: Rational, hourly: DatedLabourRate): number;
12
+ /** Exact arithmetic only; this internal module does not select host policy. */
13
+ export declare function multiply(a: Rational, b: Rational): Rational;
14
+ export declare function add(a: Rational, b: Rational): Rational;
15
+ export declare function rounded(value: Rational): number;
16
+ export declare function quantity(value: unknown): Rational;
17
+ //# sourceMappingURL=labour-math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labour-math.d.ts","sourceRoot":"","sources":["../../src/services/labour-math.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAE7E,MAAM,MAAM,QAAQ,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,eAAO,MAAM,GAAG,QAAkC,CAAC;AAEnD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAa9D;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAaxC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAG3D;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe,CAO5D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAMvE;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAK3D;AACD,wBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAWtD;AACD,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAM/C;AACD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAejD"}
@@ -0,0 +1,59 @@
1
+ import type { CommercialSnapshot } from './service-evidence-service.js';
2
+ /** Immutable host provenance. Digest equality detects conflicting supplied revisions, not authenticity. */
3
+ export interface LabourPolicyProvenance {
4
+ id: string;
5
+ version: string;
6
+ digest: string;
7
+ }
8
+ /** Private approved compensation evidence, already authorized and selected by the host. */
9
+ export interface ApprovedLabourValuationEvidence {
10
+ tenantId: string;
11
+ participantProfileId: string;
12
+ entryId: string;
13
+ snapshotId: string;
14
+ groupId: string;
15
+ groupVersion: string;
16
+ policy: LabourPolicyProvenance;
17
+ snapshot: CommercialSnapshot & {
18
+ id: string;
19
+ tenantId: string;
20
+ timeEntryId: string;
21
+ };
22
+ }
23
+ /** Explicit analytical scope; membership is supplied evidence, never a database or authorization query. */
24
+ export interface LabourValuationReconciliationInput {
25
+ tenantId: string;
26
+ currency: string;
27
+ groupId: string;
28
+ groupVersion: string;
29
+ mode: 'half-up-exact-loaded-aggregate';
30
+ evidence: readonly ApprovedLabourValuationEvidence[];
31
+ }
32
+ /** Private analytical result. No returned amount is a posting instruction. */
33
+ export interface LabourValuationReconciliation {
34
+ tenantId: string;
35
+ currency: string;
36
+ groupId: string;
37
+ groupVersion: string;
38
+ mode: 'half-up-exact-loaded-aggregate';
39
+ version: 'labour-valuation-reconciliation-v1';
40
+ canonicalCostMinor: number;
41
+ analyticalCostMinor: number;
42
+ /** Analytical minus canonical; may be negative although evidence cannot be. */
43
+ differenceMinor: number;
44
+ evidence: Array<{
45
+ entryId: string;
46
+ snapshotId: string;
47
+ participantProfileId: string;
48
+ policy: LabourPolicyProvenance;
49
+ calculationVersion: string;
50
+ }>;
51
+ }
52
+ /**
53
+ * Reconcile immutable private evidence; never reprice or mutate posted facts.
54
+ * The host must authorize every entry and exclude superseded/corrected evidence.
55
+ * IDs/digests validate consistency of supplied data, not authenticity or access.
56
+ * Reversals and mixed-sign evidence are unsupported; apply their own versioned contract.
57
+ */
58
+ export declare function reconcileLabourValuation(input: LabourValuationReconciliationInput): LabourValuationReconciliation;
59
+ //# sourceMappingURL=labour-valuation-reconciliation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labour-valuation-reconciliation.d.ts","sourceRoot":"","sources":["../../src/services/labour-valuation-reconciliation.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE,2GAA2G;AAC3G,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2FAA2F;AAC3F,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,QAAQ,EAAE,kBAAkB,GAAG;QAC7B,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,2GAA2G;AAC3G,MAAM,WAAW,kCAAkC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,gCAAgC,CAAC;IACvC,QAAQ,EAAE,SAAS,+BAA+B,EAAE,CAAC;CACtD;AAED,8EAA8E;AAC9E,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,gCAAgC,CAAC;IACvC,OAAO,EAAE,oCAAoC,CAAC;IAC9C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,MAAM,EAAE,sBAAsB,CAAC;QAC/B,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC,CAAC;CACJ;AA8FD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,kCAAkC,GACxC,6BAA6B,CAwG/B"}
@@ -3,12 +3,12 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-timesheets",
6
- "packageVersion": "0.55.21",
6
+ "packageVersion": "0.55.22",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "b6e435a45a87cc143f5afc5074bddd54ec0aa80bf4310bb60b156f59af99a503",
11
- "packageJson": "40541d1ef0ea45cc26620bbe6c8ba0ac3ad6ff3ca48c203c2854e00fa6708604",
10
+ "manifest": "0ddbb2c305ad88379ad8291cc6d77e7a45e839d44f6b768d067dc010e2d23c22",
11
+ "packageJson": "65784b169459001f6152e67591ee369e987c6a2f317613b253257a8c55e12f1f",
12
12
  "agents": "46a4e8437424b494645e90ce4a4869be04956c5da6a42f89697cbd3ab2199a7e",
13
13
  "moduleDoc:agents/period-rollup.md": "5fb741659d81dbef2e4850c10c2d65f09e3f5a83e8a88e2e0f19585f25158a6a"
14
14
  },
@@ -192,7 +192,7 @@ function formatAmount(amount: number, currency = 'USD'): string {
192
192
  flex-direction: column;
193
193
  gap: 0.375rem;
194
194
  padding: 0.5rem 0.25rem;
195
- border-bottom: 1px solid var(--smrt-color-outline-variant, transparent);
195
+ border-bottom: var(--smrt-hairline);
196
196
  }
197
197
 
198
198
  .time-approval-row:last-child {
@@ -173,14 +173,14 @@ function handleKeydown(event: KeyboardEvent) {
173
173
  display: flex;
174
174
  align-items: stretch;
175
175
  background: var(--smrt-color-surface);
176
- border: 1px solid var(--smrt-color-outline-variant);
176
+ border: var(--smrt-hairline);
177
177
  border-radius: var(--smrt-radius-medium);
178
178
  overflow: hidden;
179
179
  transition: all 0.2s var(--smrt-easing-standard);
180
180
  }
181
181
 
182
182
  .time-entry-card:hover {
183
- border-color: var(--smrt-color-outline);
183
+ border-color: var(--smrt-hairline-strong-color);
184
184
  }
185
185
 
186
186
  .time-entry-card.selected {
@@ -201,7 +201,7 @@ function handleKeydown(event: KeyboardEvent) {
201
201
  align-items: center;
202
202
  padding: 1rem;
203
203
  background: var(--smrt-color-surface-container-low);
204
- border-right: 1px solid var(--smrt-color-outline-variant);
204
+ border-right: var(--smrt-hairline);
205
205
  }
206
206
 
207
207
  .checkbox-wrapper input[type='checkbox'] {
@@ -310,7 +310,7 @@ function handleKeydown(event: KeyboardEvent) {
310
310
  display: flex;
311
311
  align-items: center;
312
312
  padding: 0.5rem;
313
- border-left: 1px solid var(--smrt-color-outline-variant);
313
+ border-left: var(--smrt-hairline);
314
314
  }
315
315
  }
316
316
  </style>
@@ -200,7 +200,7 @@ function getEntryHref(entry: TimeEntry): string | undefined {
200
200
  background: var(--smrt-color-surface);
201
201
  border-radius: var(--smrt-radius-large);
202
202
  overflow: hidden;
203
- border: 1px solid var(--smrt-color-outline-variant);
203
+ border: var(--smrt-hairline);
204
204
  }
205
205
 
206
206
  .list-header {
@@ -209,7 +209,7 @@ function getEntryHref(entry: TimeEntry): string | undefined {
209
209
  align-items: center;
210
210
  padding: 0.75rem 1rem;
211
211
  background: var(--smrt-color-surface-container-low);
212
- border-bottom: 1px solid var(--smrt-color-outline-variant);
212
+ border-bottom: var(--smrt-hairline);
213
213
  }
214
214
 
215
215
  .select-all {
@@ -241,7 +241,7 @@ function getEntryHref(entry: TimeEntry): string | undefined {
241
241
  .entry-row {
242
242
  display: flex;
243
243
  align-items: center;
244
- border-bottom: 1px solid var(--smrt-color-outline-variant);
244
+ border-bottom: var(--smrt-hairline);
245
245
  transition: background 0.15s var(--smrt-easing-standard);
246
246
  }
247
247
 
@@ -112,7 +112,7 @@ const { t } = useI18n();
112
112
 
113
113
  .summary-card {
114
114
  background: var(--smrt-color-surface);
115
- border: 1px solid var(--smrt-color-outline-variant);
115
+ border: var(--smrt-hairline);
116
116
  border-radius: var(--smrt-radius-medium);
117
117
  padding: 1rem;
118
118
  display: flex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-timesheets",
3
- "version": "0.55.21",
3
+ "version": "0.55.22",
4
4
  "smrtJsdoc": "strict",
5
5
  "description": "Shared time entries for the SMRT framework: who worked how long on what, approval and correction, with immutable charge and compensation snapshots",
6
6
  "type": "module",
@@ -39,10 +39,10 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "@happyvertical/smrt-core": "0.55.21",
43
- "@happyvertical/smrt-tenancy": "0.55.21",
44
- "@happyvertical/smrt-types": "0.55.21",
45
- "@happyvertical/smrt-ui": "0.55.21",
42
+ "@happyvertical/smrt-core": "0.55.22",
43
+ "@happyvertical/smrt-tenancy": "0.55.22",
44
+ "@happyvertical/smrt-types": "0.55.22",
45
+ "@happyvertical/smrt-ui": "0.55.22",
46
46
  "@happyvertical/sql": "^0.103.5"
47
47
  },
48
48
  "peerDependencies": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  },
56
56
  "devDependencies": {
57
- "@happyvertical/smrt-vitest": "0.55.21",
57
+ "@happyvertical/smrt-vitest": "0.55.22",
58
58
  "@sveltejs/package": "^2.5.8",
59
59
  "@sveltejs/vite-plugin-svelte": "^7.3.0",
60
60
  "@types/node": "24.13.6",