Documentation
¶
Overview ¶
Package organization defines the organization domain entity and its store interface. Organizations are user-created workspaces within an app (Clerk-style).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Invitation ¶
type Invitation struct {
ID id.InvitationID `json:"id"`
OrgID id.OrgID `json:"org_id"`
Email string `json:"email"`
Role MemberRole `json:"role"`
InviterID id.UserID `json:"inviter_id"`
Status InvitationStatus `json:"status"`
Token string `json:"-"`
TokenHash string `json:"-"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
Invitation represents a pending organization invitation.
type InvitationStatus ¶
type InvitationStatus string
InvitationStatus tracks the state of an invitation.
const ( InvitationPending InvitationStatus = "pending" InvitationAccepted InvitationStatus = "accepted" InvitationExpired InvitationStatus = "expired" InvitationDeclined InvitationStatus = "declined" )
type Member ¶
type Member struct {
ID id.MemberID `json:"id"`
OrgID id.OrgID `json:"org_id"`
UserID id.UserID `json:"user_id"`
Role MemberRole `json:"role"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Member represents a user's membership in an organization.
type MemberRole ¶
type MemberRole string
MemberRole defines the role of an organization member.
const ( RoleOwner MemberRole = "owner" RoleAdmin MemberRole = "admin" RoleMember MemberRole = "member" )
type Organization ¶
type Organization struct {
ID id.OrgID `json:"id"`
AppID id.AppID `json:"app_id"`
EnvID id.EnvironmentID `json:"env_id"`
Name string `json:"name"`
Slug string `json:"slug"`
Logo string `json:"logo,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
CreatedBy id.UserID `json:"created_by"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Organization represents a user-created workspace within an app.
type Store ¶
type Store interface {
// Organization CRUD
CreateOrganization(ctx context.Context, o *Organization) error
GetOrganization(ctx context.Context, orgID id.OrgID) (*Organization, error)
GetOrganizationBySlug(ctx context.Context, appID id.AppID, slug string) (*Organization, error)
UpdateOrganization(ctx context.Context, o *Organization) error
DeleteOrganization(ctx context.Context, orgID id.OrgID) error
ListOrganizations(ctx context.Context, appID id.AppID) ([]*Organization, error)
ListUserOrganizations(ctx context.Context, userID id.UserID) ([]*Organization, error)
// Paged twins for the request path; see page.Opts.
ListOrganizationsPage(ctx context.Context, appID id.AppID, opts page.Opts) (page.Page[*Organization], error)
ListUserOrganizationsPage(ctx context.Context, userID id.UserID, opts page.Opts) (page.Page[*Organization], error)
// Membership
CreateMember(ctx context.Context, m *Member) error
GetMember(ctx context.Context, memberID id.MemberID) (*Member, error)
GetMemberByUserAndOrg(ctx context.Context, userID id.UserID, orgID id.OrgID) (*Member, error)
UpdateMember(ctx context.Context, m *Member) error
DeleteMember(ctx context.Context, memberID id.MemberID) error
ListMembers(ctx context.Context, orgID id.OrgID) ([]*Member, error)
ListMembersPage(ctx context.Context, orgID id.OrgID, opts page.Opts) (page.Page[*Member], error)
// Invitations
CreateInvitation(ctx context.Context, inv *Invitation) error
GetInvitation(ctx context.Context, invID id.InvitationID) (*Invitation, error)
GetInvitationByToken(ctx context.Context, token string) (*Invitation, error)
UpdateInvitation(ctx context.Context, inv *Invitation) error
DeleteInvitation(ctx context.Context, invID id.InvitationID) error
ListInvitations(ctx context.Context, orgID id.OrgID) ([]*Invitation, error)
ListInvitationsPage(ctx context.Context, orgID id.OrgID, opts page.Opts) (page.Page[*Invitation], error)
// Teams
CreateTeam(ctx context.Context, t *Team) error
GetTeam(ctx context.Context, teamID id.TeamID) (*Team, error)
UpdateTeam(ctx context.Context, t *Team) error
DeleteTeam(ctx context.Context, teamID id.TeamID) error
ListTeams(ctx context.Context, orgID id.OrgID) ([]*Team, error)
ListTeamsPage(ctx context.Context, orgID id.OrgID, opts page.Opts) (page.Page[*Team], error)
// WithTx runs fn inside a single store transaction. The fn receives a
// Store handle scoped to the transaction; on error, all writes via that
// handle are rolled back. Implementations that don't yet support real
// backend transactions (postgres/sqlite/mongo at time of writing) execute
// fn against the parent store with best-effort semantics — callers should
// treat partial-failure recovery as a future-work gap, but new code is
// expected to use this entry point so we have one place to lift to real
// transactions later.
WithTx(ctx context.Context, fn func(tx Store) error) error
// DeleteOrganizationCascade deletes the organization and all of its
// dependent rows (members, teams, invitations) in a single backend-
// native transaction, so a partial failure rolls back atomically.
//
// This is the production-correct alternative to manually wrapping
// list+delete loops in WithTx — for the SQL/Mongo backends, plumbing
// a transaction through every Store method is a multi-day refactor;
// this entry point lets each backend execute the cascade as a
// single atomic operation using its native primitive (PgTx for
// postgres, SqliteTx for sqlite, mongo.Session for mongo) without
// requiring tx-scoped versions of every other Store method.
//
// Memory store falls back to the WithTx snapshot/restore semantics.
//
// Returns nil if the organization doesn't exist (idempotent — a
// double-delete is a no-op).
DeleteOrganizationCascade(ctx context.Context, orgID id.OrgID) error
}
Store defines the persistence interface for organization operations.
Click to show internal directories.
Click to hide internal directories.