@happyvertical/smrt-timesheets 0.55.7 → 0.55.9
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.
- package/dist/attendance.js +2 -2
- package/dist/chunks/{attendance-BoT5NUWk.js → attendance-WGazMNoX.js} +3 -3
- package/dist/chunks/{attendance-BoT5NUWk.js.map → attendance-WGazMNoX.js.map} +1 -1
- package/dist/chunks/{models-BO5bsZHw.js → models-BUY_DX-t.js} +2 -2
- package/dist/chunks/{models-BO5bsZHw.js.map → models-BUY_DX-t.js.map} +1 -1
- package/dist/chunks/{rollup-BUbDKkHe.js → rollup-CDEujV25.js} +3 -3
- package/dist/chunks/{rollup-BUbDKkHe.js.map → rollup-CDEujV25.js.map} +1 -1
- package/dist/chunks/{service-time-entry-BgvjPHTB.js → service-time-entry-CyOH_lNy.js} +2 -2
- package/dist/chunks/{service-time-entry-BgvjPHTB.js.map → service-time-entry-CyOH_lNy.js.map} +1 -1
- package/dist/index.js +3 -3
- package/dist/manifest.json +11 -1
- package/dist/rollup.js +1 -1
- package/dist/smrt-knowledge.json +14 -4
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as validateDurationHours, i as ServiceTimeEntryCollection, n as SERVICE_TIME_ENTRY_FROZEN_FIELDS, r as ServiceTimeEntry, t as SERVICE_DURATION_HOURS_EVIDENCE } from "./chunks/service-time-entry-
|
|
2
|
-
import { a as AttendanceReplay, i as AttendancePunchCollection, n as AttendanceBreakCollection, o as AttendanceReplayCollection, r as AttendancePunch, t as AttendanceBreak } from "./chunks/models-
|
|
1
|
+
import { a as validateDurationHours, i as ServiceTimeEntryCollection, n as SERVICE_TIME_ENTRY_FROZEN_FIELDS, r as ServiceTimeEntry, t as SERVICE_DURATION_HOURS_EVIDENCE } from "./chunks/service-time-entry-CyOH_lNy.js";
|
|
2
|
+
import { a as AttendanceReplay, i as AttendancePunchCollection, n as AttendanceBreakCollection, o as AttendanceReplayCollection, r as AttendancePunch, t as AttendanceBreak } from "./chunks/models-BUY_DX-t.js";
|
|
3
3
|
import { SERVICE_TIME_ENTRY_STATUS_TRANSITIONS } from "./types.js";
|
|
4
4
|
import { AttendanceConflict, AttendanceService } from "./attendance.js";
|
|
5
|
-
import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-
|
|
5
|
+
import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-CDEujV25.js";
|
|
6
6
|
import { TIMESHEETS_MODULE_META, TIMESHEETS_UI_SLOTS } from "./ui.js";
|
|
7
7
|
import { SmrtCollection, SmrtObject, ValidationError, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
8
8
|
import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
|
package/dist/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"timestamp": 0,
|
|
4
4
|
"packageName": "@happyvertical/smrt-timesheets",
|
|
5
|
-
"packageVersion": "0.55.
|
|
5
|
+
"packageVersion": "0.55.9",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-timesheets:AttendancePunch": {
|
|
8
8
|
"name": "attendancepunch",
|
|
@@ -3363,5 +3363,15 @@
|
|
|
3363
3363
|
"@happyvertical/smrt-core",
|
|
3364
3364
|
"@happyvertical/smrt-tenancy"
|
|
3365
3365
|
],
|
|
3366
|
+
"browser": {
|
|
3367
|
+
"status": "server-only",
|
|
3368
|
+
"issues": [
|
|
3369
|
+
"#3624"
|
|
3370
|
+
],
|
|
3371
|
+
"reason": "node:crypto",
|
|
3372
|
+
"via": [
|
|
3373
|
+
"@happyvertical/smrt-tenancy"
|
|
3374
|
+
]
|
|
3375
|
+
},
|
|
3366
3376
|
"stampsConstructors": true
|
|
3367
3377
|
}
|
package/dist/rollup.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-
|
|
1
|
+
import { a as PeriodTimecard, c as TimecardAdjustmentCollection, o as PeriodTimecardCollection, s as TimecardAdjustment, t as PeriodRollupService } from "./chunks/rollup-CDEujV25.js";
|
|
2
2
|
export { PeriodRollupService, PeriodTimecard, PeriodTimecardCollection, TimecardAdjustment, TimecardAdjustmentCollection };
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -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.
|
|
6
|
+
"packageVersion": "0.55.9",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "b3ca503a3cc91c8b9e4b8cb75b679c5f764d3ccd0114c151c1b6814add51e0b5",
|
|
11
|
+
"packageJson": "1c17f42e91d724b1573f006607243258b138c9adaee77db8718c2a60c629dc54",
|
|
12
12
|
"agents": "46a4e8437424b494645e90ce4a4869be04956c5da6a42f89697cbd3ab2199a7e",
|
|
13
13
|
"moduleDoc:agents/period-rollup.md": "5fb741659d81dbef2e4850c10c2d65f09e3f5a83e8a88e2e0f19585f25158a6a"
|
|
14
14
|
},
|
|
@@ -1937,5 +1937,15 @@
|
|
|
1937
1937
|
"module": "period-rollup",
|
|
1938
1938
|
"content": "# Period timecards\n\n`@happyvertical/smrt-timesheets/rollup` exports `PeriodRollupService`,\n`PeriodTimecard`, `TimecardAdjustment`, their collections, and resolver types.\nThe package root also exports them. SQLite and PostgreSQL are supported.\nCreate application tables through normal migrations; neither service provisions\nschema. The attendance option additionally requires the attendance tables.\n\nConstruct a service only after authenticating and authorizing its trusted\n`{ tenantId, profileId }` scope. A conflicting ambient tenant is rejected.\n`options.actorProfileId` records a separately authorized supervisor; it defaults\nto the subject profile for self confirmation/correction. Never accept this\ntrusted scope or attribution unchecked from request input. Profile authorization\nis consumer-owned; the service filters every source/card/adjustment read by its\ntrusted subject and tenant. Generic API, CLI and MCP surfaces are closed by\ndefault; consumer registry overrides may further restrict them (#3318).\n\n## Resolver contract\n\n`periodFor(at, actor)` supplies half-open UTC `startsAt`/`endsAt`, an IANA\n`timezone`, a nonempty policy `version`, and a JSON `rules` snapshot.\nThe consumer owns period length, calendar start day, timezone and DST, overtime\nthresholds, holidays and classification. The requested instant must be inside\nthe window. Overlapping windows for existing cards are rejected: introduce a new\ncalendar at a boundary after existing windows, and use adjustments for already\nconfirmed periods.\n\n`classify(period, sources, actor)` returns nonnegative safe integer\n`regularSeconds` and `overtimeSeconds`, whose sum must equal source seconds.\nInputs are detached so resolver mutation cannot rewrite evidence. Resolver\nexceptions, malformed windows, invalid timezone, fractional/unsafe totals and\nnonconserving classification abort the transaction. No Alberta or other\njurisdiction rule is assumed, and no pay rate or money is stored.\n\nA configurable UTC calendar example (illustrative policy, not payroll advice):\n\n```ts\nimport { PeriodRollupService, type PeriodRulesResolver } from\n '@happyvertical/smrt-timesheets/rollup';\n\nconst settings = {\n lengthDays: 14, startDay: 1, timezone: 'UTC', // 0 = Sunday\n anchor: '2026-01-05T00:00:00Z', // aligned Monday; anchors fortnight phase\n thresholdSeconds: 80 * 3600,\n holidays: ['2026-12-25'],\n};\nconst resolver: PeriodRulesResolver = {\n async periodFor(at) {\n const anchor = new Date(settings.anchor);\n if (anchor.getUTCDay() !== settings.startDay || settings.timezone !== 'UTC')\n throw new Error('Use a timezone-aware calendar resolver for local periods');\n const length = settings.lengthDays * 86400000;\n const start = anchor.getTime() +\n Math.floor((at.getTime() - anchor.getTime()) / length) * length;\n return {\n startsAt: new Date(start), endsAt: new Date(start + length),\n timezone: settings.timezone, version: 'shop-policy-v1', rules: settings,\n };\n },\n async classify(period, sources) {\n const rules = period.rules as typeof settings;\n // This example assigns a contribution to its clipped start's UTC date.\n // Local daily rules should split contributions at their own local midnight.\n let regular = 0;\n let holiday = 0;\n for (const source of sources) {\n if (rules.holidays.includes(source.startsAt.slice(0, 10))) holiday += source.seconds;\n else regular += source.seconds;\n }\n return {\n regularSeconds: Math.min(regular, rules.thresholdSeconds),\n overtimeSeconds: holiday + Math.max(0, regular - rules.thresholdSeconds),\n };\n },\n};\nconst rollups = new PeriodRollupService(db, authorizedSubject, resolver,\n { attendance: true, actorProfileId: authenticatedSupervisorProfileId });\nconst card = await rollups.rollup(new Date());\nawait rollups.confirm(card.id!);\nawait rollups.adjust(card.id!, {\n operationId: requestId, regularSeconds: 900, overtimeSeconds: 0,\n reason: 'Approved correction after confirmation',\n});\nconst effectiveSeconds = await rollups.totals(card.id!);\n```\n\nA timezone-aware resolver must compute each local boundary separately: a local\nday crossing DST is not necessarily 86400 seconds. Resolvers can use an app's\nexisting calendar library; no new timezone dependency or implicit default is\nintroduced here.\n\n## Evidence and immutability\n\nDecimal-hours-only entries have no measured integer seconds. The seconds-only\nrollup rejects these sources explicitly when their approval instant falls in the\nrequested period; it never rounds them or counts null as\nzero. Use an hours-aware consumer policy for that source representation.\n\nOnly approved human `ServiceTimeEntry` rows for the subject count; corrected\nancestors do not. Correction chains must remain within that subject/tenant and\npoint to corrected parents. Multiple approved descendants of one root are\nrejected as ambiguous rather than double-counted. Entries with both `startedAt`\nand `endedAt` allocate their declared seconds\nproportionally across the period using exact integer prefix division, preserving\nseconds over adjacent periods. Unbounded entries count at `startedAt`, or, when\nabsent, `approvedAt`; an end-only timestamp does not create an interval. Missing\nboth attribution timestamps is an error. This is time attribution, not a\nclaim that a manual entry has a continuous wall-clock duration.\n\nWith `attendance: true`, closed punches without `reviewRequired` count, excluding\nunpaid breaks and retaining paid breaks. Open/review-required punches do not\ncount. Linked attendance is authoritative: its evidence entry and any approved\ncorrection descendants are excluded, including when the punch is still under\nreview or outside the requested period. Unlinked approved work entries and\nattendance both count; consumers must link overlapping evidence explicitly.\nSource snapshots preserve each paid attendance segment and entry identity.\n\nRepeated rollup updates one open card per tenant/person/start; a confirmed card\ncannot be recomputed. Confirmation is attributed and idempotent. Model save,\ncollection create/update/upsert and object/collection delete cannot bypass the\nservice. Model mutation capabilities are per-instance and not exported.\nDirect SQL is a trusted administrative boundary, not an exposed application API.\nProfile/card foreign keys restrict deletion to preserve history.\n\nAdjustments contain signed integer regular/overtime deltas, reason, operation\nkey and actor attribution. A retry reuses its row only for the exact same\npayload and actor. Effective totals may never become negative or unsafe.\nAdjustments never alter the confirmed row or source snapshot. Undo an adjustment\nwith a separately attributed compensating adjustment, never deletion.\n\nAll service mutations use a root transaction, transaction-bound collections,\nembedded writer serialization or a PostgreSQL tenant/person advisory lock.\nOutputs are reloaded on the root executor after commit. Rollup reads are an\napplication snapshot: subsequent source approvals/corrections appear on the\nnext open rollup, and confirmed cards require explicit adjustments.\n"
|
|
1939
1939
|
}
|
|
1940
|
-
]
|
|
1940
|
+
],
|
|
1941
|
+
"browser": {
|
|
1942
|
+
"status": "server-only",
|
|
1943
|
+
"issues": [
|
|
1944
|
+
"#3624"
|
|
1945
|
+
],
|
|
1946
|
+
"reason": "node:crypto",
|
|
1947
|
+
"via": [
|
|
1948
|
+
"@happyvertical/smrt-tenancy"
|
|
1949
|
+
]
|
|
1950
|
+
}
|
|
1941
1951
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-timesheets",
|
|
3
|
-
"version": "0.55.
|
|
3
|
+
"version": "0.55.9",
|
|
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,11 +39,11 @@
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@happyvertical/smrt-core": "0.55.
|
|
43
|
-
"@happyvertical/smrt-tenancy": "0.55.
|
|
44
|
-
"@happyvertical/smrt-types": "0.55.
|
|
45
|
-
"@happyvertical/smrt-ui": "0.55.
|
|
46
|
-
"@happyvertical/sql": "^0.
|
|
42
|
+
"@happyvertical/smrt-core": "0.55.9",
|
|
43
|
+
"@happyvertical/smrt-tenancy": "0.55.9",
|
|
44
|
+
"@happyvertical/smrt-types": "0.55.9",
|
|
45
|
+
"@happyvertical/smrt-ui": "0.55.9",
|
|
46
|
+
"@happyvertical/sql": "^0.103.1"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"svelte": "^5.57.0"
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@happyvertical/smrt-vitest": "0.55.
|
|
57
|
+
"@happyvertical/smrt-vitest": "0.55.9",
|
|
58
58
|
"@sveltejs/package": "^2.5.8",
|
|
59
59
|
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
60
60
|
"@types/node": "24.13.6",
|