Files
zitadel/backend/v3/domain/instance_domain.go

80 lines
3.0 KiB
Go
Raw Normal View History

feat(backend): state persisted objects (#9870) This PR initiates the rework of Zitadel's backend to state-persisted objects. This change is a step towards a more scalable and maintainable architecture. ## Changes * **New `/backend/v3` package**: A new package structure has been introduced to house the reworked backend logic. This includes: * `domain`: Contains the core business logic, commands, and repository interfaces. * `storage`: Implements the repository interfaces for database interactions with new transactional tables. * `telemetry`: Provides logging and tracing capabilities. * **Transactional Tables**: New database tables have been defined for `instances`, `instance_domains`, `organizations`, and `org_domains`. * **Projections**: New projections have been created to populate the new relational tables from the existing event store, ensuring data consistency during the migration. * **Repositories**: New repositories provide an abstraction layer for accessing and manipulating the data in the new tables. * **Setup**: A new setup step for `TransactionalTables` has been added to manage the database migrations for the new tables. This PR lays the foundation for future work to fully transition to state-persisted objects for these components, which will improve performance and simplify data access patterns. This PR initiates the rework of ZITADEL's backend to state-persisted objects. This is a foundational step towards a new architecture that will improve performance and maintainability. The following objects are migrated from event-sourced aggregates to state-persisted objects: * Instances * incl. Domains * Orgs * incl. Domains The structure of the new backend implementation follows the software architecture defined in this [wiki page](https://github.com/zitadel/zitadel/wiki/Software-Architecturel). This PR includes: * The initial implementation of the new transactional repositories for the objects listed above. * Projections to populate the new relational tables from the existing event store. * Adjustments to the build and test process to accommodate the new backend structure. This is a work in progress and further changes will be made to complete the migration. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Iraq Jaber <iraq+github@zitadel.com> Co-authored-by: Iraq <66622793+kkrime@users.noreply.github.com> Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2025-09-05 10:54:34 +02:00
package domain
import (
"context"
"time"
"github.com/zitadel/zitadel/backend/v3/storage/database"
)
type InstanceDomain struct {
InstanceID string `json:"instanceId,omitempty" db:"instance_id"`
Domain string `json:"domain,omitempty" db:"domain"`
// IsPrimary indicates if the domain is the primary domain of the instance.
// It is only set for custom domains.
IsPrimary *bool `json:"isPrimary,omitempty" db:"is_primary"`
// IsGenerated indicates if the domain is a generated domain.
// It is only set for custom domains.
IsGenerated *bool `json:"isGenerated,omitempty" db:"is_generated"`
Type DomainType `json:"type,omitempty" db:"type"`
CreatedAt time.Time `json:"createdAt,omitzero" db:"created_at"`
UpdatedAt time.Time `json:"updatedAt,omitzero" db:"updated_at"`
}
type AddInstanceDomain struct {
InstanceID string `json:"instanceId,omitempty" db:"instance_id"`
Domain string `json:"domain,omitempty" db:"domain"`
IsPrimary *bool `json:"isPrimary,omitempty" db:"is_primary"`
IsGenerated *bool `json:"isGenerated,omitempty" db:"is_generated"`
Type DomainType `json:"type,omitempty" db:"type"`
// CreatedAt is the time when the domain was added.
// It is set by the repository and should not be set by the caller.
CreatedAt time.Time `json:"createdAt,omitzero" db:"created_at"`
// UpdatedAt is the time when the domain was last updated.
// It is set by the repository and should not be set by the caller.
UpdatedAt time.Time `json:"updatedAt,omitzero" db:"updated_at"`
}
type instanceDomainColumns interface {
domainColumns
// IsGeneratedColumn returns the column for the is generated field.
IsGeneratedColumn() database.Column
// TypeColumn returns the column for the type field.
TypeColumn() database.Column
}
type instanceDomainConditions interface {
domainConditions
// TypeCondition returns a filter for the type field.
TypeCondition(typ DomainType) database.Condition
}
type instanceDomainChanges interface {
domainChanges
// SetType sets the type column.
SetType(typ DomainType) database.Change
}
type InstanceDomainRepository interface {
instanceDomainColumns
instanceDomainConditions
instanceDomainChanges
// Get returns a single domain based on the criteria.
// If no domain is found, it returns an error of type [database.ErrNotFound].
// If multiple domains are found, it returns an error of type [database.ErrMultipleRows].
Get(ctx context.Context, opts ...database.QueryOption) (*InstanceDomain, error)
// List returns a list of domains based on the criteria.
// If no domains are found, it returns an empty slice.
List(ctx context.Context, opts ...database.QueryOption) ([]*InstanceDomain, error)
// Add adds a new domain to the instance.
Add(ctx context.Context, domain *AddInstanceDomain) error
// Update updates an existing domain in the instance.
Update(ctx context.Context, condition database.Condition, changes ...database.Change) (int64, error)
// Remove removes a domain from the instance.
Remove(ctx context.Context, condition database.Condition) (int64, error)
}