You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(accounts): mount the declared installation REST routes - #1185
Installation REST routes were present in the public catalog but returned 404 because the permissions plugin never mounted InstallationService. Register its existing generated transcoder so catalogue reads and lifecycle actions reach the same authenticated RPC implementation as Connect.
This is an owner fix for #1184. It reuses the existing descriptor catalog, generated grpc-gateway handlers, plugin selection and authenticated Connect service. It adds no API, authority, alternate launcher or registry, and changes no generated artifact or dependency pin.
Validation:
All ten HTTP-to-gRPC transport regressions pass with race detection (Go 1.27.2, package 1.305s); replacing only the registration with the unchanged base makes all ten fail at 404. go vet ./pkg/permissionsplugin passes.
A real local host was rebuilt with CLI 0.1.195 through its supported Accounts service source override, retaining its database. The gateway returned 200 for GET /v1/installations:listAvailable and GET /v1/installations after fixture sign-in; anonymous catalogue access returned 401. The released v0.0.102 host returned 404 on the same catalogue REST route while its Connect equivalent returned 200. Candidate host startup took 41.4s.
The local catalog is empty; these checks establish routing and authorization reachability, not an installed consuming solution or a complete product workflow. The earlier bearer was refused after restart and the documented fixture sign-in was repeated; session continuity is not claimed. Independent fresh-context owner review at eb69661e found no actionable issues; its additional catalog and inherited authority/transport checks pass. Full service CI is running on this PR; cloud/deployed qualification has not been run. No merge or deployment is requested by this change.
Closing as contained by #1217. This change is already on main, so merging it would change nothing.
Evidence
main at review time was 35a8aca1d, the squash of feat(accounts): serve the published host interfaces as adapters — rung 1, with the gap list #1217. Its first two squashed commits are this PR's two commits, verbatim: fix(accounts): register installation REST handlers (eb69661e6) and style(accounts): apply canonical test import grouping (5e556f3bd). git branch -r --contains 5e556f3bd lists pr/1217.
permissionsplugin/plugin.go and permissionsplugin/plugin_test.go are byte-identical between this PR's head and main: git diff 5e556f3bd origin/main -- module/services/accounts/code/pkg/permissionsplugin/ is empty. The REST_SURFACE.md paragraph this PR adds is on main unchanged.
Merging this PR into main yields main's own tree. git merge-tree --write-tree 35a8aca1d 5e556f3bd gives d200cf42, which equals 35a8aca1d^{tree}. Rechecked against today's main (aaf998b87): the merge result is f34f529a, which again equals main's tree.
Review result: the change is safe, and nothing is lost by closing. The independent review covered all three files:
Mounted surface. Exactly the ten InstallationService routes that carry HTTP annotations are now mounted. installations.pb.gw.go has ten patterns, and generate_unbound_methods is not set. The internal ListInstallations stays unreachable over REST.
Same handler, same checks. The REST hop transcodes to the same Connect handler and interceptors that Connect callers already used. Every handler checks requireOrgAdmin/requireOrgMember against the verified actor's membership in the request's org_id. installation_id comes from the path and is read inside the org-bound transaction under RLS. No route derives an installation from a token. allowed_audiences stays bounded by RequireHostAudiences.
Tests run.go test -race ./pkg/permissionsplugin: 10/10 pass. With plugin.go at the base 8d06ea4d8, all ten fail at 404. go test -tags pure ./pkg/adapters ./pkg/cataloggen ./pkg/permissionsplugin passes. The naming gate and scripts/check-boundaries.sh are clean.
Not verified. No graph, gateway or DB-backed suites were booted, and codefly ci run was not run.
Follow-ups for the owner to decide. These are not filed as issues. Both reproduce on today's main (aaf998b87).
A declared-but-unmounted route is still silent.cataloggen/rest_surface.go:269 emits plugin.RegisterREST(...) for each kind: plugin binding. It checks only that the plugin exists, never that it registered the services rest_bindings.yaml binds to it. The test this change added pins the ten installation routes by hand. It covers no other plugin-bound service and would not notice a newly bound one. The probe below closes that gap. With plugin.go at base 8d06ea4d8, exactly the ten installation routes fail with 404 Route not found. With the fix, 171 of 173 catalog routes reach their declared procedure, and the remaining two are follow-up 2.
Two declared routes dispatch to a different RPC. grpc-gateway v2.31's ServeMux.Handle prepends (runtime/mux.go:395), so a template registered later shadows an earlier literal path:
GET /v1/users/self (declared UserService/GetSelf, identity.proto:148) reaches /saas.accounts.v1.UserService/GetUser with id="self".
GET /v1/platform/jobs/operations (declared PlatformAdminService/GetJobOperations, platform_admin.proto:929) reaches /saas.accounts.v1.PlatformAdminService/GetJob with job_id="operations" (:957).
The gateway authorizes the declared procedure, and accounts then runs the shadowing procedure's own checks and handler. So the expected cost is correctness, not privilege. The end-to-end response has not been verified.
Reproduction: catalog-wide transcoding probe (drop into module/services/accounts/code/pkg/adapters/, then run GOWORK=off go test -tags pure -count=1 -run TestCatalogRouteReachesItsProcedure -v ./pkg/adapters/)
lazybox has finished working on this.claude (Opus 5.5) held it from 2026-10-26 16:43 UTC until 2026-11-02 20:23 UTC. The working label has been removed; this comment is the record.
claim detail
Lazybox-Claim-Device: effacd542b611010656e
Lazybox-Claim-Session: 5edfc00eb2
Lazybox-Claim-Workspace: github-codefly-dev-module-saas-starter-1185
Lazybox-Claim-Agent: claude
Lazybox-Claim-Model: Opus 5.5
Lazybox-Claim-Started: 2026-10-26T16:43:33Z
Lazybox-Claim-Heartbeat: 2026-11-02T20:23:05Z
Lazybox-Claim-Expires: 2026-11-02T16:08:10Z
Lazybox-Claim-Released: 2026-11-02T20:23:05Z
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
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.
Installation REST routes were present in the public catalog but returned 404 because the permissions plugin never mounted
InstallationService. Register its existing generated transcoder so catalogue reads and lifecycle actions reach the same authenticated RPC implementation as Connect.This is an owner fix for #1184. It reuses the existing descriptor catalog, generated grpc-gateway handlers, plugin selection and authenticated Connect service. It adds no API, authority, alternate launcher or registry, and changes no generated artifact or dependency pin.
Validation:
go vet ./pkg/permissionspluginpasses.TestRESTSurface*catalog checks pass (package 0.371s). Module verification, naming and boundary checks pass.GET /v1/installations:listAvailableandGET /v1/installationsafter fixture sign-in; anonymous catalogue access returned 401. The released v0.0.102 host returned 404 on the same catalogue REST route while its Connect equivalent returned 200. Candidate host startup took 41.4s.The local catalog is empty; these checks establish routing and authorization reachability, not an installed consuming solution or a complete product workflow. The earlier bearer was refused after restart and the documented fixture sign-in was repeated; session continuity is not claimed. Independent fresh-context owner review at
eb69661efound no actionable issues; its additional catalog and inherited authority/transport checks pass. Full service CI is running on this PR; cloud/deployed qualification has not been run. No merge or deployment is requested by this change.