Versions in this module Expand all Collapse all v0 v0.3.2 Jul 17, 2026 v0.3.1 Jul 17, 2026 Changes in this version + const DefaultSQLAssignmentTableName + const DefaultSQLMoveTableName + const DefaultSQLUnitTableName + const SQLDialectMySQL + const SQLDialectPostgres + const SQLDialectSQLite + var ErrAssignmentAlreadyExists = errors.New("saas/deployment: assignment already exists") + var ErrAssignmentConflict = errors.New("saas/deployment: assignment conflict") + var ErrAssignmentNotFound = errors.New("saas/deployment: assignment not found") + var ErrDeploymentUnitAlreadyExists = errors.New("saas/deployment: deployment unit already exists") + var ErrDeploymentUnitConflict = errors.New("saas/deployment: deployment unit conflict") + var ErrDeploymentUnitInUse = errors.New("saas/deployment: deployment unit in use") + var ErrDeploymentUnitNotFound = errors.New("saas/deployment: deployment unit not found") + var ErrDeploymentUnitUnavailable = errors.New("saas/deployment: deployment unit unavailable") + var ErrInvalidAssignment = errors.New("saas/deployment: invalid assignment") + var ErrInvalidDeploymentUnit = errors.New("saas/deployment: invalid deployment unit") + var ErrInvalidMove = errors.New("saas/deployment: invalid move") + var ErrInvalidTableName = errors.New("saas/deployment: invalid table name") + var ErrMoveAlreadyExists = errors.New("saas/deployment: move already exists") + var ErrMoveConflict = errors.New("saas/deployment: move conflict") + var ErrMoveNotFound = errors.New("saas/deployment: move not found") + var ErrNilDB = errors.New("saas/deployment: nil db") + var ErrNilStore = errors.New("saas/deployment: nil store") + var ErrPolicyDenied = errors.New("saas/deployment: policy denied") + var ErrUnsupportedSQLDialect = errors.New("saas/deployment: unsupported sql dialect") + type Assignment struct + TenantID types.TenantID + UnitID types.DeploymentUnitID + Version uint64 + type Auditor interface + Record func(context.Context, Event) error + type AuditorFunc func(context.Context, Event) error + func (auditor AuditorFunc) Record(ctx context.Context, event Event) error + type Event struct + Action string + SourceUnitID types.DeploymentUnitID + TargetUnitID types.DeploymentUnitID + TenantID types.TenantID + UnitID types.DeploymentUnitID + type MemoryStore struct + func NewMemoryStore() *MemoryStore + func (store *MemoryStore) CompareAndSwapAssignment(ctx context.Context, expected Assignment, updated Assignment) error + func (store *MemoryStore) CreateAssignment(ctx context.Context, assignment Assignment) error + func (store *MemoryStore) CreateMove(ctx context.Context, move Move) error + func (store *MemoryStore) CreateUnit(ctx context.Context, unit types.DeploymentUnit) error + func (store *MemoryStore) CutoverMove(ctx context.Context, expected Assignment, move Move, updated Assignment) error + func (store *MemoryStore) DeleteMove(ctx context.Context, tenantID types.TenantID) error + func (store *MemoryStore) DeleteMoveIfMatch(ctx context.Context, move Move) error + func (store *MemoryStore) DeleteUnit(ctx context.Context, id types.DeploymentUnitID) error + func (store *MemoryStore) DisableUnit(ctx context.Context, id types.DeploymentUnitID) (types.DeploymentUnit, bool, error) + func (store *MemoryStore) GetAssignment(ctx context.Context, tenantID types.TenantID) (Assignment, error) + func (store *MemoryStore) GetMove(ctx context.Context, tenantID types.TenantID) (Move, error) + func (store *MemoryStore) GetUnit(ctx context.Context, id types.DeploymentUnitID) (types.DeploymentUnit, error) + func (store *MemoryStore) ListAssignmentsByUnit(ctx context.Context, unitID types.DeploymentUnitID) ([]Assignment, error) + func (store *MemoryStore) ListMovesByUnit(ctx context.Context, unitID types.DeploymentUnitID) ([]Move, error) + func (store *MemoryStore) ListUnits(ctx context.Context) ([]types.DeploymentUnit, error) + func (store *MemoryStore) UpdateUnit(ctx context.Context, unit types.DeploymentUnit) error + type Move struct + SourceUnitID types.DeploymentUnitID + TargetUnitID types.DeploymentUnitID + TenantID types.TenantID + type Option func(*Service) + func WithAuditor(auditor Auditor) Option + func WithPolicy(policy Policy) Option + type Policy interface + Validate func(context.Context, types.Tenant, types.DeploymentUnit) error + type PolicyFunc func(context.Context, types.Tenant, types.DeploymentUnit) error + func (policy PolicyFunc) Validate(ctx context.Context, tenant types.Tenant, unit types.DeploymentUnit) error + type Resolver interface + Resolve func(context.Context, types.Tenant) (types.DeploymentUnit, error) + type SQLDialect = sqlutil.Dialect + type SQLStore struct + func NewSQLStore(db *sql.DB, opts ...SQLStoreOption) (*SQLStore, error) + func (store *SQLStore) CompareAndSwapAssignment(ctx context.Context, expected Assignment, updated Assignment) (err error) + func (store *SQLStore) CreateAssignment(ctx context.Context, assignment Assignment) (err error) + func (store *SQLStore) CreateMove(ctx context.Context, move Move) (err error) + func (store *SQLStore) CreateUnit(ctx context.Context, unit types.DeploymentUnit) error + func (store *SQLStore) CutoverMove(ctx context.Context, expected Assignment, move Move, updated Assignment) (err error) + func (store *SQLStore) DeleteMove(ctx context.Context, tenantID types.TenantID) error + func (store *SQLStore) DeleteMoveIfMatch(ctx context.Context, move Move) (err error) + func (store *SQLStore) DeleteUnit(ctx context.Context, id types.DeploymentUnitID) (err error) + func (store *SQLStore) DisableUnit(ctx context.Context, id types.DeploymentUnitID) (unit types.DeploymentUnit, changed bool, err error) + func (store *SQLStore) GetAssignment(ctx context.Context, tenantID types.TenantID) (Assignment, error) + func (store *SQLStore) GetMove(ctx context.Context, tenantID types.TenantID) (Move, error) + func (store *SQLStore) GetUnit(ctx context.Context, id types.DeploymentUnitID) (types.DeploymentUnit, error) + func (store *SQLStore) ListAssignmentsByUnit(ctx context.Context, unitID types.DeploymentUnitID) (assignments []Assignment, err error) + func (store *SQLStore) ListMovesByUnit(ctx context.Context, unitID types.DeploymentUnitID) (moves []Move, err error) + func (store *SQLStore) ListUnits(ctx context.Context) (units []types.DeploymentUnit, err error) + func (store *SQLStore) UpdateUnit(ctx context.Context, unit types.DeploymentUnit) (err error) + type SQLStoreOption func(*SQLStore) error + func WithAssignmentTableName(table string) SQLStoreOption + func WithMoveTableName(table string) SQLStoreOption + func WithSQLDialect(dialect SQLDialect) SQLStoreOption + func WithUnitTableName(table string) SQLStoreOption + type Service struct + func New(store Store, opts ...Option) *Service + func (service *Service) Assign(ctx context.Context, tenant types.Tenant, unitID types.DeploymentUnitID) (Assignment, error) + func (service *Service) CancelMove(ctx context.Context, tenantID types.TenantID) error + func (service *Service) CreateUnit(ctx context.Context, unit types.DeploymentUnit) error + func (service *Service) CutoverMove(ctx context.Context, tenant types.Tenant) (Assignment, error) + func (service *Service) DeleteUnit(ctx context.Context, id types.DeploymentUnitID) error + func (service *Service) DisableUnit(ctx context.Context, id types.DeploymentUnitID) (types.DeploymentUnit, error) + func (service *Service) PrepareMove(ctx context.Context, tenant types.Tenant, targetID types.DeploymentUnitID) (Move, error) + func (service *Service) Resolve(ctx context.Context, tenant types.Tenant) (types.DeploymentUnit, error) + func (service *Service) UpdateUnit(ctx context.Context, unit types.DeploymentUnit) error + type Store interface + CompareAndSwapAssignment func(ctx context.Context, expected Assignment, updated Assignment) error + CreateAssignment func(ctx context.Context, assignment Assignment) error + CreateMove func(ctx context.Context, move Move) error + CreateUnit func(ctx context.Context, unit types.DeploymentUnit) error + CutoverMove func(ctx context.Context, expected Assignment, move Move, updated Assignment) error + DeleteMove func(ctx context.Context, tenantID types.TenantID) error + DeleteMoveIfMatch func(ctx context.Context, move Move) error + DeleteUnit func(ctx context.Context, id types.DeploymentUnitID) error + DisableUnit func(ctx context.Context, id types.DeploymentUnitID) (types.DeploymentUnit, bool, error) + GetAssignment func(ctx context.Context, tenantID types.TenantID) (Assignment, error) + GetMove func(ctx context.Context, tenantID types.TenantID) (Move, error) + GetUnit func(ctx context.Context, id types.DeploymentUnitID) (types.DeploymentUnit, error) + ListAssignmentsByUnit func(ctx context.Context, unitID types.DeploymentUnitID) ([]Assignment, error) + ListMovesByUnit func(ctx context.Context, unitID types.DeploymentUnitID) ([]Move, error) + ListUnits func(ctx context.Context) ([]types.DeploymentUnit, error) + UpdateUnit func(ctx context.Context, unit types.DeploymentUnit) error