organization

package
v1.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 4 Imported by: 0

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 Metadata

type Metadata map[string]string

Metadata holds arbitrary organization metadata as typed key-value pairs.

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"`
	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.

type Team

type Team struct {
	ID        id.TeamID `json:"id"`
	OrgID     id.OrgID  `json:"org_id"`
	Name      string    `json:"name"`
	Slug      string    `json:"slug"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Team represents a team within an organization.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL