Tenant
Overview
The Tenant
domain is a default domain in comby, designed to represent an organization that can manage identities. These identities may be linked to existing accounts, creating a structured relationship between organizations and individual users. The domain is implemented through the Tenant aggregate, which models the organization, manages associated metadata, and reacts to domain events.
The Tenant
serves as the central hub for all aggregates. While each aggregate operates independently, all comby default aggregates reference the Tenant by default to support a multi-tenancy system.
Structure
The structure of a Tenant
is simple and consists of the following elements:
- Name: The name of the tenant or organization.
- Secrets: A map for storing sensitive information, such as API keys or other credentials linked to the tenant.
A Tenant
does not reference other aggregates, as it serves as the central entity. All other aggregates refer to the Tenant instead. In comby, multiple Tenants can be created and managed. The framework ensures that Tenants are isolated, and no data is shared between them.
Commands
- TenantCommandCreate
- TenantCommandRemove
- TenantCommandRemoveAttribute
- TenantCommandRemoveSecret
- TenantCommandSetAttribute
- TenantCommandSetSecret
- TenantCommandUpdate
TenantCommandCreate
Domain Command Struct:
type TenantCommandCreate struct {
TenantUuid string `json:"tenantUuid"`
Name string `json:"name"`
Attributes string `json:"attributes,omitempty"`
}
Domain Command Handling Method:
func (cs *commandHandler) TenantCommandCreate(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandCreate) ([]comby.Event, error)
TenantCommandRemove
Domain Command Struct:
type TenantCommandRemove struct {
TenantUuid string `json:"tenantUuid"`
}
Domain Command Handling Method:
func (cs *commandHandler) TenantCommandRemove(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandRemove) ([]comby.Event, error)
TenantCommandRemoveAttribute
Domain Command Struct:
type TenantCommandRemoveAttribute struct {
TenantUuid string `json:"tenantUuid"`
Key string `json:"key"`
}
Domain Command Handling Method:
func (ch *commandHandler) TenantCommandRemoveAttribute(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandRemoveAttribute) ([]comby.Event, error)
TenantCommandRemoveSecret
Domain Command Struct:
type TenantCommandRemoveSecret struct {
TenantUuid string `json:"tenantUuid"`
SecretKey string `json:"secretKey"`
}
Domain Command Handling Method:
func (ch *commandHandler) TenantCommandRemoveSecret(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandRemoveSecret) ([]comby.Event, error)
TenantCommandSetAttribute
Domain Command Struct:
type TenantCommandSetAttribute struct {
TenantUuid string `json:"tenantUuid"`
Key string `json:"key"`
Value any `json:"value"`
}
Domain Command Handling Method:
func (cs *commandHandler) TenantCommandSetAttribute(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandSetAttribute) ([]comby.Event, error)
TenantCommandSetSecret
Domain Command Struct:
type TenantCommandSetSecret struct {
TenantUuid string `json:"tenantUuid"`
SecretKey string `json:"secretKey"`
SecretValue string `json:"secretValue,omitempty"`
}
Domain Command Handling Method:
func (cs *commandHandler) TenantCommandSetSecret(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandSetSecret) ([]comby.Event, error)
TenantCommandUpdate
Domain Command Struct:
type TenantCommandUpdate struct {
TenantUuid string `json:"tenantUuid"`
Name string `json:"name,omitempty"`
Attributes string `json:"attributes,omitempty"`
PatchedFields []string `json:"patchedFields" doc:"list of fields that should be patched - comma separated" example:"field1,field2"`
}
Domain Command Handling Method:
func (cs *commandHandler) TenantCommandUpdate(ctx context.Context, cmd comby.Command, domainCmd *TenantCommandUpdate) ([]comby.Event, error)
Queries
Domain Query Structs:
Domain Query Responses:
TenantQueryList
TenantQueryList returns a list of tenants based on the context of the requestor.
This query determines the list of tenants a requestor is allowed to access, with behavior depending on the requestor's context. The query outcome is classified into two distinct cases:
- System Tenant Context:
- When the requestor represents the system tenant, the query retrieves a complete list of all tenants.
- This includes tenants from all contexts, providing global visibility for the system tenant.
- Specific Tenant Context:
- If the requestor represents a specific tenant, the query returns a list containing only the tenant associated with the requestor.
- This ensures that the tenant has access only to its own information, adhering to strict isolation principles in a multi-tenant architecture.
Domain Query Struct:
type TenantQueryList struct {
Page int64 `json:"page,omitempty"`
PageSize int64 `json:"pageSize,omitempty"`
OrderBy string `json:"orderBy,omitempty"`
Attributes string `json:"attributes,omitempty"`
}
Domain Query Handling Method:
func (qs *queryHandler) TenantQueryList(ctx context.Context, qry comby.Query, domainQry *TenantQueryList) (*TenantQueryListResponse, error)
TenantQueryModelByName
Domain Query Struct:
type TenantQueryModelByName struct {
Name string `json:"name"`
}
Domain Query Handling Method:
func (qs *queryHandler) TenantQueryModelByName(ctx context.Context, qry comby.Query, domainQry *TenantQueryModelByName) (*TenantQueryItemResponse, error)
TenantQueryModel
Domain Query Struct:
type TenantQueryModel struct {
TenantUuid string `json:"tenantUuid"`
}
Domain Query Handling Method:
func (qs *queryHandler) TenantQueryModel(ctx context.Context, qry comby.Query, domainQry *TenantQueryModel) (*TenantQueryItemResponse, error)
TenantQueryListResponse
type TenantQueryListResponse struct {
Items []*readmodel.TenantModel `json:"items,omitempty"`
Total int64 `json:"total,omitempty"`
Page int64 `json:"page,omitempty"`
PageSize int64 `json:"pageSize,omitempty"`
}
TenantQueryItemResponse
type TenantQueryItemResponse struct {
Item *readmodel.TenantModel `json:"item,omitempty"`
}
Events
- TenantCreatedEvent
- TenantRemovedEvent
- TenantAttributeRemovedEvent
- TenantSecretRemovedEvent
- TenantAttributeSetEvent
- TenantSecretSetEvent
- TenantUpdatedEvent
TenantCreatedEvent
Domain Event Struct:
type TenantCreatedEvent struct {
Name string `json:"name"`
Attributes string `json:"attributes,omitempty"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantCreatedEvent(ctx context.Context, evt comby.Event, domainEvt *TenantCreatedEvent) (error)
TenantRemovedEvent
Domain Event Struct:
type TenantRemovedEvent struct {
Reason string `json:"reason,omitempty"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantRemovedEvent(ctx context.Context, evt comby.Event, domainEvt *TenantRemovedEvent) (error)
TenantAttributeRemovedEvent
Domain Event Struct:
type TenantAttributeRemovedEvent struct {
Key string `json:"key"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantAttributeRemovedEvent(ctx context.Context, evt comby.Event, domainEvt *TenantAttributeRemovedEvent) (error)
TenantSecretRemovedEvent
Domain Event Struct:
type TenantSecretRemovedEvent struct {
SecretKey string `json:"secretKey"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantSecretRemovedEvent(ctx context.Context, evt comby.Event, domainEvt *TenantSecretRemovedEvent) (error)
TenantAttributeSetEvent
Domain Event Struct:
type TenantAttributeSetEvent struct {
Key string `json:"key"`
Value any `json:"value"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantAttributeSetEvent(ctx context.Context, evt comby.Event, domainEvt *TenantAttributeSetEvent) (error)
TenantSecretSetEvent
Domain Event Struct:
type TenantSecretSetEvent struct {
SecretKey string `json:"SecretKey"`
SecretValue string `json:"SecretValue,omitempty"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantSecretSetEvent(ctx context.Context, evt comby.Event, domainEvt *TenantSecretSetEvent) (error)
TenantUpdatedEvent
Domain Event Struct:
type TenantUpdatedEvent struct {
Name string `json:"name,omitempty"`
Attributes string `json:"attributes,omitempty"`
}
Domain Event Handling Method:
func (agg *Tenant) TenantUpdatedEvent(ctx context.Context, evt comby.Event, domainEvt *TenantUpdatedEvent) (error)
Aggregate
Aggregate Struct:
type Tenant struct {
*comby.BaseAggregate
// Value Objects
Name string
Secrets *comby.Attributes
}
Methods
Create
func (agg *Tenant) Create(name, attributes string) (error)
Remove
func (agg *Tenant) Remove() (error)
RemoveAttribute
func (agg *Tenant) RemoveAttribute(key string) (error)
RemoveSecret
func (agg *Tenant) RemoveSecret(key string) (error)
SetAttribute
func (agg *Tenant) SetAttribute(key string, value any) (error)
SetSecret
func (agg *Tenant) SetSecret(key, value string) (error)
Update
func (agg *Tenant) Update(name, attributes string) (error)
Event Handlers
TenantReadmodel
Domain Event | Method |
---|---|
webhookAggregate.WebhookRemovedEvent | WebhookRemovedEvent |
webhookAggregate.WebhookAddedEvent | WebhookAddedEvent |
tenantAggregate.TenantCreatedEvent | TenantCreatedEvent |
tenantAggregate.TenantSecretRemovedEvent | TenantSecretRemovedEvent |
tenantAggregate.TenantSecretSetEvent | TenantSecretSetEvent |
tenantAggregate.TenantAttributeRemovedEvent | TenantAttributeRemovedEvent |
tenantAggregate.TenantAttributeSetEvent | TenantAttributeSetEvent |
tenantAggregate.TenantUpdatedEvent | TenantUpdatedEvent |
tenantAggregate.TenantRemovedEvent | TenantRemovedEvent |
invitationAggregate.InvitationCreatedEvent | InvitationCreatedEvent |
invitationAggregate.InvitationRemovedEvent | InvitationRemovedEvent |
identityAggregate.IdentityProfileUpdatedEvent | IdentityProfileUpdatedEvent |
identityAggregate.IdentityRemovedEvent | IdentityRemovedEvent |
identityAggregate.IdentityCreatedEvent | IdentityCreatedEvent |
groupAggregate.GroupUpdatedEvent | GroupUpdatedEvent |
groupAggregate.GroupRemovedEvent | GroupRemovedEvent |
groupAggregate.GroupAddedEvent | GroupAddedEvent |
assetAggregate.AssetAddedEvent | AssetAddedEvent |
assetAggregate.AssetRemovedEvent | AssetRemovedEvent |