docs(guide): rewrite GUIDE.md against the product that actually exists - #10
Merged
Merged
Conversation
GUIDE.md described a pest-control demo product from two days ago. It never mentioned Sanocare or Kelava, described an Object Explorer UI that does not exist, documented action parameters that are wrong, and promised multi-tenant isolation and audit trails that the demo mode does not deliver. Every command and endpoint in the new guide was executed against a running stack before being written down: the ten services start.sh launches were started individually, pest control was seeded, and all 63 documented endpoints were re-verified end to end (62 pass, and the one mismatch was my probe omitting a required query param, not the product). What the guide now says that it did not before: - Sanocare (Live) at /sanocare is the operational dashboard, reading the sanocare-kelava ontology. PestControlDashboard.tsx is kept as an archive, its route is gone, and /pest-control now renders a blank page. - A Sinkronisasi Kelava section: which object and link types sync-kelava.sh creates, and that its credentials come from .env, with the keys named from .env.example and no address or secret written into this public repo. - /api/v1 is served alongside /api/v2, with the wire shapes that actually differ and the three operations deliberately left unserved (both file GETs and the whole attachments namespace), each verified to answer 404. - The truth about gateway auth: it does NOT enforce. Verified directly - with AUTH_PUBLIC_KEY set, an unauthenticated GET still returns 200, because authPlugin is registered encapsulated. The guide says so, and says what follows from it, instead of implying enforcement exists. - start.sh does not start svc-compass, svc-webhooks or svc-media, so those pages 502 out of the box; the guide gives the commands to start them. - The four scripts/demo seeds reuse the first existing ontology and ignore ORG_RID, so "Ganti Industri" by running a second seed silently merges industries. start.sh --industry is the only correct switch. - A closing "Batasan yang Diketahui" section: 20 verified defects, including Network Graph never drawing an edge, the aggregation summary strip, global search needing Postgres, Compass falling back to a canned tree, the complete-service-job invoice-id collision, and the VITE_API_URL vs VITE_API_BASE_URL mismatch. Also fixes one product bug, because a documented command failed on it: the gateway forwarded the caller's Content-Length while re-serializing the parsed body, so any request whose JSON was not already compact was rejected by undici and answered 502. That made bash scripts/bootstrap-admin.sh - the documented production bootstrap path - fail with 502 instead of a real status on every run. Dropping the header lets fetch set it; a regression test covers it. AGENTS.md records the start.sh service gap, the demo-seed ontology reuse, and a pointer to the guide's limitations list.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
GUIDE.mddescribed the product from two days ago. It still sold the pest-control demo as the product, never once mentioned Sanocare or Kelava, and predated the auth,/api/v1, seed-relocation and identity-header work. Documentation that is wrong is worse than documentation that is missing, because people follow it and fail in places it does not explain.How this was checked
Nothing here was written from memory.
bash start.shitself could not be run on this machine (port 3000 was held by an unrelated Docker container andstart.shkills whatever holds it), so its contents were run instead: the ten services it launches were started individually, plus the three it does not launch, pest control was seeded fromscripts/demo/, and the console was served on a spare port and driven in a real browser through every page in the sidebar.All 63 endpoints and status codes documented in the guide were then re-verified end to end against that stack. 62 matched on the first pass; the single mismatch was my own probe omitting a required query parameter, not the product.
What was not executed, and is labelled as such inside the guide: the three Kelava scripts (they need an SSH tunnel and live database credentials) and the
docker composedeploy path (needs a full image build and the ports).What the guide now says
/sanocareis the daily operational dashboard, reading thesanocare-kelavaontology.PestControlDashboard.tsxis called out as a deliberate archive - kept, not deleted - its route is gone, and/pest-controlnow renders a blank page.sync-kelava.shcreates, its fail-fast behaviour withoutKELAVA_PASS, andseed-kelava-alerts.sh. Credentials are named by key from.env.exampleonly - no address, host or secret is written into this public repo./api/v1served alongside/api/v2, with the wire shapes that genuinely differ (shown side by side) and the three operations deliberately left unserved, each verified to answer 404:GET .../files,GET .../files/{filePath}, and the whole/api/v1/attachmentsnamespace. The guide also points out thatDELETE .../files/*is served and its 404 means something different.AUTH_PUBLIC_KEYset,GET /api/v2/ontologieswith noAuthorizationheader still returns 200, and so does a fabricated token, becauseauthPluginis registered encapsulated inserver.ts. The guide states that plainly along with what follows (request.claimsnever populated, no role enforcement,ENFORCE_PERMISSIONS=trueturning every proxied route into a 403), and separately states what the gateway does do: drop every client-assertedx-user-*header.scripts/demo/commands were re-run rather than assumed. They work - but the guide now explains that all four seeds reuse the first existing ontology and ignoreORG_RID, so the old "Ganti Industri" instructions silently merged four industries into one ontology.start.sh --industryis the only correct switch, and the clear-then-seed mechanism it relies on was verified directly.OPENFOUNDRY_ALLOW_OPEN_SIGNUPwhere it is actually read - on svc-multipass and the gateway - and shows the old form as the mistake it is.Product defects found while testing (recorded, not fixed)
The guide's closing Batasan yang Diketahui section lists 20 verified defects. The ones worth a maintainer's attention:
start.shnever starts svc-compass, svc-webhooks or svc-media, so/api/v2/compass/*,/api/v2/webhooks*and/api/v2/media*answer 502 and those pages do not work out of the box. Starting them by hand makes all three return 200.sourceObjectType/targetPrimaryKeyoff.../links/:lt, which returns linked objects and has no such fields; and it fires one request per object-per-link-type, which trips the gateway's own 100 req/min limit.complete-service-jobderivesinvoiceIdfromjobIdwhile the seed numbers invoices independently, so almost every job 500s wrapping a 409. On a fresh seed onlyJOB-2026-008succeeds..env.exampleanddeploy/docker/Dockerfile.consolesetVITE_API_BASE_URL; the console readsVITE_API_URL. Configuring the API base URL as documented has no effect.docker-compose.ymluses a different Postgres password for the database service than for the app'sDATABASE_URL.009_multi_tenancy.sqlreadsapp.org_rid, whilepg-object-store.tssetsapp.current_org_rid.type: COUNT/value: nbecause the console expectsdata[0].metricswhile the service returns a flat list).GET /api/v2/search- the navbar "Search everything..." box - 500s without Postgres.pnpm db:seedpoints atscripts/seed.js, which does not exist./pest-controlincluded, render a blank page rather than a 404.The one product change in this PR
Flagged separately, per the brief's one-line exception.
bash scripts/bootstrap-admin.sh- the documented production bootstrap path - failed with a 502 on every run. The gateway forwarded the caller'sContent-Lengthwhile re-serializing the parsed body, so undici rejected any request whose JSON was not already compact, andbootstrap-admin.shsends pretty-printed JSON. One line inproxy.tsdrops the header and letsfetchset it. With it, signup answers a real status (403 closed, 201 when enabled), and the full bootstrap flow was run to completion. A regression test covers it.This affects far more than the one script: any caller posting non-compact JSON through the gateway was getting a 502.
Checks
npx turbo run build --continue- 49/49npx turbo run test --continue- 97/97 (36 in svc-gateway, +1 new)pnpm run lint- 0 errors, 227 warnings (unchanged baseline)AGENTS.mdrecords thestart.shservice gap, the demo-seed ontology reuse, and a pointer to the guide's limitations list so no future session re-derives them.