Commit Graph

3 Commits

Author SHA1 Message Date
vvzvlad
d9d8538846 test(sync): implement test-strategy Phase 1-2 (pure unit/golden/property), +102 tests
Work through test-strategy-report.md, high-ROI no-refactor subset (no regen).

- R-Infra: vitest resolve.alias docmost-client -> packages/docmost-client/src
  (fixes the dist-vs-src coverage artifact: canonicalize 0% -> real)
- R-Cfg-1: export parseArgs + tests
- canonicalize: align family / comment.resolved kept / link non-default +
  fixpoint & docsCanonicallyEqual reflexive/symmetric properties (0 -> 100%)
- markdown-converter golden matrix: columns/embed/audio/pdf, drawio data-align
  rule, inline-mark matrix, textAlign, escaping idempotence, table sanitization
  (61 -> 79%)
- schema parse-closures via generateJSON (TextStyle/comment/mention/Highlight/Column)
- node-ops (immutability, table edge cases, makeFreshId property), transforms
  (setCalloutRange/insertMarkerAfter/commentsToFootnotes + renumber property)
- stabilize normalize-on-write fixpoint (0 -> 100%); diff coarse-fallback;
  client-utils; firstDivergence; corpus fixtures details/columns/mention
- 593 -> 695 green; build clean; corpus STABLE

Deferred (Phase 3-4, refactor-gated): pull/collab/client-REST/git-merge integration.
2026-06-17 01:01:26 +03:00
vvzvlad
4b34f4d30a feat(sync): resolve §11 idempotency via canonical comparison + corpus harness
Close Задача №0 (SPEC §11) with the spec-sanctioned option (b): compare a
canonicalized ProseMirror form instead of raw bytes.

- canonicalize.ts: canonicalizeContent/docsCanonicallyEqual — strip node attrs.id,
  drop null/undefined attrs, and drop attrs equal to their type's known non-null
  schema default (KNOWN_DEFAULTS: link target/rel, comment.resolved, orderedList.start,
  diagram/media align) so "absent" ≡ "default"; comment anchors + meaningful attrs kept
- roundtrip.ts: assert markdown byte-stability AND canonical stability; add --corpus
  mode and mutually-exclusive-flag warning
- synthetic corpus (headings, marks, lists, table, callout, code w/ trailing \n,
  diagrams, textStyle/mention) + canonicalize/corpus tests (558 green)
- known converter asymmetries (block image after paragraph; embed width/height
  coercion) converge to a fixpoint after one export->import pass -> handled by
  normalize-on-write at vault-write time; isolated under it.fails
- SPEC §11: record the resolution and normalize-on-write strategy
2026-06-16 23:23:32 +03:00
vvzvlad
447d2508ae feat(sync): scaffold monorepo, extract docmost-client, add Phase-0 harness + read-only pull
Lock the access-layer decision (REST only) and start implementation per SPEC.

- monorepo (npm workspaces): packages/docmost-client = DocmostClient + lib/*
  copied 1:1 from docmost-mcp/src (backport target), plus bannered sync methods
  (listTrash, restorePage, listAllSpacePages, exportPageBody, listRecentSince /
  collectRecentSince cursor scan)
- engine stays the root app per AGENTS.md (src/, test/, build/, data/, settings.ts);
  add roundtrip.ts (SPEC §11 idempotency harness), pull.ts (SPEC §6 read-only
  Docmost->FS mirror), sanitize.ts (SPEC §12 filenames, path-traversal-safe)
- Dockerfile builds the workspace lib before the app; vitest gates CI
- exportPageBody never touches /comments (SPEC §3); serializeDocmostMarkdownBody
  emits meta + body only
- SPEC: resolve access-layer (REST), reflect root-engine layout + REST pagination
- tests: sanitize (incl. dot-traversal), collectRecentSince (cutoff/dedup/cap),
  stripBlockIds, markdown round-trip byte-stability

Note: raw ProseMirror round-trip is byte-stable in Markdown but not yet attribute-
idempotent (SPEC §11 Задача №0, before Phase 2).
2026-06-16 20:20:20 +03:00