feat(client)!: delete projects.listTemplates() — nothing has ever mounted its route (#3702) - #3730
Merged
Merged
Conversation
…ounted its route (#3702) `client.projects.listTemplates()` built `GET /api/v1/cloud/templates`. That path is mounted by nothing: none of the 17 registrars in cloud's `cloud-artifact-api-plugin.ts` (91 registrations, enumerated by driving them against a capturing mock `IHttpServer`), and nothing here — the string occurs exactly once in each repo, at the call itself. Every invocation was a 404 behind a type signature promising a resolved value. Templates are real as DATA — `sys_package_templates`, the `is_starter = true` view over `sys_package`, rendered as a console page — but there has never been an HTTP route that lists them, and an org-wide code search finds no caller in any repo. Mounting a route to satisfy a method nobody calls is the wrong order: the client's declared shape (`{ id, label, description, category? }`) does not match `sys_package`'s columns, so picking that mapping is a product decision. The method returns when a route exists to back it, with an `sdk` ledger row proving so — cloud's ledger already pins the absence ("DELIBERATELY ABSENT") and `UNMOUNTED_CLIENT_METHODS` shrinks to empty on the companion bump there. Sixth instance of the `the method exists != the method can be called` class, after analytics.explain/meta (#3584), meta.getView (#3611) and i18n.getTranslations/getFieldLabels (#3636) — and the first only a cross-repo guard could see: the framework capstone (#3642) exempts the `/api/v1/cloud/` prefix wholesale because this repo does not serve those routes, so the finding came from cloud's control-plane ledger (#3655). Audit doc and the capstone's prose updated to record the finding as resolved. Closes #3702 Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
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.
Closes #3702.
What was wrong
client.projects.listTemplates()builtGET /api/v1/cloud/templates. Nothing mounts that path, in either repo:cloud-artifact-api-plugin.tswere enumerated for the control-plane ledger (Theprojects.*SDK namespace targets the control plane, which no in-repo ledger can vouch for #3655) by driving them against a capturing mockIHttpServer: 91 registrations, 90 distinct, none/cloud/templates. The ledger records the absence deliberately (cloud-route-ledger.ts: "DELIBERATELY ABSENT").So every invocation was a 404, behind a type signature promising a resolved value.
No caller anywhere.
gh search code --owner objectstack-aireturns only the definition, the two guards, and history — nothing inobjectui,cloud,templates,objectos,website,builder,crm,hotcrm,mobile,objectbase.Why option 1 (trim), not option 2 (mount)
Templates are real as data —
sys_package_templates, theis_starter = trueview oversys_package, rendered as a console page — but have never been an HTTP route, and cloud states the position explicitly (sys-package.object.ts: there "is no separate 'template' concept";apps/cloud/objectstack.config.ts: "No built-in environment templates: every environment is provisioned empty"). The client's declared shape ({ id, label, description, category? }) does not matchsys_package's columns, so mounting a route means first deciding what a template is on the wire — a product call, not an implementation detail, and the wrong order for a method nobody calls. It returns when a route exists to back it, with ansdkledger row proving so.The class
Sixth instance of
the method exists ≠ the method can be called, afteranalytics.explain/analytics.meta(#3584),meta.getView(#3611),i18n.getTranslations/getFieldLabels(#3636) — and the first one only a cross-repo guard could see: the framework capstone (#3642) exempts the/api/v1/cloud/prefix wholesale because this repo does not serve those routes, so the finding came from cloud's control-plane ledger (#3655), the one place the mounted set and the SDK are both in scope.Changes
packages/client/src/index.ts— method deleted, tombstone comment in its place (same treatment the 21 dead methods got in feat(client,spec)!: delete 21 dead SDK methods + the four ghost route tables under them (#3612) #3616).packages/client/src/client-url-conformance.test.ts— capstone prose records the finding as resolved (comment only).docs/audits/2026-07-dispatcher-client-route-coverage.md— §13 finding annotated Removed inclient.projects.listTemplates()targets/api/v1/cloud/templates, which nothing mounts #3702; a "23 methods" count replaced with "everyprojects.*method" so it stops drifting.@objectstack/clientminor, breaking-marked, carrying the migration line (read starter packages through thesys_packageview).Companion change required in
cloud— after this mergesprojects-namespace-coverage.test.tsthere drives the real SDK and will go red on the next.objectstack-shabump: it assertsmethods.length >= 23(becomes 22) and drivesprojects.listTemplatesfrom itsDRIVEtable. The cloud PR bumps the pin and prunes the row in one commit (it cannot be green against the old pin, by design — that lockstep is the guard working):UNMOUNTED_CLIENT_METHODSentry → the list becomes[], and the exact-pin assertion holds it there'projects.listTemplates': []fromDRIVE,23→22Verification
pnpm vitest run src/inpackages/client— 13 files / 175 tests pass, including the capstoneclient-url-conformance.test.ts(itscontrolPlane.length > 0bound still holds; the remainingprojects.*methods reach the control plane).pnpm build— 71/71 tasks green with dts on (OS_SKIP_DTSunset);packages/client/dist/index.d.tsregenerated with zerolistTemplateshits, which is the type-check for a method-removal.Out of scope, filed separately
The same dead concept has a second, still-advertised half:
os env create --templateandprojects.create({ template_id }). Filed as #3731.🤖 Generated with Claude Code