fix/wikijs-docs-recovery #174

Merged
haydar merged 2 commits from fix/wikijs-docs-recovery into develop 2026-10-28 21:04:24 +00:00
Member
No description provided.
getPageByPath resolved pages through pages/search — a prefix-filtered,
relevance-ranked query whose server-side default window can crowd the
bound page out of the first result page, so provisioning reported live
bound pages as 'missing remotely' and refused to proceed. Resolve by the
deterministic path hash (cyrb53, the same lookup the viewer uses) with a
paginated exact-match search fallback, and distinguish 401/403
inaccessible from 404 missing so a denied page is never treated as absent.

Add a verified-state recovery surface for org Owners/Administrators:
GET /o/{org}/projects/{project}/docs/diagnose reports site resolution,
provisioner session health, bindings, and the real remote state of each
bound page (found/moved/inaccessible/foreign/missing) plus the narrowest
recommended action. POST .../docs/repair applies rebind (bookkeeping
only), rebind_moved (ULID-marker-verified moved page inside the org
subtree), or reinitialize (explicit confirm; releases only verified-
absent bindings and lets the convergent ensure recreate just the missing
structure). Foreign occupants and inaccessible pages always stay manual.

Bound docs paths are now authoritative in provisioning so a repaired
rebind to a moved location converges cleanly, while knowledge-base and
public roots remain canonical since the Guests rule keys off them.
provisioning errors for the bound-but-missing guard now point admins at
Diagnose Docs instead of dead-ending.
fix(portal): incomplete Wiki.js lookups can never authorize docs reinitialization
All checks were successful
ci / commit-trailers (pull_request) Successful in 10s
ci / secret-scan (pull_request) Successful in 13s
ci / integrations-js (pull_request) Successful in 30s
ci / portal-frontend (pull_request) Successful in 39s
ci / openproject-spec (pull_request) Successful in 46s
ci / release-tests (pull_request) Successful in 1m25s
ci / portal-php (pull_request) Successful in 5m35s
ci / openproject-rspec (pull_request) Successful in 5m58s
1ff7ef7edd
The search fallback behind path lookups stopped at a fixed result cap
and the moved-page scan truncated at 500 — an exhausted budget was
indistinguishable from verified absence, so a live page crowded out of
the result window could be reported missing and reinitialization would
release a verified-binding and recreate over it.

Completeness is now proven, not assumed:

- searchPagesDetailed exposes the endpoint's authoritative totalHits;
  the shared paginated walker treats exhaustion as proven only when the
  total is consumed, a page arrives shorter than the server's effective
  page size (the largest batch observed, so a clamped 25-of-50 response
  is a full page, not the end), or an empty page returns.
- getPageByPath throws WikiJsIncompleteLookupException whenever the hash
  fetch does not resolve the page AND the fallback cannot verify it
  examined the whole result set — budget hit mid-walk, a batch larger
  than requested, or a timeout/5xx interrupting pagination. A null is
  only ever verified absence.
- probePageByPath reports five states: found | missing | incomplete |
  inaccessible | error, and diagnose carries them through, recommending
  manual recovery with 'lookup incomplete — no documentation modified,
  reinitialization blocked' instead of a missing verdict.
- repairReinitialize refuses every non-authoritative state, refuses
  when the moved-page scan was truncated, and re-probes each binding
  immediately before releasing it (TOCTOU); explicit confirmation
  cannot override an unresolved lookup.
- The moved-page scan is tag-filtered to the org/project ULID markers
  so it verifies exhaustion on real sites; both scans report
  complete/truncated and an incomplete scan surfaces 'a moved page may
  exist outside the scanned window' rather than supporting a missing
  verdict.
- pagePathHash now mirrors upstream normalizePagePath
  (whitespace folding) and is verified byte-identical to Wiki.js's
  generatePathHash across ASCII, Unicode, non-BMP and nested paths.
haydar scheduled this pull request to auto merge when all checks succeed 2026-10-28 20:58:37 +00:00
haydar merged commit 5232733671 into develop 2026-10-28 21:04:24 +00:00
Sign in to join this conversation.
No reviewers
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
developing4all/devworkbase!174
No description provided.