Skip to content

Resolve an address from an id - #45

Merged
rafiki270 merged 1 commit into
mainfrom
claude/resolve-by-id
Sep 6, 2026
Merged

Resolve an address from an id#45
rafiki270 merged 1 commit into
mainfrom
claude/resolve-by-id

Conversation

@rafiki270

Copy link
Copy Markdown
Contributor

Summary

Adds the inverse of resolving a hostname:

GET /domain/organisations/:id/address  ->  org_slug (+ name, icon)
GET /domain/teams/:id/address          ->  team_slug AND org_slug

A product stores UOA's ids and no slug of its own — the slug belongs to UOA. So until now it could route a tenant hostname it was handed, but could not build one. That is half a feature, and it showed up in two concrete ways: a team picker cannot move the address bar, and there is no way to ask what address an existing organisation is at.

The team route returns both labels in one read, because an address is <team.slug>.<organisation.slug>.<base domain> and the caller holds neither. A picker that moves the address bar would otherwise make one request per row.

Scoping is load-bearing here

Both reads are confined to the calling client domain like every other /domain/* read. For teams that is not decoration: team ids are globally unique, so a bare id would be a cross-tenant read. The query is confined by an organisation-domain predicate, and a test pins exactly that shape so it can't be refactored away.

Testing

  • 1882 passed, five new unit tests covering both routes, the null cases, and the two scoping predicates.
  • The two failures in email-registration-link.route.test.ts are pre-existing and unrelated — clean main fails that same file harder (four cases to this branch's two). Worth someone's attention separately: UOA's main is red again.

Not verified

No consumer yet — the Nessie side that uses this follows, and this must deploy first.

🤖 Generated with Claude Code

…ing a name

A product stores UOA's ids and no slug of its own, because the slug belongs to
UOA. So it could route a tenant hostname it was handed but could not build one
— half a feature. Concretely: a team picker cannot move the address bar, and a
product cannot tell an operator what address an existing organisation is at.

  GET /domain/organisations/:id/address -> org_slug (+ name, icon)
  GET /domain/teams/:id/address         -> team_slug AND org_slug

The team route returns both labels in one read because an address is
`<team.slug>.<organisation.slug>.<base domain>` and the caller holds neither; a
picker that moves the address bar would otherwise make a request per row.

Both are scoped to the calling client domain, like every other /domain/* read.
For teams that scoping is load-bearing rather than decorative: team ids are
globally unique, so a bare id would be a cross-tenant read — the query is
confined by an organisation-domain predicate, and a test pins that.

Suite: 1882 passed. The two failures in email-registration-link.route.test.ts
are pre-existing and unrelated — clean main fails the same file harder (four
cases to this branch's two).

Co-Authored-By: Claude Opus 5 <[email protected]>
@rafiki270
rafiki270 merged commit 6f5cd86 into main Sep 6, 2026
2 checks passed
@rafiki270
rafiki270 deleted the claude/resolve-by-id branch September 6, 2026 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant