Skip to content

Time tracker and Issue Tracker templates: make shared-class rows #2152

Open

Description

@michielbdejong

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 its work-project/work-person classes are minted per drive by timeTrackingSchema(). 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's allowsOnly (createColumnOnClass, createTableFromSpec.ts:291-336). These are exactly the values issue-v1 uses.

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

  1. Row class. When time-tracker or issue-tracker is instantiated, use the shared class as the table's classtype instead of calling createRowClass. That means <base>/classes/time-entry-v1 and <base>/classes/issue-v1. Other templates are unchanged.

  2. Columns are the shared properties.

    • Time tracker:
      • Start, End and Billable bind <base>/properties/work-start, work-end and work-billable.
      • Project and Person bind work-project and work-person, with targetClass set to work-project-v1 and work-person-v1.
      • The template's schema: timeTrackingSchema() goes. work-source-id is provider bookkeeping and is not part of the shared class.
    • Issue Tracker: keep Description (body), Status and Assignee as they are. They already use task/v1.
  3. 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.

  4. The Issue Tracker's Priority column. issue-v1 has no priority. A published class can't gain one: changing its fields would mean a new issue-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-v2 in 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.

  5. 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>/v1 and resolve the subjects at runtime.

    Terms are fetched once on first use and kept, as for any external term (recommends value of Property get erased for some reason #177 spike S1).

  6. Gate. The base is still ontola.github.io, which is temporary. atomic-plugins keeps every catalog entry that uses it enabled: false until the stable domain is in base.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.

  1. Offer. Show "Upgrade to shared class" on a table whose classtype came from the time-tracker or issue-tracker template.
    • Detection: the table records the template id it was made from, or failing that, its row class is a createRowClass class 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.
  2. Copy. Create a new table with the shared classtype. For each row, create a new row with isA the shared class and the properties mapped:
    • Issue Tracker:
      • name, body, status and assignee copy 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-project and work-person point at are copied first into work-project-v1 and work-person-v1 tables, and the links are rewritten through an identity map from old row to new row.
      • work-source-id stays on the copy as an extra property, so provider imports don't duplicate rows.
  3. Keep the originals. The old table, rows and class stay untouched and readable. Optionally mark the old table "migrated to ".
  4. 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.

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 isA and 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 classtype time-entry-v1, its columns are the shared work-* properties, and Project and Person pick work-project-v1 and work-person-v1 rows. A new Issue Tracker table has classtype issue-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-v1 or issue-v1 is 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

  1. michielbdejong commented on Oct 12, 2026

    @michielbdejong
    ContributorAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions