Repository navigation
Time tracker and Issue Tracker templates: make shared-class rows #2152
Description
From the atomic-plugins devonian worker, 2026-10-08. Decided by Michiel: Decision Inbox Q-107 = shared-classes. Item 4 (Priority) is pending Michiel's answer to Q-108.
Context
atomic-plugins publishes shared row classes, so that one view or integration works on any table of that class (ontola/atomic-plugins#177). Two of them match the host's templates:
Template (tableTemplates.ts) |
Shared class | Its fields |
|---|---|---|
Time tracker (time-tracker) |
time-entry-v1 |
requires work-start; recommends name, work-end, work-project (→ work-project-v1), work-person (→ work-person-v1), work-billable |
Issue Tracker (issue-tracker) |
issue-v1 |
requires name; recommends task/v1 status, body, assignee, due-date |
The subjects are in atomic-plugins ontology-kit/terms.mjs, under https://ontola.github.io/atomic-plugins/ontology/. Published term files never change.
Today, at the pin a12b74a:
- Every template table gets its own row class from
createRowClass(createTableFromSpec.ts:262). - The Time tracker's
work-*properties and itswork-project/work-personclasses are minted per drive bytimeTrackingSchema(). Its own comment says "Shared within a drive until frozen schema package distribution lands". - The Issue Tracker already uses the embedded task/v1 properties. Its Status column binds
taskSchema.properties.status, so the Todo, Doing, Blocked and Done options resolve to the task/v1 tag subjects through the property'sallowsOnly(createColumnOnClass,createTableFromSpec.ts:291-336). These are exactly the valuesissue-v1uses.
So a template table never matches a shared-class view or integration exactly. A per-drive class cannot be named in a published lens catalog, so no lens can bridge the gap either. Q-107 settles it: the templates make shared-class rows.
Ask
-
Row class. When
time-trackerorissue-trackeris instantiated, use the shared class as the table'sclasstypeinstead of callingcreateRowClass. That means<base>/classes/time-entry-v1and<base>/classes/issue-v1. Other templates are unchanged. -
Columns are the shared properties.
- Time tracker:
- Start, End and Billable bind
<base>/properties/work-start,work-endandwork-billable. - Project and Person bind
work-projectandwork-person, withtargetClassset towork-project-v1andwork-person-v1. - The template's
schema: timeTrackingSchema()goes.work-source-idis provider bookkeeping and is not part of the shared class.
- Start, End and Billable bind
- Issue Tracker: keep Description (
body), Status and Assignee as they are. They already use task/v1.
- Time tracker:
-
Status options. No change needed: Todo, Doing, Blocked and Done already resolve to task/v1 tags through the embedded status property. Please keep it that way. A per-table select property would make the rows stop matching
issue-v1. -
The Issue Tracker's Priority column.
issue-v1has no priority. A published class can't gain one: changing its fields would mean a newissue-v2. Two options:- (a) Drop Priority from the template while it uses
issue-v1. Recommended for now. - (b) Michiel adds a shared priority property and
issue-v2in atomic-plugins first; the template then uses that.
This is Michiel's call (atomic-plugins side). Priority values already stored on old tables are covered by the migration below.
- (a) Drop Priority from the template while it uses
-
Where the host gets the subjects. atomic-server can't import atomic-plugins
terms.mjs. Either:- vendor a generated copy pinned to an ontology release (
v1), recommended; or - fetch
<base>/v1and resolve the subjects at runtime.
Terms are fetched once on first use and kept, as for any external term (
recommendsvalue of Property get erased for some reason #177 spike S1). - vendor a generated copy pinned to an ontology release (
-
Gate. The base is still
ontola.github.io, which is temporary. atomic-plugins keeps every catalog entry that uses itenabled: falseuntil the stable domain is inbase.json(ontology-kit/README.md, "Gate"), because a drive stores a term subject for good. The same applies here.- Ship the template change only once the stable ontology domain is in place, or behind a flag (for example the split-pieces flag) until then.
- Templates on production drives must not mint github.io subjects.
Migrating tables made from the old templates (proposal)
Feasible as a one-off copy migration, per table, opt-in, keeping the originals. It needs no lens, because the mapping is fixed and known.
- Offer. Show "Upgrade to shared class" on a table whose
classtypecame from thetime-trackerorissue-trackertemplate.- Detection: the table records the template id it was made from, or failing that, its row class is a
createRowClassclass and its columns bind the template's properties. - Before anything is written, show a preview: the number of rows and columns, and what won't carry over.
- Detection: the table records the template id it was made from, or failing that, its row class is a
- Copy. Create a new table with the shared
classtype. For each row, create a new row withisAthe shared class and the properties mapped:- Issue Tracker:
name,body,statusandassigneecopy unchanged; they are the same subjects.- Priority follows item 4: under (a) it is copied as an extra, non-column property, or reported as not carried over; under (b) it maps to the new shared property.
- Time tracker:
- Each per-drive
work-*property maps to the shared one with the same shortname. - The rows that
work-projectandwork-personpoint at are copied first intowork-project-v1andwork-person-v1tables, and the links are rewritten through an identity map from old row to new row. work-source-idstays on the copy as an extra property, so provider imports don't duplicate rows.
- Each per-drive
- Issue Tracker:
- Keep the originals. The old table, rows and class stay untouched and readable. Optionally mark the old table "migrated to ".
- Runner. Add frozen app schemas, JSON Schema interchange and typed collaboration APIs #2045 (draft) proposes "trusted native copy migrations with preview, source/version pins, resumable progress and retained originals". That is this shape. Browser migration orchestration is listed there as follow-up work.
- Until Add frozen app schemas, JSON Schema interchange and typed collaboration APIs #2045 lands, the same copy can run as a data-browser action. It is idempotent: an identity map stored on the new rows means a re-run skips rows already copied.
What migration does not do, and why:
- Links from elsewhere in the drive to old rows (another table's relation, a document mention) keep pointing at the originals. Rewriting them in place would modify resources outside the table and break "keep the originals".
- Edits made to the old table after the copy are not carried over. Concurrent old-version edits need explicit reconciliation, as Add frozen app schemas, JSON Schema interchange and typed collaboration APIs #2045 says.
- In-place retyping (changing
isAand properties on the existing rows) would avoid the copy and keep inbound links working, but it changes the originals and has no undo. I don't recommend it unless Michiel prefers it.
Not in this issue
- Lenses for these templates. With Q-107 none are needed or planned.
- Other templates (Project tasks, CRM, Reading list, …). They stay per-table until a shared class exists for them.
Done when
- A new Time tracker table has
classtypetime-entry-v1, its columns are the sharedwork-*properties, and Project and Person pickwork-project-v1andwork-person-v1rows. A new Issue Tracker table hasclasstypeissue-v1, and its Status options are the task/v1 tags. - With the change on (behind the flag or the stable domain), an atomic-plugins drive app that declares
time-entry-v1orissue-v1is offered on such a table by exact match (appsForClass). Its e2e reads and writes a row there: timesheets and issue-tracker already add themselves as a view of a hand-made shared-class table. - Migration:
- a unit test copies a fixture old Time tracker table (with project and person rows) and a fixture old Issue Tracker table into shared-class tables, with the originals unchanged;
- a second run copies nothing new;
- the preview lists what doesn't carry over.
- With the change off, templates behave exactly as today.
Filed by Claude (VPS coordinator) on Michiel's behalf. @joepio, for you and the Trekmeester.
Activity
michielbdejong commentedon Oct 12, 2026
Update on item 4 (Priority): Michiel decided (Decision Inbox Q-108) to drop Priority from the Issue Tracker template while it uses
issue-v1. Priority values on tables migrated from the old template stay on the copied rows as an extra, non-column property. Posted by Claude (VPS coordinator) on Michiel's behalf.