Skip to content

billing: add account membership API (invite members)#123

Merged
acoshift merged 1 commit into
mainfrom
billing-members
Jul 1, 2026
Merged

billing: add account membership API (invite members)#123
acoshift merged 1 commit into
mainfrom
billing-members

Conversation

@acoshift

@acoshift acoshift commented Jul 1, 2026

Copy link
Copy Markdown
Member

Summary

Lets a billing account owner invite other people to help manage the account — e.g. a company accountant who needs to view invoices/receipts and pay them, without sharing the owner's login.

Adds three methods to the Billing interface plus their request/response types and Go client implementations:

  • billing.listMembers — list a billing account's invited members (owner/admin only).
  • billing.addMember — invite a user or change an existing member's role (owner/admin only; upsert).
  • billing.removeMember — remove an invited member (owner/admin only).

Roles

Two member roles alongside the implicit owner (the billing_accounts.owner column, never a member row):

capability owner admin accountant
view account / invoices / receipts / report
pay (upload transfer slip)
edit tax info (billing.update)
list / add / remove members
delete account (billing.delete)

Notes

  • BillingItem gains a Role field carrying the caller's effective role (owner|admin|accountant) so a client can gate management UI without a second lookup.
  • AddMember.Valid() uses govalidator.IsEmail, which also rejects allUsers/allAuthenticatedUsers — billing is money, so members must be real, addressable identities (no public principals).
  • billing.* remains non-delegatable (unchanged role.go branch): billing is authorized by ownership/membership, not project IAM.
  • New errors: ErrBillingForbidden, ErrBillingMemberNotFound, ErrBillingMemberIsOwner.

This is the contract-only PR; the apiserver enforcement, console portal UI, docs, MCP and CLI changes land in follow-up PRs that pin to this once merged.

Test

go build ./... && go vet ./... clean.

Add ListMembers/AddMember/RemoveMember to the Billing interface plus their
request/response types, so a billing account owner can invite other people to
help manage the account.

Two member roles alongside the implicit owner:
- admin: full co-manager (view + pay invoices, edit tax details, manage members,
  bill projects to the account); cannot delete the account.
- accountant: view invoices/receipts, view the usage report, and pay only.

BillingItem gains a Role field carrying the caller's effective role
(owner|admin|accountant). AddMember validates a real email (govalidator.IsEmail
rejects allUsers/allAuthenticatedUsers — no public principals) + a valid role,
and canonicalizes the email lower-case so a mixed-case invite can't lock out the
invitee. New errors: ErrBillingForbidden, ErrBillingMemberNotFound,
ErrBillingMemberIsOwner. billing.* stays non-delegatable.

Also documents on the Project interface that project.create/update require the
caller to be owner/admin of the target billing account.
@acoshift acoshift merged commit ed9c3d1 into main Jul 1, 2026
@acoshift acoshift deleted the billing-members branch July 1, 2026 06:37
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