Skip to content

fix: encode dal.Key parent chain into record path (per-parent scoping)#2

Merged
trakhimenok merged 1 commit into
mainfrom
fix/encode-key-parent-chain
Jul 4, 2026
Merged

fix: encode dal.Key parent chain into record path (per-parent scoping)#2
trakhimenok merged 1 commit into
mainfrom
fix/encode-key-parent-chain

Conversation

@trakhimenok

Copy link
Copy Markdown
Contributor

Problem

dalgo2ingitdb4github (used by sneat-co/sneat-go PR #712) mapped a dalgo
dal.Key to an in-repo record path using only the leaf collection/{id},
dropping the key's parent chain. Two records under different parents that share
a leaf id collided:

  • spaces/family/contacts/c1spaces/contacts/$records/c1.yaml
  • spaces/work/contacts/c1spaces/contacts/$records/c1.yaml ← same file!

The second write clobbered the first — no per-space scoping.

Fix

Add resolveScopedCollection, which walks key.Parent() and interleaves each
ancestor record id with its subcollection name into the collection DirPath,
mirroring Firestore-style nesting:

  • spaces/family/contacts/c1spaces/family/contacts/$records/c1.yaml
  • spaces/work/contacts/c1spaces/work/contacts/$records/c1.yaml

This is the same Option A layout already shipped in
github.com/ingitdb/dalgo2ingitdb v0.1.0, so all three adapters agree on the
on-repo layout (write path == read path). Top-level keys are unchanged (flat
def.Collections lookup).

Get (previously inlined) and resolveCollection (Set/Insert/Delete + the
batching tx) now both route through the scoped resolver.

Tests

  • TestResolveScopedCollection_DistinctPathsForSameLeaf — same leaf id under
    different parents → distinct paths; top-level path unchanged.
  • TestResolveScopedCollection_DeepNesting / _Errors — grandchild path +
    error branches.
  • TestGitHubDB_NestedKeys_ScopedByParentRecord — end-to-end round-trip:
    write under two parents, read both back, no clobber.

go build ./..., go test ./..., go vet ./... all pass; coverage 99.5%.

🤖 Generated with Claude Code

The adapter mapped a dal.Key to an in-repo record path using only the leaf
collection + record id, dropping the key's parent chain. Two keys sharing a
leaf but living under different parents — e.g. spaces/family/contacts/c1 and
spaces/work/contacts/c1 — resolved to the same path and clobbered each other
(no per-space scoping).

Add resolveScopedCollection, which walks key.Parent() and interleaves each
ancestor record id with its subcollection name into the DirPath, mirroring
Firestore-style nesting (spaces/<spaceID>/contacts/...). This matches the
Option A layout already shipped in github.com/ingitdb/dalgo2ingitdb v0.1.0, so
the write and read paths agree with the sibling adapters. Top-level (non-nested)
keys are unchanged: a plain flat def.Collections lookup.

Route both resolveCollection (Set/Insert/Delete, incl. the batching tx) and the
previously-inlined Get through the scoped resolver so reads and writes agree.

Regression tests: two keys with the same leaf id under different parents map to
DISTINCT paths, plus an end-to-end round-trip proving a record written under one
parent is not visible/overwritten under another.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FV3pbooAc9UPpNdiaJuKve
@trakhimenok trakhimenok merged commit eaa8d8a into main Jul 4, 2026
8 checks passed
@trakhimenok trakhimenok deleted the fix/encode-key-parent-chain branch July 4, 2026 09:07
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