Scope Atomic table rows by table parent and class instead of Store-wide class membership #51

Closed
opened 2026-10-19 11:19:57 +02:00 by michielbdejong · 0 comments

Problem

The shared React table needs backend-specific collection membership. AtomicTable currently treats all loaded Resources of a Class in an Atomic Store as one table. A Store is a broader resource cache/client context, not a document or table boundary: it can contain rows from several tables using the same Class.

In shared/atomic/atomicTable.ts (verified on main at be8938078d97a70519a991ade8b9207d07067c5f):

  • The constructor accepts store and classId, with no table/parent identity.
  • records() scans store.resources and filters only with resource.hasClasses(this.classId).
  • create() sets isA but does not set https://atomicdata.dev/properties/parent.
  • save() rechecks class membership, but has no parent-membership check.

This mixes same-class rows from different Atomic tables and creates rows with no table membership.

Expected membership semantics

NextGraph: the selected RDF graph is the document boundary. Any subject in that graph with the selected class belongs in the table. Do not introduce an Atomic parent/table-ownership requirement into the NextGraph path.

Atomic: select an actual table resource and its row Class, using Atomic's existing Table/collection conventions. Rows belong to that table through parent and must also have the selected Class. The Atomic table documentation explicitly describes rows as sharing the same parent and class. Confirm the existing table-resource-to-row-Class metadata when implementing; do not invent a new ontology for this adapter. Parent membership should not be described as an independent permission grant.

Reproduction

  1. Load two Atomic tables A and B that use the same row Class into one Store.
  2. Load row a with that Class and parent A, row b with that Class and parent B, and a same-class row without a parent.
  3. Open A through the current AtomicTable(store, classId).
  4. All three loaded rows appear; creating another row assigns the Class but no parent.

Requested change and acceptance

  • Give the Atomic adapter explicit table/collection identity in addition to schema identity. Use the existing Atomic Table resource and parent convention.
  • Select rows by both Class and the selected table parent. Exclude same-class rows with a different or absent parent, and wrong-class rows under the selected parent.
  • Set the selected table as parent on newly created rows and preserve that membership during ordinary field edits.
  • Recheck membership before saving a stale row. If it was deleted, reclassified or reparented externally, show a useful error and retain the draft rather than saving through a stale table view.
  • React to membership changes: rows arriving, leaving or being reparented must update the displayed collection. Per-record subscriptions alone do not discover new members.
  • Keep collection selection and fetching behind the host/adapter boundary; SchemaTable should continue to consume columns, row values and save callbacks without depending on graph or Atomic parent.
  • Update /atomic-reuse to demonstrate two tables sharing one Class in one Store, including correctly parented creation and external membership changes.
  • Add tests for those cases and retain the NextGraph graph-plus-class behavior.

Scanning the currently loaded Store cache also does not establish a complete server collection. The actual Atomic backend should use the existing collection query/paging mechanism rather than interpreting cache contents as all rows; coordinate that transport work with #45.

Related: #43 (shared table/Atomic reuse), #45 (actual Atomic backend).

## Problem The shared React table needs backend-specific collection membership. `AtomicTable` currently treats all loaded Resources of a Class in an Atomic Store as one table. A Store is a broader resource cache/client context, not a document or table boundary: it can contain rows from several tables using the same Class. In `shared/atomic/atomicTable.ts` (verified on main at `be8938078d97a70519a991ade8b9207d07067c5f`): - The constructor accepts `store` and `classId`, with no table/parent identity. - `records()` scans `store.resources` and filters only with `resource.hasClasses(this.classId)`. - `create()` sets `isA` but does not set `https://atomicdata.dev/properties/parent`. - `save()` rechecks class membership, but has no parent-membership check. This mixes same-class rows from different Atomic tables and creates rows with no table membership. ## Expected membership semantics **NextGraph:** the selected RDF graph is the document boundary. Any subject in that graph with the selected class belongs in the table. Do not introduce an Atomic parent/table-ownership requirement into the NextGraph path. **Atomic:** select an actual table resource and its row Class, using Atomic's existing Table/collection conventions. Rows belong to that table through `parent` and must also have the selected Class. The [Atomic table documentation](https://docs.atomicdata.dev/atomicserver/gui/tables) explicitly describes rows as sharing the same parent and class. Confirm the existing table-resource-to-row-Class metadata when implementing; do not invent a new ontology for this adapter. Parent membership should not be described as an independent permission grant. ## Reproduction 1. Load two Atomic tables A and B that use the same row Class into one Store. 2. Load row a with that Class and parent A, row b with that Class and parent B, and a same-class row without a parent. 3. Open A through the current `AtomicTable(store, classId)`. 4. All three loaded rows appear; creating another row assigns the Class but no parent. ## Requested change and acceptance - Give the Atomic adapter explicit table/collection identity in addition to schema identity. Use the existing Atomic Table resource and parent convention. - Select rows by both Class and the selected table parent. Exclude same-class rows with a different or absent parent, and wrong-class rows under the selected parent. - Set the selected table as `parent` on newly created rows and preserve that membership during ordinary field edits. - Recheck membership before saving a stale row. If it was deleted, reclassified or reparented externally, show a useful error and retain the draft rather than saving through a stale table view. - React to membership changes: rows arriving, leaving or being reparented must update the displayed collection. Per-record subscriptions alone do not discover new members. - Keep collection selection and fetching behind the host/adapter boundary; `SchemaTable` should continue to consume columns, row values and save callbacks without depending on `graph` or Atomic `parent`. - Update `/atomic-reuse` to demonstrate two tables sharing one Class in one Store, including correctly parented creation and external membership changes. - Add tests for those cases and retain the NextGraph graph-plus-class behavior. Scanning the currently loaded Store cache also does not establish a complete server collection. The actual Atomic backend should use the existing collection query/paging mechanism rather than interpreting cache contents as all rows; coordinate that transport work with #45. Related: #43 (shared table/Atomic reuse), #45 (actual Atomic backend).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ELFA/database-apps#51
No description provided.