Help us shape the future of Go! Take the 2026 Go Developer Survey

organization

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package organization provides organization management services.

Index

Constants

View Source
const (
	RoleOwner  = "owner"
	RoleAdmin  = "admin"
	RoleMember = "member"
)

MembershipRole constants for common roles.

Variables

This section is empty.

Functions

This section is empty.

Types

type API

type API struct {
	// contains filtered or unexported fields
}

API provides HTTP handlers for Organization management.

func NewAPI

func NewAPI(service Service, config APIConfig) *API

NewAPI creates a new Organization API.

func (*API) Router

func (a *API) Router() chi.Router

Router returns the Chi router.

func (*API) ServeHTTP

func (a *API) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

type APIConfig

type APIConfig struct {
	// BasePath is the base path for all endpoints (default: "/api/v1").
	BasePath string
	// Logger is the logger to use (default: slog.Default()).
	Logger *slog.Logger
}

APIConfig configures the Organization API.

func DefaultAPIConfig

func DefaultAPIConfig() APIConfig

DefaultAPIConfig returns the default API configuration.

type AddMemberInput

type AddMemberInput struct {
	OrganizationID uuid.UUID
	PrincipalID    uuid.UUID
	Role           string
	Permissions    []string
}

AddMemberInput contains input for adding a member to an organization.

type AddMemberRequest

type AddMemberRequest struct {
	Slug string `path:"slug"`
	Body struct {
		PrincipalID string   `json:"principal_id" required:"true" format:"uuid"`
		Role        string   `json:"role" required:"true" enum:"owner,admin,member"`
		Permissions []string `json:"permissions,omitempty"`
	}
}

AddMemberRequest is the request for adding a member.

type AddMemberResponse

type AddMemberResponse struct {
	Body *MemberResponse
}

AddMemberResponse is the response for adding a member.

type CheckSlugInput

type CheckSlugInput struct {
	Slug string `path:"slug"`
}

CheckSlugInput is the request for checking slug availability.

type CheckSlugOutput

type CheckSlugOutput struct {
	Body struct {
		Available bool   `json:"available"`
		Slug      string `json:"slug"`
	}
}

CheckSlugOutput is the response for checking slug availability.

type CreateOrgInput

type CreateOrgInput struct {
	Body struct {
		Name        string         `json:"name" required:"true" minLength:"1" maxLength:"100"`
		Slug        string         `json:"slug" required:"true" minLength:"3" maxLength:"63" pattern:"^[a-z][a-z0-9-]*[a-z0-9]$"`
		OrgType     string         `json:"org_type,omitempty" enum:"personal,team,enterprise" default:"team"`
		LogoURL     *string        `json:"logo_url,omitempty"`
		Description *string        `json:"description,omitempty"`
		WebsiteURL  *string        `json:"website_url,omitempty"`
		Plan        string         `json:"plan,omitempty" enum:"free,starter,pro,enterprise" default:"free"`
		Settings    map[string]any `json:"settings,omitempty"`
	}
}

CreateOrgInput is the request body for creating an organization.

type CreateOrgOutput

type CreateOrgOutput struct {
	Body *OrgResponse
}

CreateOrgOutput is the response for creating an organization.

type CreateOrganizationInput

type CreateOrganizationInput struct {
	Name             string
	Slug             string
	OrgType          OrgType
	OwnerPrincipalID *uuid.UUID // Required for personal orgs
	LogoURL          *string
	Description      *string
	WebsiteURL       *string
	Settings         map[string]any
	Plan             Plan
}

CreateOrganizationInput contains input for creating an organization.

type CreatePersonalOrgInput

type CreatePersonalOrgInput struct {
	OwnerPrincipalID uuid.UUID
	Name             string  // Display name (usually user's name)
	Slug             string  // URL-safe username
	LogoURL          *string // Optional avatar
}

CreatePersonalOrgInput contains input for creating a personal organization.

type DefaultService

type DefaultService struct {
	// contains filtered or unexported fields
}

DefaultService implements the Service interface.

func (*DefaultService) AddMember

func (s *DefaultService) AddMember(ctx context.Context, input AddMemberInput) (*Membership, error)

AddMember adds a principal as a member of an organization.

func (*DefaultService) Create

Create creates a new organization.

func (*DefaultService) CreatePersonalOrg

func (s *DefaultService) CreatePersonalOrg(ctx context.Context, input CreatePersonalOrgInput) (*Organization, error)

CreatePersonalOrg creates a personal organization for a user.

func (*DefaultService) Delete

func (s *DefaultService) Delete(ctx context.Context, id uuid.UUID) error

Delete soft-deletes an organization.

func (*DefaultService) GenerateSlug

func (s *DefaultService) GenerateSlug(ctx context.Context, name string) (string, error)

GenerateSlug generates a unique slug from a name.

func (*DefaultService) GetByID

func (s *DefaultService) GetByID(ctx context.Context, id uuid.UUID) (*Organization, error)

GetByID retrieves an organization by ID.

func (*DefaultService) GetBySlug

func (s *DefaultService) GetBySlug(ctx context.Context, slug string) (*Organization, error)

GetBySlug retrieves an organization by slug.

func (*DefaultService) GetMembership

func (s *DefaultService) GetMembership(ctx context.Context, organizationID, principalID uuid.UUID) (*Membership, error)

GetMembership retrieves a specific membership.

func (*DefaultService) GetPersonalOrg

func (s *DefaultService) GetPersonalOrg(ctx context.Context, principalID uuid.UUID) (*Organization, error)

GetPersonalOrg retrieves a principal's personal organization.

func (*DefaultService) List

List lists organizations with optional filters.

func (*DefaultService) ListMembers

func (s *DefaultService) ListMembers(ctx context.Context, organizationID uuid.UUID) ([]*Membership, error)

ListMembers lists all members of an organization.

func (*DefaultService) ListMemberships

func (s *DefaultService) ListMemberships(ctx context.Context, principalID uuid.UUID) ([]*Membership, error)

ListMemberships lists all organizations a principal belongs to.

func (*DefaultService) RemoveMember

func (s *DefaultService) RemoveMember(ctx context.Context, organizationID, principalID uuid.UUID) error

RemoveMember removes a principal from an organization.

func (*DefaultService) SlugAvailable

func (s *DefaultService) SlugAvailable(ctx context.Context, slug string) (bool, error)

SlugAvailable checks if a slug is available.

func (*DefaultService) TransferOwnership

func (s *DefaultService) TransferOwnership(ctx context.Context, input TransferOwnershipInput) error

TransferOwnership transfers ownership of an organization to another principal.

func (*DefaultService) Update

Update updates an organization.

func (*DefaultService) UpdateMember

func (s *DefaultService) UpdateMember(ctx context.Context, membershipID uuid.UUID, input UpdateMemberInput) (*Membership, error)

UpdateMember updates a membership.

type DeleteOrgInput

type DeleteOrgInput struct {
	Slug string `path:"slug"`
}

DeleteOrgInput is the request for deleting an organization.

type GetMemberInput

type GetMemberInput struct {
	Slug        string `path:"slug"`
	PrincipalID string `path:"principal_id" format:"uuid"`
}

GetMemberInput is the request for getting a specific member.

type GetMemberOutput

type GetMemberOutput struct {
	Body *MemberResponse
}

GetMemberOutput is the response for getting a member.

type GetOrgInput

type GetOrgInput struct {
	Slug string `path:"slug"`
}

GetOrgInput is the request for getting an organization.

type GetOrgOutput

type GetOrgOutput struct {
	Body *OrgResponse
}

GetOrgOutput is the response for getting an organization.

type ListMembersInput

type ListMembersInput struct {
	Slug string `path:"slug"`
}

ListMembersInput is the request for listing members.

type ListMembersOutput

type ListMembersOutput struct {
	Body struct {
		Members []*MemberResponse `json:"members"`
	}
}

ListMembersOutput is the response for listing members.

type ListOrganizationsInput

type ListOrganizationsInput struct {
	OrgType *OrgType
	Plan    *Plan
	Active  *bool
	Limit   int
	Offset  int
}

ListOrganizationsInput contains filters for listing organizations.

type ListOrgsInput

type ListOrgsInput struct {
	OrgType *string `query:"org_type" enum:"personal,team,enterprise"`
	Plan    *string `query:"plan" enum:"free,starter,pro,enterprise"`
	Active  *bool   `query:"active"`
	Limit   int     `query:"limit" default:"20" minimum:"1" maximum:"100"`
	Offset  int     `query:"offset" default:"0" minimum:"0"`
}

ListOrgsInput is the request for listing organizations.

type ListOrgsOutput

type ListOrgsOutput struct {
	Body struct {
		Organizations []*OrgResponse `json:"organizations"`
		Total         int            `json:"total"`
	}
}

ListOrgsOutput is the response for listing organizations.

type MemberResponse

type MemberResponse struct {
	ID             string    `json:"id"`
	PrincipalID    string    `json:"principal_id"`
	OrganizationID string    `json:"organization_id"`
	Role           string    `json:"role"`
	Permissions    []string  `json:"permissions,omitempty"`
	Active         bool      `json:"active"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
}

MemberResponse is the API representation of a membership.

type Membership

type Membership struct {
	ID             uuid.UUID
	PrincipalID    uuid.UUID
	OrganizationID uuid.UUID
	Role           string
	Permissions    []string
	Active         bool
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

Membership represents a principal's membership in an organization.

type OrgResponse

type OrgResponse struct {
	ID               string         `json:"id"`
	Name             string         `json:"name"`
	Slug             string         `json:"slug"`
	OrgType          string         `json:"org_type"`
	OwnerPrincipalID *string        `json:"owner_principal_id,omitempty"`
	LogoURL          *string        `json:"logo_url,omitempty"`
	Description      *string        `json:"description,omitempty"`
	WebsiteURL       *string        `json:"website_url,omitempty"`
	Plan             string         `json:"plan"`
	Active           bool           `json:"active"`
	Settings         map[string]any `json:"settings,omitempty"`
	CreatedAt        time.Time      `json:"created_at"`
	UpdatedAt        time.Time      `json:"updated_at"`
}

OrgResponse is the API representation of an organization.

type OrgType

type OrgType string

OrgType represents the type of organization.

const (
	OrgTypePersonal   OrgType = "personal"   // Personal namespace for a user
	OrgTypeTeam       OrgType = "team"       // Shared team organization
	OrgTypeEnterprise OrgType = "enterprise" // Enterprise organization
)

type Organization

type Organization struct {
	ID               uuid.UUID
	Name             string
	Slug             string
	OrgType          OrgType
	OwnerPrincipalID *uuid.UUID // For personal orgs
	LogoURL          *string
	Description      *string
	WebsiteURL       *string
	Settings         map[string]any
	Plan             Plan
	Active           bool
	CreatedAt        time.Time
	UpdatedAt        time.Time
}

Organization represents an organization in the system.

func (*Organization) IsPersonal

func (o *Organization) IsPersonal() bool

IsPersonal returns true if this is a personal organization.

type Plan

type Plan string

Plan represents the organization's subscription plan.

const (
	PlanFree       Plan = "free"
	PlanStarter    Plan = "starter"
	PlanPro        Plan = "pro"
	PlanEnterprise Plan = "enterprise"
)

type RemoveMemberInput

type RemoveMemberInput struct {
	Slug        string `path:"slug"`
	PrincipalID string `path:"principal_id" format:"uuid"`
}

RemoveMemberInput is the request for removing a member.

type Service

type Service interface {
	// Create creates a new organization.
	Create(ctx context.Context, input CreateOrganizationInput) (*Organization, error)

	// CreatePersonalOrg creates a personal organization for a user.
	CreatePersonalOrg(ctx context.Context, input CreatePersonalOrgInput) (*Organization, error)

	// GetByID retrieves an organization by ID.
	GetByID(ctx context.Context, id uuid.UUID) (*Organization, error)

	// GetBySlug retrieves an organization by slug.
	GetBySlug(ctx context.Context, slug string) (*Organization, error)

	// GetPersonalOrg retrieves a principal's personal organization.
	GetPersonalOrg(ctx context.Context, principalID uuid.UUID) (*Organization, error)

	// Update updates an organization.
	Update(ctx context.Context, id uuid.UUID, input UpdateOrganizationInput) (*Organization, error)

	// Delete soft-deletes an organization.
	Delete(ctx context.Context, id uuid.UUID) error

	// List lists organizations with optional filters.
	List(ctx context.Context, input ListOrganizationsInput) ([]*Organization, error)

	// AddMember adds a principal as a member of an organization.
	AddMember(ctx context.Context, input AddMemberInput) (*Membership, error)

	// UpdateMember updates a membership.
	UpdateMember(ctx context.Context, membershipID uuid.UUID, input UpdateMemberInput) (*Membership, error)

	// RemoveMember removes a principal from an organization.
	RemoveMember(ctx context.Context, organizationID, principalID uuid.UUID) error

	// GetMembership retrieves a specific membership.
	GetMembership(ctx context.Context, organizationID, principalID uuid.UUID) (*Membership, error)

	// ListMembers lists all members of an organization.
	ListMembers(ctx context.Context, organizationID uuid.UUID) ([]*Membership, error)

	// ListMemberships lists all organizations a principal belongs to.
	ListMemberships(ctx context.Context, principalID uuid.UUID) ([]*Membership, error)

	// SlugAvailable checks if a slug is available.
	SlugAvailable(ctx context.Context, slug string) (bool, error)

	// GenerateSlug generates a unique slug from a name.
	GenerateSlug(ctx context.Context, name string) (string, error)

	// TransferOwnership transfers ownership of an organization to another principal.
	TransferOwnership(ctx context.Context, input TransferOwnershipInput) error
}

Service defines the organization service interface.

func NewService

func NewService(client *ent.Client, opts ...ServiceOption) Service

NewService creates a new organization service.

type ServiceOption

type ServiceOption func(*DefaultService)

ServiceOption configures a DefaultService.

func WithAuthzSyncer

func WithAuthzSyncer(syncer authz.RelationshipSyncer) ServiceOption

WithAuthzSyncer sets the authorization syncer for keeping authz in sync with identity changes.

func WithLogger

func WithLogger(logger *slog.Logger) ServiceOption

WithLogger sets the logger for the service.

func WithSyncMode

func WithSyncMode(mode authz.SyncMode) ServiceOption

WithSyncMode sets the sync mode (strict or eventual).

type TransferOwnershipInput

type TransferOwnershipInput struct {
	OrganizationID uuid.UUID
	FromPrincipal  uuid.UUID // Current owner
	ToPrincipal    uuid.UUID // New owner
	NewRoleForOld  string    // Role for the previous owner (default: "admin")
}

TransferOwnershipInput contains input for transferring organization ownership.

type TransferOwnershipRequest

type TransferOwnershipRequest struct {
	Slug string `path:"slug"`
	Body struct {
		NewOwnerPrincipalID string `json:"new_owner_principal_id" required:"true" format:"uuid"`
		NewRoleForOldOwner  string `json:"new_role_for_old_owner,omitempty" enum:"admin,member"`
	}
}

TransferOwnershipRequest is the request for transferring ownership.

type TransferOwnershipResponse

type TransferOwnershipResponse struct {
	Body struct {
		Message string `json:"message"`
	}
}

TransferOwnershipResponse is the response for transferring ownership.

type UpdateMemberInput

type UpdateMemberInput struct {
	Role        *string
	Permissions []string
	Active      *bool
}

UpdateMemberInput contains input for updating a membership.

type UpdateMemberRequest

type UpdateMemberRequest struct {
	Slug        string `path:"slug"`
	PrincipalID string `path:"principal_id" format:"uuid"`
	Body        struct {
		Role        *string  `json:"role,omitempty" enum:"owner,admin,member"`
		Permissions []string `json:"permissions,omitempty"`
		Active      *bool    `json:"active,omitempty"`
	}
}

UpdateMemberRequest is the request for updating a member.

type UpdateMemberResponse

type UpdateMemberResponse struct {
	Body *MemberResponse
}

UpdateMemberResponse is the response for updating a member.

type UpdateOrgInput

type UpdateOrgInput struct {
	Slug string `path:"slug"`
	Body struct {
		Name        *string        `json:"name,omitempty" maxLength:"100"`
		LogoURL     *string        `json:"logo_url,omitempty"`
		Description *string        `json:"description,omitempty"`
		WebsiteURL  *string        `json:"website_url,omitempty"`
		Plan        *string        `json:"plan,omitempty" enum:"free,starter,pro,enterprise"`
		Settings    map[string]any `json:"settings,omitempty"`
	}
}

UpdateOrgInput is the request for updating an organization.

type UpdateOrgOutput

type UpdateOrgOutput struct {
	Body *OrgResponse
}

UpdateOrgOutput is the response for updating an organization.

type UpdateOrganizationInput

type UpdateOrganizationInput struct {
	Name        *string
	LogoURL     *string
	Description *string
	WebsiteURL  *string
	Settings    map[string]any
	Plan        *Plan
}

UpdateOrganizationInput contains input for updating an organization.

Jump to

Keyboard shortcuts

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