gitoriaLog in with ident

tickets

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commitbb64d57cbb64d57cmission 012 (ticket #25 API part): every /api/projects/<x>/… route takes the project's id (12-char record id) as well as its slug, same answers byte for byte; tickets stay under their project, no global /api/tickets/<x>. gate 315/0 (old code: the 13 id checks fail), connect 60/0, live-data copy old vs new 1,484 identical, slug vs id 772 identicalmrebb64d57c/reports/012-api-project-ids.md

4.2 KB

  1. # Report 012 (w091): tickets#25 API part — a project by its id
  2. **Where:** one commit on main in loreana:/media/STORAGE/projects/tickets.worldapi.org (on top of 7538b03).
  3. Not pushed, not deployed. No `.env` read. Ports used: 8760–8764 and 8767–8769 (8765/8766 not touched). Every server I
  4. started was stopped by its PID; nothing of mine is still running (checked with `ss -ltn` and `ps … hl-browser-tier`).
  5. ## What changed
  6. - **Every `/api/projects/<x>/…` route takes the slug OR the project's id** (all 16 routes: the project itself, members,
  7. members/remove, invites, connections, connections/remove, tickets, tickets/<n> and its comments / state / edit / assign /
  8. parent / blocked-by). GET and POST.
  9. - **The id format:** projects had no short id, so it is the existing record id: hl:mpackdb's `@id`, **12 characters
  10. `[0-9a-z]`** (time-based), e.g. `0mufbw18nsuj` = tickets.worldapi.org. Shown as `id` in `GET /api/projects` (`details`)
  11. and `GET /api/projects/<x>` (`project`). It stays the same when the slug changes (checked in the gate).
  12. - **Tickets stay under their project:** `/api/projects/<id or slug>/tickets/<n>`. **No new global `/api/tickets/<x>`.**
  13. The old `/api/tickets/<old number | ticket UUID>` is unchanged; `/api/tickets/<project id>` → 404 as before.
  14. - **How:** `lib/projects.hl slugOfRef` — a slug (also an old one) stays as it is; else a project id gives its CURRENT slug;
  15. else unchanged (names nothing → 404 as before). `lib/api.hl slugOf(route)` uses it in `byNumber` and in the 7 route
  16. functions that read `route.params.slug`. Everything after that runs as with the slug, so the id form answers byte for
  17. byte what the slug form answers. A slug is tried first: it would win if a slug ever equalled another project's id.
  18. - **Not changed:** pages (`/<slug>`, `/projects/<slug>` … take slugs only), every existing API path and answer.
  19. ## Tests
  20. | test | result |
  21. |---|---|
  22. | gate `tests/browser.mjs` (`.scratch/w091/gate.sh`) | **315 passed, 0 failed** (293 before + 22 new "ids (#25)") |
  23. | control: the same gate on the OLD code (`.scratch/w091/old`) | 286 passed, **13 failed — exactly the id checks**, then it stops |
  24. | `tests/connect.mjs` (`.scratch/w091/connect.sh`) | **60 passed, 0 failed**, twice. A first run stopped once at "#connecttitleinput" (the connect page's UI, not touched) — a flake |
  25. | real-data copy, new `tests/projectids-realdata.py` (old :8763 vs new :8764) | **0 FAILED** (see below) |
  26. | `tests/letcount.py` | never-reassigned `let` = 0 |
  27. **The new gate checks:**
  28. - 9 reads by id equal the slug form byte for byte: the project, its tickets (+ `?state=open`, `?state=bogus`, Markdown), ticket 1
  29. (JSON + Markdown), a missing ticket, the connections.
  30. - An unknown id → 404 on 4 routes.
  31. - `/api/tickets/<project id>` → 404.
  32. - Every write route by id:
  33. - a new project `delta`: POST tickets → 201 #1;
  34. - comments, state, edit, assign, parent, blocked-by → 201 each, and the slug form reads what they wrote;
  35. - the project POST, members, members/remove → 200;
  36. - invites with a bad role and connections/remove of an unknown key → 400 (the project's own checks, not 404);
  37. - POST to an unknown id → refused.
  38. - After a slug change, the id, the new slug and the old slug answer the same ticket.
  39. - The PWA count is now TOTAL + 1, because of the ticket made by id.
  40. **Real-data copy:** taken from Byrodin on 2026-10-04 around 05:00 and deleted after the run.
  41. - **Data:** 11 projects, 309 tickets.
  42. - **Old vs new code, 1,484 answers:** every API read as JSON and as Markdown, and the refusals. All byte-identical, including status and content type.
  43. - **On the new code, 772 slug-vs-id answers:** every project route, plus every ticket by id, as JSON and as Markdown. All identical.
  44. - **404s:** an unknown id, and `/api/tickets/<project id>` for all 11 projects.
  45. - **The ticket's own case:** `/api/projects/0mufbw18nsuj/tickets/25` returns the Markdown of tickets.worldapi.org #25. The old code returns 404 for `/api/projects/0mufbw18nsuj`.
  46. ## Not done / open
  47. - **Not deployed:** deploying is the architect's job (`./deploy.sh`). There is no data change.
  48. - **Tools:** t.py, watch.py and the connected apps keep working unchanged. They can switch to ids whenever that is wanted.
  49. - **Scratch (gitignored) in `.scratch/w091/`:** `gate.sh`, `connect.sh`, the gate logs and the old tree.

Branches

Latest commits

  • bb64d57cmission 012 (ticket #25 API part): every /api/projects/<x>/… route takes the project's id (12-char record id) as well as its slug, same answers byte for byte; tickets stay under their project, no global /api/tickets/<x>. gate 315/0 (old code: the 13 id checks fail), connect 60/0, live-data copy old vs new 1,484 identical, slug vs id 772 identicalmre
  • 7538b034mission 011 (ticket #25 web part): short page URLs /<slug> and /<slug>/<number>; /projects/<slug>, /projects/<slug>/<n>, /projects/<slug>/tickets/<n> and /tickets/<ref> answer 301 (current slug); slug pages moved behind hl:web's own routes after construction (they answered /__hl/* and /components/*.hl); reserved slugs refused; API paths unchanged. gate 293/0, connect 60/0, live-data copy 187/0, API old vs new: only page links differmre
  • 0369106emission 010 (code order) 4/4: README file map + import order + 'Same output' test, STATUS (entry, lessons, how to verify), LOG, report; tests/realdata-baseline.mjs + realdata-compare*.py (a cleanup answers the same on live data), tests/letcount.pymre
  • a75e0279mission 010 (code order) 3/4: let only where a variable is reassigned or re-bound in a loop body (456 lets → plain declarations; Hybriel refuses a plain declaration inside a loop on its 2nd pass). gate 249/0, connect 60/0, real-data reads identical, a 50-step write sequence (API + faces) identical to the old codemre
  • e9d5c618mission 010 (code order) 2/4: one lib/ file per topic — store.hl split into projects / tickets (+ relations) / events / tickets-helpers, util.hl shared helpers (env, storage dir, URLs, sorts, Vienna time), the function routes out of project.hl into lib/api.hl (thin; auth/filters/Accept in api-helpers.hl), invite + member-removal logic out of the faces/routes into invites.hl / tickets.hl; project.hl is the map. /login/callback gets req + the session store by reference. gate 249/0, connect 60/0, real-data reads identicalmre
  • 97e269b5mission 010 (code order) 1/4: .hl files out of the root — lib/ (store, users, connections, invites, migrate, markdown, mdview, import = ticketfile, util = localtime, jsoncheck, api-helpers = api), tools/import.hl, components/styles.hl; import paths only. gate 249/0, connect 60/0, real-data reads identicalmre
  • 38f9d10ftickets: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gate 249/0, connect 60/0mre
  • d3db6139tickets: Hybriel master 190aa11d (fc838894 GC correctness, #126 closure scopes, #127); gate 249/0, connect 60/0mre
  • bce182e3tickets: Hybriel master 7eea0d32 (#126 memory, #48 lambda copies its argument); migrate.hl lambdas take &logmre
  • 4137be0fantcolony#40: mission references point to the moved missionsmre
  • 9bfba36aantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
  • c7bd2645tickets: Hybriel master 73267707 (#122 fixed); compactNow workaround removed (#110 covered)mre
  • 2ab91ee9tickets: gate checks rows appear once (session sync); re-vendor to ff51cf46 stopped on hybriel#122, stays 837fe120mre
  • e01c2b1dtickets#24: installable app (manifest, service worker, offline list), own icon; gate waits for the hello's pongmre
  • 752fbb7fdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • 38bdd5e4deploy.sh: never send .git or .gitignore to Byrodinmre
  • f12fa1bcState of 2026-09-27, before the move to gitoriamre