Files
q-blog/docs/features/TECH_IMPL_WIKI_MODE.md
greenflame089 0b100af686 Release v0.2.2
2025-08-22 07:28:42 -04:00

3.2 KiB
Raw Permalink Blame History

Wiki Mode / Multi-Editor — Technical Implementation

Generated 2025-08-22

Data Model

BlogSettings

  • wikiEnabled: boolean (optional; missing = false)
  • editorWhitelist: Name[] (optional; empty = global allow)
  • editorBlacklist: Name[] (optional)

Post (revision)

  • originPostId: Id (first ancestor; fallback to id if missing)
  • parentPostId?: Id
  • lineageBlogId: BlogId (owners blog id; fallback to route blog id)
  • authorName: Name (registered name)
  • updatedAt: ISO timestamp (fallback to QDN timestamp if missing)
  • published: boolean

Authorization (by Name)

  1. Owner always allowed.
  2. Blacklist blocks regardless.
  3. Whitelist non-empty → only listed Names (minus blacklist).
  4. Whitelist empty → all Names allowed (minus blacklist).

canEdit(viewerName, settings, ownerName)

  • Returns true if viewerName is Owner, or if wiki enabled and viewerName passes the whitelist/blacklist rules.

Canonical Resolver (client)

  1. Resolve origin id.
  2. Collect revisions with same origin + blog lineage, published = true.
  3. Filter by authorization (authorName vs blog settings).
  4. Pick newest by updatedAt; tiebreak: Owner wins; then lowest id.

Reference implementation in code:

  • src/utils/wiki.ts provides isAuthorized, canEdit, and selectCanonical used across UI.
  • src/utils/wikiSettingsCache.ts caches per-blog (ownerName, settings) using /arbitrary/resources?service=BLOG&identifier=... and /arbitrary/BLOG/<owner>/<id>.
  • src/hooks/useFetchPosts.tsx groups search results by identifier and applies canonical selection in feed, favorites, and subscriptions.
  • src/pages/BlogIndividualPost/BlogIndividualPost.tsx resolves canonical author before fetching BLOG_POST JSON when wiki mode is enabled.

UI

  • Blog Settings: toggle, Name pickers for whitelist/blacklist.
    • Implemented in Edit Blog modal (checkbox + comma-separated Name inputs).
    • Also available in Create Blog modal so new blogs can enable wiki from the start.
  • Post page: “Latest by Name on Date” subheader if revision not by Owner.
  • Edit: shown only if canEdit true.
  • Blog list: use resolver to show canonical per lineage.
    • Global feed, Subscriptions, and Favorites use a lightweight cache of per-blog settings to canonicalize duplicates by identifier.
    • Header blog switcher seeds blog context to ensure the posts list refreshes immediately on change.

Backward Compatibility

  • Missing fields → defaults (wikiEnabled=false, lists empty, origin=id, lineage=blogId, updatedAt=QDN ts).

Performance Notes

  • Settings Resolution: reads wiki settings from BLOG resource metadata when available; otherwise fetches BLOG JSON as fallback.
  • Prefetch: for each page of results, settings for blogs with duplicate identifiers are prefetched in parallel (singletons skip resolution).
  • Canonicalization happens only when necessary; otherwise owner or newest item is used.

Edit Flow (Wiki)

  • Editors do not need their own blog to publish a revision of an existing post when the target blog has Wiki Mode enabled.
  • Edits publish a new BLOG_POST under the editor's Name using the original BLOG_POST identifier; the canonical resolver selects the visible revision.
  • Blog (service: BLOG) metadata is not republished during edits.