Files
tegwick 4543f5dc43 research: Wiki.js deep dive (storage-module engine, DB<->Git Markdown, GraphQL); UC-68/69
The closest existing engine to shard-wiki's own design: DB-canonical
(Postgres/MySQL/SQLite) but with a pluggable storage-module abstraction
that bidirectionally syncs clean Markdown (+ YAML frontmatter) to Git
(also FS/S3/Azure), each provider acting as backup or source of truth.
Two big findings: (1) the storage-module interface is concrete
adapter-contract prior art alongside Foswiki::Store, and the closer one
(medium = Markdown in Git); (2) the engine-maintained bidirectional Git
mirror is the ideal file-store attach (clean MD + git history) and, being
bidirectional, makes git commit a write path (overlay/patch as a commit,
no API). Also GraphQL API (introspection = capability discovery;
selective fields = efficient projection) and authn-delegated auth modules
+ path-based rule ACL. Added UC-68 (engine-maintained bidirectional Git
mirror, write-by-commit), UC-69 (typed/introspectable API for schema
discovery + selective projection); enriched UC-06/36/38/40/42/57. Catalog
now 69 UCs. Architecture for SHARD-WP-0002 T11/T14: storage-module
abstraction as 2nd adapter-contract prior art, engine-maintained Git
mirror as attach+write surface, GraphQL introspection for capability
discovery.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 17:50:27 +02:00

15 KiB

Findings — Wiki.js: the storage-module engine that already speaks Git + Markdown

Date: 2026-06-14 Source kind: modern shipped product — a server wiki engine; a candidate shard and the closest existing engine to shard-wiki's own design (DB-canonical, but with a pluggable storage-module abstraction that bidirectionally syncs clean Markdown to Git/FS/S3/Azure) Lens: shard-wiki — storage-module-as-adapter-contract prior art, the engine-maintained Git mirror as an attach + write surface, GraphQL as a typed/introspectable API, and path-based access rules

Why Wiki.js is special in this set. Every prior engine/tool stored content in one substrate and exposed one or two surfaces. Wiki.js is DB-canonical (Postgres/MySQL/ SQLite) but abstracts persistence behind pluggable "storage modules" — Git, local filesystem, S3, Azure Blob — each of which can act as backup or source of truth, and the Git module bidirectionally syncs clean .md files (with YAML frontmatter) to a repo. In other words, Wiki.js already does, internally, much of what shard-wiki's adapter contract is meant to do: a versioned, capability-bearing, multi-provider persistence interface over Markdown. It is the second concrete prior art for the contract after Foswiki::Store — and arguably the closer one, because its content is Markdown in Git, exactly shard-wiki's native shape.

Contrast set: the engine dives (XWiki DB/components, TWiki/Foswiki file+RCS) and the modern tools. Wiki.js = modern server engine, DB-canonical, Git-storage-of-Markdown, GraphQL API, pluggable modules.


1. Core architecture

  • Stack: Node.js backend, Vue front end; everything is accessible via a GraphQL API (/graphql, with a Playground). The DB is Postgres (primary; MySQL/SQLite supported), read-replica-capable.
  • Content: Markdown (primary), plus HTML and AsciiDoc, via pluggable editors (Markdown, WYSIWYG/visual, raw HTML). Pages live on paths (a path-based hierarchy) with tags.
  • Modular architecture: typed pluggable modulesstorage, auth, search, rendering, editor. The contract-relevant ones are storage (§2) and auth (§4).
  • 3.0: a large rewrite is in development; storage remains a headline subsystem.

2. Storage modules — the headline (≈ shard-wiki's adapter contract)

A storage module "connects Wiki.js with a local or remote storage provider, to act as backup or source of truth for content. It consists of properties (user-set) and methods called on events — create, update, delete content, and sync." Providers include Git, local filesystem, S3, Azure Blob.

The Git module is the most-used: every page change commits to a Git repository, turning the wiki into version-controlled .md files. Content is written as clean Markdown, and injectMetadata() prepends YAML frontmatter (for Markdown) or HTML comments (for HTML) carrying page metadata. The sync is bidirectional with the remote repo, and access to the synced files honors Wiki.js access rules (§4).

Why this matters to shard-wiki — three distinct payoffs:

  1. Prior art for the adapter contract. Wiki.js's storage-module interface is a shipped instance of what SHARD-WP-0002 T11 specifies: a versioned, capability- bearing, multi-provider persistence abstraction, with a backup-vs-source-of-truth choice and lifecycle methods (create/update/delete/sync). It joins Foswiki::Store as concrete prior art — and is closer, because its medium is Markdown in Git.
  2. The ideal file-store attach. A Wiki.js instance with the Git module is a git repo of clean Markdown + YAML frontmatter, maintained by the engine. shard-wiki can attach that repo directly (UC-40) — better than reading the DB — and get git history for free (UC-36, adopt not supplement, via the mirror).
  3. A write path via Git, no API needed. Because the Git sync is bidirectional, shard-wiki can write-through by committing Markdown to the repo; Wiki.js ingests git→DB. This is overlay/patch application as a git commit, not an API call (UC-68). Caution: Wiki.js owns the DB↔git sync — don't double-sync, and coordinate which side is source of truth (configurable).

3. GraphQL — a typed, introspectable external API

Unlike the REST/local-REST tools (Joplin, Trilium, Notion), Wiki.js exposes a GraphQL API over all resources. Two shard-wiki-relevant properties:

  • Introspection = capability/schema discovery. A GraphQL schema is self-describing; an adapter can introspect the content/page schema rather than hard-coding it — feeding T11's capability discovery.
  • Selective-field projection. GraphQL fetches exactly the fields a projection needs (page body vs. metadata vs. tags), reducing over-fetch — relevant to projection efficiency and the operational envelope. (UC-69; an external-API sub-mode beside Notion's REST, UC-57.)

4. Auth modules + path-based access rules

  • Auth modules (local, LDAP, OAuth, SAML, …) — authentication is delegated to pluggable providers, exactly shard-wiki's authn-delegated stance (shard-wiki-auth-in-core-decision).
  • Access rules are path-based / rule-based ACL: allow/deny access to all or specific sections of the wiki per group; the Git-synced files honor the same rules. For shard-wiki this is a richer ACL than TWiki's per-topic flags (UC-06) — rule-based by path pattern — and informs how a projection should honor/surface a shard's restricted regions (union without erasure: show that a region is restricted, don't silently drop or expose it).

5. Wiki.js as a shard — capability profile

Capability Wiki.js Notes for the adapter contract
Read yes (Git mirror / GraphQL / DB) Git mirror = clean Markdown is the best surface
Write yes (GraphQL or git commit) bidirectional Git ingest = write-by-commit (UC-68)
Write granularity per-page
Identity / addressing path (+ page id) path-based; YAML frontmatter carries metadata/id
Structure YAML frontmatter (in-file via Git module) git-diffable in-text structure (good)
History git-native via Git module (else DB versions) adopt the mirror's git history (UC-36)
Native query GraphQL; pluggable search (DB/Elastic/Algolia) delegate search; GraphQL selective fetch (UC-69)
Translation Markdown primary; HTML/AsciiDoc too mostly native; multi-format = light translation (UC-42)
Attach modes file-store (engine-maintained Git mirror) / external-API (GraphQL) clean MD in git is the ideal file-store (UC-40, UC-68)
Access control path-based rule ACL; delegated auth modules authn-delegated; honor restricted regions (UC-06)
Storage abstraction pluggable storage modules (Git/FS/S3/Azure) adapter-contract prior art (T11)
Content types pages + media/assets assets via storage modules

Verdict: the most shard-wiki-shaped engine yet. Best attached via its Git storage mirror (clean Markdown + frontmatter + git history, with write-by-commit), or via GraphQL for live/selective access. Its standout gift is architectural: a shipped storage-module abstraction that is near-isomorphic to shard-wiki's adapter contract.


6. Mapping to shard-wiki INTENT (compare, do not equate)

6.1 Reinforcements

  • Storage modules = the adapter contract, shipped. A versioned, capability-bearing, multi-provider persistence interface with backup-vs-source-of-truth — exactly T11's shape, in production (with Foswiki::Store as the other prior art).
  • Markdown-in-Git is the native shape. Wiki.js validates that a serious engine can keep content as clean .md + frontmatter in git — shard-wiki's preferred medium — while still offering a rich app over a DB.
  • authn-delegated (auth modules) and git coordination (Git storage) are both core shard-wiki stances, here shipped.

6.2 Deliberate divergences (design bugs if conflated)

  1. DB is Wiki.js's canonical store; the Git repo is a maintained mirror. Treat the mirror as the attach surface, but respect that Wiki.js runs the DB↔git sync — don't double-sync; coordinate source-of-truth (UC-68).
  2. Bidirectional write needs care. Committing Markdown is a real write path, but races with the engine's own sync; apply overlays as commits the engine can ingest cleanly, never out-of-band DB edits (overlay before mutation, no silent mutation).
  3. One Wiki.js instance = one shard, not the federation layer; its access rules are the shard's, to be honored/surfaced, not re-implemented.
  4. HTML/AsciiDoc pages need light translation; Markdown pages are native.

6.3 What Wiki.js teaches that shard-wiki should keep

  • Model the contract on a real storage-module interface (Wiki.js + Foswiki::Store): properties + lifecycle methods (create/update/delete/sync) + a backup-vs-source-of- truth flag + a provider list. (T11.)
  • Prefer the engine-maintained Git mirror as the attach surface for DB-canonical engines that offer one — clean Markdown, git history, and write-by-commit (UC-68).
  • Use GraphQL introspection for capability discovery and selective projection where a shard offers it (UC-69).

7. Use-case seeds → catalog (promoted 2026-06-14)

Last existing UC is UC-67. New UCs UC-68, UC-69 added; existing UCs enriched.

Seed Catalog action
Attach an engine-maintained bidirectional Git mirror of clean Markdown (Wiki.js Git storage module): attach the repo as a file-store shard (clean MD + YAML frontmatter + git history) and optionally write-through by committing Markdown the engine ingests; coordinate source-of-truth, don't double-sync UC-68 (new)
Attach via a typed, introspectable API (GraphQL): discover the shard's schema by introspection (capability discovery) and fetch only the fields a projection needs (selective projection) UC-69 (new)
Pluggable storage modules (Git/FS/S3/Azure) = adapter-contract prior art; modular auth/search/render/editor enriches UC-38
Git storage = clean Markdown in git, the ideal engine-maintained file-store attach enriches UC-40
Git history natively via the storage module (adopt via mirror) enriches UC-36
GraphQL external-API variant (typed/introspectable/selective) enriches UC-57
Multi-format (Markdown primary; HTML/AsciiDoc) enriches UC-42
Path-based rule ACL; delegated auth modules enriches UC-06 (links authz decision)
Engine-maintained clean git shard links UC-02

8. Architecture notes for SHARD-WP-0002 (no UC)

  • Second adapter-contract prior art (T11). Wiki.js's storage-module interface (properties + create/update/delete/sync methods + backup-vs-source-of-truth + multi- provider Git/FS/S3/Azure) is, with Foswiki::Store, the model to base the contract on — and the closer one (medium = Markdown in Git). Cite both in T11.
  • Engine-maintained Git mirror (T14). Add to the attachment taxonomy: for a DB-canonical engine that offers a bidirectional Git-of-Markdown mirror, the mirror is the preferred attach + write surface (clean MD, git history, write-by-commit). A cleaner sibling of Joplin's proprietary interchange mirror (UC-60) and the file-store native-store kind (UC-40).
  • GraphQL → capability discovery + selective projection (T11/T14). Typed/ introspectable APIs give schema discovery (capability negotiation) and reduce over-fetch — note alongside Notion's REST external-API mode.
  • authn-delegated + path-based ACL reinforce the settled authz decision and inform how projections honor/surface restricted regions (union without erasure).

9. Open questions (for spec / workplans)

  1. For an engine with a bidirectional Git mirror (UC-68), is the mirror or the DB the source of truth from shard-wiki's view, and how do we avoid races with the engine's own sync (write-by-commit cadence, locking)?
  2. When both a Git mirror and GraphQL are available, which does a binding prefer — mirror for content/history, GraphQL for live/selective metadata? Can one binding use both?
  3. How does shard-wiki honor/surface path-based access rules (UC-06) in a projection without re-implementing the shard's ACL engine?
  4. Should the adapter contract's storage-module shape be standardized directly on Wiki.js + Foswiki::Store, or generalized further?

10. Sources

Source Used for
Wiki.js — GraphQL API docs (https://docs.requarks.io/dev/api) Everything via GraphQL; /graphql Playground; access/modify all resources
Wiki.js — Git storage (https://docs.requarks.io/storage/git) Per-change commit to git; clean .md; bidirectional sync with remote repo
Wiki.js — Storage overview + dev/storage.md (https://docs.requarks.io/storage ; https://github.com/requarks/wiki-docs/blob/master/dev/storage.md) Storage module = provider connector; backup-or-source-of-truth; properties + create/update/delete/sync methods; injectMetadata() YAML frontmatter; providers Git/FS/S3/Azure
Wiki.js 3.0 storage preview (https://beta.js.wiki/blog/2021-wiki-js-3-feature-preview-storage) Storage subsystem direction (3.0)
Wikipedia — Wiki.js (https://en.wikipedia.org/wiki/Wiki.js) Node.js/Vue, DB options, formats, modular architecture
BrightCoding / Grokipedia overviews Auth providers, access rules, editors, read replicas

Cross-references: research/260613-foswiki-deep-dive/findings.md (Foswiki::Store, the other storage-interface prior art), research/260614-joplin-deep-dive/findings.md (interchange/sync-mirror contrast), research/260614-notion-deep-dive/findings.md (external-API/REST contrast), research/260614-shard-spectrum-synthesis/findings.md (attachment-mode spectrum), spec/UseCaseCatalog.md (UC-02, UC-06, UC-36, UC-38, UC-40, UC-42, UC-57), workplans/SHARD-WP-0002-federation-architecture.md (T11, T14).


11. Traceability

  • New UCs: UC-68, UC-69spec/UseCaseCatalog.md.
  • Enriched UCs: UC-06, UC-36, UC-38, UC-40, UC-42, UC-57 (links UC-02, authz decision).
  • Architecture (no UC): storage-module abstraction = 2nd adapter-contract prior art (with Foswiki::Store); engine-maintained Git mirror as attach+write surface; GraphQL introspection → capability discovery + selective projection; path-based ACL + authn- delegated → SHARD-WP-0002 (T11, T14).
  • Boundary recorded: Wiki.js is one server-engine candidate shard, DB-canonical with a bidirectional Git-of-Markdown mirror that is the preferred attach surface; not a substrate and not the federation layer (don't double-sync; honor its access rules).