Skip to content

docs(openspec): deprecate booked hours in shillinq, lean on humaniq - #1447

Merged
rubenvdlinde merged 1 commit into
developmentfrom
feat/hours-to-humaniq
Sep 1, 2026
Merged

docs(openspec): deprecate booked hours in shillinq, lean on humaniq#1447
rubenvdlinde merged 1 commit into
developmentfrom
feat/hours-to-humaniq

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

A change proposal, not an implementation. It scopes retiring UrenRegistratie as the place hours are booked against a domain object.

Why

ADR-107 decision 6 is explicit:

Effort is recorded against the domain object and costed by hrmq. Hours logged on a case are hrmq time entries carrying the case reference.

Shillinq ships the opposite. lib/Settings/register.d/uren-domain-subject-link.json adds subjectApp + subjectId to UrenRegistratie so a domain app can book hours against a case here, and its own _meta cites the same ADR.

Both readings cite "ADR-081", a number two documents claimed until the 2026-08-26 renumbering, so the citation resolved to whichever the reader assumed. Read against ADR-107 as it now stands, decision 6 settles where an hour lives.

The investigation: there is nothing to migrate

Before designing a migration we checked what would have to migrate.

UrenRegistratie.subjectApp has no writer. A fleet-wide grep finds the field in exactly three places: the overlay that declares it, a shillinq test asserting the declaration, and one consumer.

That consumer is a dossiq KPI, and it can only ever read zero. Dossiq's case-kpis-hours tile sums UrenRegistratie.hours filtered on subjectApp: "dossiq". Nothing writes a matching row, so the tile has reported 0 hours on every case in every install since it shipped, and looked correct doing it.

Humaniq's side is unwired too. TimeEntry.domainObjectRef / domainObjectType are declared and nothing reads or writes them either.

So the fleet holds two competing designs for case hours and neither has ever carried a record. This is the same failure ADR-107 itself documents about procest's IV3 report: an aggregator reading a field almost nothing filled.

The design question this leaves

UrenRegistratie carries nine fields TimeEntry has no equivalent for — recognisedRate, glTransactionId, the four WBSO tagging fields, projectAssignmentId, costProjectId, utilizationPercent. Those are ledger and subsidy concerns, and ADR-107 decision 1 keeps them here. So the answer is not "copy them to humaniq". proposal.md states both open shapes and leaves the choice to design.md.

Risks the tasks are ordered around

The WBSO export guard and the urencriterium guard both feed a tax position, so they are last, behind a side-by-side proof against the same period. A wrong 1225-hour count costs a self-employed person a real deduction; "the tests pass" is not the bar.

Caveat

We checked the source tree, not a production database. Task 2 adds an occ count of rows with a non-null subjectApp and blocks on it being zero.

Related: dossiq#1608 repoints the hours tile at humaniq, and humaniq#279 corrects the domainObjectType example.

🤖 Generated with Claude Code

ADR-107 decision 6 puts hours logged on a case in humaniq, not here. Shillinq
ships the opposite in uren-domain-subject-link.json, which adds subjectApp and
subjectId to UrenRegistratie so a domain app can book against a case in this
app. Both cite ADR-081, a number two documents claimed until the 2026-08-26
renumbering, so the citation resolved to whichever the reader assumed.

Neither arrangement has ever carried a record. A fleet-wide grep finds
subjectApp in three places: the overlay that declares it, a test asserting the
declaration, and dossiq's case-kpis-hours tile. Nothing writes it, so that tile
reports 0 hours on every case in every install. Humaniq's domainObjectRef is
equally unwired.

So there is nothing to migrate, and the work is to pick where the ledger and
WBSO fields live once the hour moves. The proposal states both shapes and
leaves the choice to design.md. Tasks order the consumers by blast radius and
put the two statutory readers last, behind a side-by-side proof: a wrong
1225-hour urencriterium count costs a real person a real deduction.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/shillinq @ fd358f7

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development
Hydra gates

Quality workflow — 2026-09-01 11:18 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit ae11c4b into development Sep 1, 2026
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant