diff --git a/backend/v3/domain/domain.go b/backend/v3/domain/domain.go index 38e8d6a9cd..e6ac73dac1 100644 --- a/backend/v3/domain/domain.go +++ b/backend/v3/domain/domain.go @@ -1,5 +1,61 @@ package domain +import "github.com/zitadel/zitadel/backend/v3/storage/database" + +type DomainVerificationType string + +const ( + DomainVerificationTypeDNS DomainVerificationType = "dns" + DomainVerificationTypeHTTP DomainVerificationType = "http" +) + +type domainColumns interface { + // InstanceIDColumn returns the column for the instance id field. + InstanceIDColumn() database.Column + // DomainColumn returns the column for the domain field. + DomainColumn() database.Column + // IsVerifiedColumn returns the column for the is verified field. + IsVerifiedColumn() database.Column + // IsPrimaryColumn returns the column for the is primary field. + IsPrimaryColumn() database.Column + // VerificationTypeColumn returns the column for the verification type field. + VerificationTypeColumn() database.Column + // CreatedAtColumn returns the column for the created at field. + CreatedAtColumn() database.Column + // UpdatedAtColumn returns the column for the updated at field. + UpdatedAtColumn() database.Column +} + +type domainConditions interface { + // InstanceIDCondition returns a filter on the instance id field. + InstanceIDCondition(instanceID string) database.Condition + // DomainCondition returns a filter on the domain field. + DomainCondition(op database.TextOperation, domain string) database.Condition + // IsPrimaryCondition returns a filter on the is primary field. + IsPrimaryCondition(isPrimary bool) database.Condition + // IsVerifiedCondition returns a filter on the is verified field. + IsVerifiedCondition(isVerified bool) database.Condition +} + +type domainChanges interface { + // SetVerified sets the is verified column to true. + SetVerified() database.Change + // SetPrimary sets a domain as primary based on the condition. + // All other domains will be set to non-primary. + // + // An error is returned if: + // - The condition identifies multiple domains. + // - The condition does not identify any domain. + // + // This is a no-op if: + // - The domain is already primary. + // - No domain matches the condition. + SetPrimary() database.Change + // SetVerificationType sets the verification type column. + // If the domain is already verified, this is a no-op. + SetVerificationType(verificationType DomainVerificationType) database.Change +} + // import ( // "math/rand/v2" // "strconv" diff --git a/backend/v3/domain/instance.go b/backend/v3/domain/instance.go index 2efe6734b3..761ed22e11 100644 --- a/backend/v3/domain/instance.go +++ b/backend/v3/domain/instance.go @@ -92,6 +92,8 @@ type InstanceRepository interface { Create(ctx context.Context, instance *Instance) error Update(ctx context.Context, id string, changes ...database.Change) (int64, error) Delete(ctx context.Context, id string) (int64, error) + + Domains() InstanceDomainRepository } type CreateInstance struct { diff --git a/backend/v3/domain/instance_domain.go b/backend/v3/domain/instance_domain.go new file mode 100644 index 0000000000..9dd6568c92 --- /dev/null +++ b/backend/v3/domain/instance_domain.go @@ -0,0 +1,53 @@ +package domain + +import ( + "context" + + "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"` + IsVerified bool `json:"isVerified,omitempty" db:"is_verified"` + IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"` + VerificationType DomainVerificationType `json:"verificationType,omitempty" db:"verification_type"` + + CreatedAt string `json:"createdAt,omitempty" db:"created_at"` + UpdatedAt string `json:"updatedAt,omitempty" db:"updated_at"` +} + +type AddInstanceDomain struct { + InstanceID string `json:"instanceId,omitempty" db:"instance_id"` + Domain string `json:"domain,omitempty" db:"domain"` + IsVerified bool `json:"isVerified,omitempty" db:"is_verified"` + IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"` + VerificationType DomainVerificationType `json:"verificationType,omitempty" db:"verification_type"` +} + +type instanceDomainColumns interface { + domainColumns + // IsGeneratedColumn returns the column for the is generated field. + IsGeneratedColumn() database.Column +} + +type instanceDomainConditions interface { + domainConditions +} + +type instanceDomainChanges interface { + domainChanges +} + +type InstanceDomainRepository interface { + instanceDomainColumns + instanceDomainConditions + instanceDomainChanges + + // 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) error + // Remove removes a domain from the instance. + Remove(ctx context.Context, condition database.Condition) error +} diff --git a/backend/v3/domain/organization.go b/backend/v3/domain/organization.go index 94dd80d72f..c59a134082 100644 --- a/backend/v3/domain/organization.go +++ b/backend/v3/domain/organization.go @@ -20,14 +20,14 @@ type Organization struct { Name string `json:"name,omitempty" db:"name"` InstanceID string `json:"instanceId,omitempty" db:"instance_id"` State string `json:"state,omitempty" db:"state"` - CreatedAt time.Time `json:"createdAt,omitempty" db:"created_at"` - UpdatedAt time.Time `json:"updatedAt,omitempty" db:"updated_at"` + CreatedAt time.Time `json:"createdAt,omitzero" db:"created_at"` + UpdatedAt time.Time `json:"updatedAt,omitzero" db:"updated_at"` DeletedAt *time.Time `json:"deletedAt,omitempty" db:"deleted_at"` } // OrgIdentifierCondition is used to help specify a single Organization, // it will either be used as the organization ID or organization name, -// as organizations can be identified either using (instnaceID + ID) OR (instanceID + name) +// as organizations can be identified either using (instanceID + ID) OR (instanceID + name) type OrgIdentifierCondition interface { database.Condition } @@ -82,6 +82,9 @@ type OrganizationRepository interface { Create(ctx context.Context, instance *Organization) error Update(ctx context.Context, id OrgIdentifierCondition, instance_id string, changes ...database.Change) (int64, error) Delete(ctx context.Context, id OrgIdentifierCondition, instance_id string) (int64, error) + + // Domains returns the domain sub repository for the organization. + Domains() OrganizationDomainRepository } type CreateOrganization struct { diff --git a/backend/v3/domain/organization_domain.go b/backend/v3/domain/organization_domain.go new file mode 100644 index 0000000000..5fb817b1c0 --- /dev/null +++ b/backend/v3/domain/organization_domain.go @@ -0,0 +1,57 @@ +package domain + +import ( + "context" + + "github.com/zitadel/zitadel/backend/v3/storage/database" +) + +type OrganizationDomain struct { + InstanceID string `json:"instanceId,omitempty" db:"instance_id"` + OrgID string `json:"orgId,omitempty" db:"org_id"` + Domain string `json:"domain,omitempty" db:"domain"` + IsVerified bool `json:"isVerified,omitempty" db:"is_verified"` + IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"` + VerificationType DomainVerificationType `json:"verificationType,omitempty" db:"verification_type"` + + CreatedAt string `json:"createdAt,omitempty" db:"created_at"` + UpdatedAt string `json:"updatedAt,omitempty" db:"updated_at"` +} + +type AddOrganizationDomain struct { + InstanceID string `json:"instanceId,omitempty" db:"instance_id"` + OrgID string `json:"orgId,omitempty" db:"org_id"` + Domain string `json:"domain,omitempty" db:"domain"` + IsVerified bool `json:"isVerified,omitempty" db:"is_verified"` + IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"` + VerificationType DomainVerificationType `json:"verificationType,omitempty" db:"verification_type"` +} + +type organizationDomainColumns interface { + domainColumns + // OrgIDColumn returns the column for the org id field. + OrgIDColumn() database.Column +} + +type organizationDomainConditions interface { + domainConditions + // OrgIDCondition returns a filter on the org id field. + OrgIDCondition(orgID string) database.Condition +} + +type organizationDomainChanges interface { + domainChanges +} + +type OrganizationDomainRepository interface { + organizationDomainColumns + organizationDomainConditions + organizationDomainChanges + + // Add adds a new domain to the organization. + Add(ctx context.Context, domain *AddOrganizationDomain) error + // Update updates an existing domain in the organization. + Update(ctx context.Context, condition database.Condition, changes ...database.Change) error + // Remove removes a domain from the organization. + Remove(ctx context.Context, condition database.Condition) error +} diff --git a/backend/v3/storage/database/dialect/postgres/migration/003_domains_table.go b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table.go new file mode 100644 index 0000000000..c00b7ea281 --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table.go @@ -0,0 +1,16 @@ +package migration + +import ( + _ "embed" +) + +var ( + //go:embed 003_domains_table/up.sql + up003DomainsTable string + //go:embed 003_domains_table/down.sql + down003DomainsTable string +) + +func init() { + registerSQLMigration(3, up003DomainsTable, down003DomainsTable) +} diff --git a/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/down.sql b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/down.sql new file mode 100644 index 0000000000..cdda052e64 --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/down.sql @@ -0,0 +1,4 @@ +DROP TABLE IF EXISTS zitadel.instance_domains; +DROP TABLE IF EXISTS zitadel.org_domains; +DROP TYPE IF EXISTS zitadel.domain_validation_type; +DROP FUNCTION IF EXISTS zitadel.check_verified_org_domain(); diff --git a/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql new file mode 100644 index 0000000000..8f5025fe6f --- /dev/null +++ b/backend/v3/storage/database/dialect/postgres/migration/003_domains_table/up.sql @@ -0,0 +1,128 @@ +CREATE TYPE zitadel.domain_validation_type AS ENUM ( + 'http' + , 'dns' +); + +CREATE TABLE zitadel.instance_domains( + instance_id TEXT NOT NULL + , domain TEXT NOT NULL CHECK (LENGTH(domain) BETWEEN 1 AND 255) + , is_verified BOOLEAN NOT NULL DEFAULT FALSE + , is_primary BOOLEAN NOT NULL DEFAULT FALSE + , is_generated BOOLEAN NOT NULL DEFAULT FALSE + , validation_type zitadel.domain_validation_type + + , created_at TIMESTAMP DEFAULT NOW() + , updated_at TIMESTAMP DEFAULT NOW() + + , PRIMARY KEY (domain) + + , FOREIGN KEY (instance_id) REFERENCES zitadel.instances(id) ON DELETE CASCADE +); + +CREATE INDEX idx_instance_domain_instance ON zitadel.instance_domains(instance_id); + +CREATE TABLE zitadel.org_domains( + instance_id TEXT NOT NULL + , org_id TEXT NOT NULL + , domain TEXT NOT NULL CHECK (LENGTH(domain) BETWEEN 1 AND 255) + , is_verified BOOLEAN NOT NULL DEFAULT FALSE + , is_primary BOOLEAN NOT NULL DEFAULT FALSE + , validation_type zitadel.domain_validation_type + + , created_at TIMESTAMP DEFAULT NOW() + , updated_at TIMESTAMP DEFAULT NOW() + + , PRIMARY KEY (instance_id, org_id, domain) + + , FOREIGN KEY (instance_id, org_id) REFERENCES zitadel.organizations(instance_id, id) ON DELETE CASCADE + + , UNIQUE (instance_id, org_id, domain) +); + +CREATE INDEX idx_org_domain ON zitadel.org_domains(instance_id, domain); + +-- Trigger to update the updated_at timestamp on instance_domains +CREATE TRIGGER trg_set_updated_at_instance_domains + BEFORE UPDATE ON zitadel.instance_domains + FOR EACH ROW + WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at) + EXECUTE FUNCTION zitadel.set_updated_at(); + +-- Trigger to update the updated_at timestamp on org_domains +CREATE TRIGGER trg_set_updated_at_org_domains + BEFORE UPDATE ON zitadel.org_domains + FOR EACH ROW + WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at) + EXECUTE FUNCTION zitadel.set_updated_at(); + +-- Function to check for already verified org domains +CREATE OR REPLACE FUNCTION zitadel.check_verified_org_domain() +RETURNS TRIGGER AS $$ +BEGIN + -- Check if there's already a verified domain within this instance (excluding the current record being updated) + IF EXISTS ( + SELECT 1 + FROM zitadel.org_domains + WHERE instance_id = NEW.instance_id + AND domain = NEW.domain + AND is_verified = TRUE + AND (TG_OP = 'INSERT' OR (org_id != NEW.org_id)) + ) THEN + RAISE EXCEPTION 'org domain is already taken'; + END IF; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Trigger to enforce verified domain constraint on org_domains +CREATE TRIGGER trg_check_verified_org_domain + BEFORE INSERT OR UPDATE ON zitadel.org_domains + FOR EACH ROW + WHEN (NEW.is_verified IS TRUE) + EXECUTE FUNCTION zitadel.check_verified_org_domain(); + +-- Function to ensure only one primary domain per instance in instance_domains +CREATE OR REPLACE FUNCTION zitadel.ensure_single_primary_instance_domain() +RETURNS TRIGGER AS $$ +BEGIN + -- If setting this domain as primary, update all other domains in the same instance to non-primary + UPDATE zitadel.instance_domains + SET is_primary = FALSE, updated_at = NOW() + WHERE instance_id = NEW.instance_id + AND domain != NEW.domain + AND is_primary = TRUE; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Trigger to enforce single primary domain constraint on instance_domains +CREATE TRIGGER trg_ensure_single_primary_instance_domain + BEFORE INSERT OR UPDATE ON zitadel.instance_domains + FOR EACH ROW + WHEN (NEW.is_primary IS TRUE) + EXECUTE FUNCTION zitadel.ensure_single_primary_instance_domain(); + +-- Function to ensure only one primary domain per organization in org_domains +CREATE OR REPLACE FUNCTION zitadel.ensure_single_primary_org_domain() +RETURNS TRIGGER AS $$ +BEGIN + -- If setting this domain as primary, update all other domains in the same organization to non-primary + UPDATE zitadel.org_domains + SET is_primary = FALSE, updated_at = NOW() + WHERE instance_id = NEW.instance_id + AND org_id = NEW.org_id + AND domain != NEW.domain + AND is_primary = TRUE; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Trigger to enforce single primary domain constraint on org_domains +CREATE TRIGGER trg_ensure_single_primary_org_domain + BEFORE INSERT OR UPDATE ON zitadel.org_domains + FOR EACH ROW + WHEN (NEW.is_primary IS TRUE) + EXECUTE FUNCTION zitadel.ensure_single_primary_org_domain(); \ No newline at end of file diff --git a/backend/v3/storage/database/repository/instance.go b/backend/v3/storage/database/repository/instance.go index 80e852785f..6a8dbdc91b 100644 --- a/backend/v3/storage/database/repository/instance.go +++ b/backend/v3/storage/database/repository/instance.go @@ -15,6 +15,8 @@ var _ domain.InstanceRepository = (*instance)(nil) type instance struct { repository + shouldJoinDomains bool + domainRepo domain.InstanceDomainRepository } func InstanceRepository(client database.QueryExecutor) domain.InstanceRepository { @@ -244,3 +246,22 @@ func scanInstances(ctx context.Context, querier database.Querier, builder *datab return instances, nil } + +// ------------------------------------------------------------- +// sub repositories +// ------------------------------------------------------------- + +// Domains implements [domain.InstanceRepository]. +func (i *instance) Domains() domain.InstanceDomainRepository { + i.shouldJoinDomains = true + + if i.domainRepo != nil { + return i.domainRepo + } + + i.domainRepo = &instanceDomain{ + repository: i.repository, + instance: i, + } + return i.domainRepo +} diff --git a/backend/v3/storage/database/repository/instance_domain.go b/backend/v3/storage/database/repository/instance_domain.go new file mode 100644 index 0000000000..a9da950cbc --- /dev/null +++ b/backend/v3/storage/database/repository/instance_domain.go @@ -0,0 +1,128 @@ +package repository + +import ( + "context" + + "github.com/zitadel/zitadel/backend/v3/domain" + "github.com/zitadel/zitadel/backend/v3/storage/database" +) + +var _ domain.InstanceDomainRepository = (*instanceDomain)(nil) + +type instanceDomain struct { + repository + *instance +} + +// ------------------------------------------------------------- +// repository +// ------------------------------------------------------------- + +// Add implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) Add(ctx context.Context, domain *domain.AddInstanceDomain) error { + panic("unimplemented") +} + +// Remove implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) Remove(ctx context.Context, condition database.Condition) error { + panic("unimplemented") +} + +// Update implements [domain.InstanceDomainRepository]. +// Subtle: this method shadows the method (instance).Update of instanceDomain.instance. +func (i *instanceDomain) Update(ctx context.Context, condition database.Condition, changes ...database.Change) error { + panic("unimplemented") +} + +// ------------------------------------------------------------- +// changes +// ------------------------------------------------------------- + +// SetVerificationType implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) SetVerificationType(verificationType domain.DomainVerificationType) database.Change { + panic("unimplemented") +} + +// SetPrimary implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) SetPrimary() database.Change { + panic("unimplemented") +} + +// SetVerified implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) SetVerified() database.Change { + panic("unimplemented") +} + +// ------------------------------------------------------------- +// conditions +// ------------------------------------------------------------- + +// DomainCondition implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) DomainCondition(op database.TextOperation, domain string) database.Condition { + panic("unimplemented") +} + +// InstanceIDCondition implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) InstanceIDCondition(instanceID string) database.Condition { + panic("unimplemented") +} + +// IsPrimaryCondition implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) IsPrimaryCondition(isPrimary bool) database.Condition { + panic("unimplemented") +} + +// IsVerifiedCondition implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) IsVerifiedCondition(isVerified bool) database.Condition { + panic("unimplemented") +} + +// ------------------------------------------------------------- +// columns +// ------------------------------------------------------------- + +// CreatedAtColumn implements [domain.InstanceDomainRepository]. +// Subtle: this method shadows the method (instance).CreatedAtColumn of instanceDomain.instance. +func (i *instanceDomain) CreatedAtColumn() database.Column { + panic("unimplemented") +} + +// DomainColumn implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) DomainColumn() database.Column { + panic("unimplemented") +} + +// InstanceIDColumn implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) InstanceIDColumn() database.Column { + panic("unimplemented") +} + +// IsPrimaryColumn implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) IsPrimaryColumn() database.Column { + panic("unimplemented") +} + +// IsVerifiedColumn implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) IsVerifiedColumn() database.Column { + panic("unimplemented") +} + +// UpdatedAtColumn implements [domain.InstanceDomainRepository]. +// Subtle: this method shadows the method (instance).UpdatedAtColumn of instanceDomain.instance. +func (i *instanceDomain) UpdatedAtColumn() database.Column { + panic("unimplemented") +} + +// VerificationTypeColumn implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) VerificationTypeColumn() database.Column { + panic("unimplemented") +} + +// IsGeneratedColumn implements [domain.InstanceDomainRepository]. +func (i *instanceDomain) IsGeneratedColumn() database.Column { + return database.NewColumn("is_generated") +} + +// ------------------------------------------------------------- +// scanners +// ------------------------------------------------------------- diff --git a/backend/v3/storage/database/repository/org.go b/backend/v3/storage/database/repository/org.go index 90670500fa..441249f021 100644 --- a/backend/v3/storage/database/repository/org.go +++ b/backend/v3/storage/database/repository/org.go @@ -18,7 +18,9 @@ import ( var _ domain.OrganizationRepository = (*org)(nil) type org struct { + shouldJoinDomains bool repository + domainRepo domain.OrganizationDomainRepository } func OrganizationRepository(client database.QueryExecutor) domain.OrganizationRepository { @@ -229,6 +231,10 @@ func (org) DeletedAtColumn() database.Column { return database.NewColumn("deleted_at") } +// ------------------------------------------------------------- +// scanners +// ------------------------------------------------------------- + func scanOrganization(ctx context.Context, querier database.Querier, builder *database.StatementBuilder) (*domain.Organization, error) { rows, err := querier.Query(ctx, builder.String(), builder.Args()...) if err != nil { @@ -264,3 +270,22 @@ func scanOrganizations(ctx context.Context, querier database.Querier, builder *d } return organizations, nil } + +// ------------------------------------------------------------- +// sub repositories +// ------------------------------------------------------------- + +func (o *org) Domains() domain.OrganizationDomainRepository { + o.shouldJoinDomains = true + + if o.domainRepo != nil { + return o.domainRepo + } + + o.domainRepo = &orgDomain{ + repository: o.repository, + org: o, + } + + return o.domainRepo +} diff --git a/backend/v3/storage/database/repository/org_domain.go b/backend/v3/storage/database/repository/org_domain.go index e494c6a369..3f32c30c0c 100644 --- a/backend/v3/storage/database/repository/org_domain.go +++ b/backend/v3/storage/database/repository/org_domain.go @@ -4,25 +4,132 @@ import ( "context" "github.com/zitadel/zitadel/backend/v3/domain" + "github.com/zitadel/zitadel/backend/v3/storage/database" ) +var _ domain.OrganizationDomainRepository = (*orgDomain)(nil) + type orgDomain struct { + repository *org } -// AddDomain implements [domain.DomainRepository]. -func (o *orgDomain) AddDomain(ctx context.Context, domain string) error { +// ------------------------------------------------------------- +// repository +// ------------------------------------------------------------- + +// Add implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) Add(ctx context.Context, domain *domain.AddOrganizationDomain) error { panic("unimplemented") } -// RemoveDomain implements [domain.DomainRepository]. -func (o *orgDomain) RemoveDomain(ctx context.Context, domain string) error { +// Update implements [domain.OrganizationDomainRepository]. +// Subtle: this method shadows the method (*org).Update of orgDomain.org. +func (o *orgDomain) Update(ctx context.Context, condition database.Condition, changes ...database.Change) error { panic("unimplemented") } -// SetDomainVerified implements [domain.DomainRepository]. -func (o *orgDomain) SetDomainVerified(ctx context.Context, domain string) error { +// Remove implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) Remove(ctx context.Context, condition database.Condition) error { panic("unimplemented") } -var _ domain.DomainRepository = (*orgDomain)(nil) +// ------------------------------------------------------------- +// changes +// ------------------------------------------------------------- + +// SetPrimary implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) SetPrimary() database.Change { + panic("unimplemented") +} + +// SetVerificationType implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) SetVerificationType(verificationType domain.DomainVerificationType) database.Change { + panic("unimplemented") +} + +// SetVerified implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) SetVerified() database.Change { + panic("unimplemented") +} + +// ------------------------------------------------------------- +// conditions +// ------------------------------------------------------------- + +// DomainCondition implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) DomainCondition(op database.TextOperation, domain string) database.Condition { + panic("unimplemented") +} + +// InstanceIDCondition implements [domain.OrganizationDomainRepository]. +// Subtle: this method shadows the method (*org).InstanceIDCondition of orgDomain.org. +func (o *orgDomain) InstanceIDCondition(instanceID string) database.Condition { + panic("unimplemented") +} + +// IsPrimaryCondition implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) IsPrimaryCondition(isPrimary bool) database.Condition { + panic("unimplemented") +} + +// IsVerifiedCondition implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) IsVerifiedCondition(isVerified bool) database.Condition { + panic("unimplemented") +} + +// OrgIDCondition implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) OrgIDCondition(orgID string) database.Condition { + panic("unimplemented") +} + +// ------------------------------------------------------------- +// columns +// ------------------------------------------------------------- + +// CreatedAtColumn implements [domain.OrganizationDomainRepository]. +// Subtle: this method shadows the method (*org).CreatedAtColumn of orgDomain.org. +func (o *orgDomain) CreatedAtColumn() database.Column { + panic("unimplemented") +} + +// DomainColumn implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) DomainColumn() database.Column { + panic("unimplemented") +} + +// InstanceIDColumn implements [domain.OrganizationDomainRepository]. +// Subtle: this method shadows the method (*org).InstanceIDColumn of orgDomain.org. +func (o *orgDomain) InstanceIDColumn() database.Column { + panic("unimplemented") +} + +// IsPrimaryColumn implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) IsPrimaryColumn() database.Column { + panic("unimplemented") +} + +// IsVerifiedColumn implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) IsVerifiedColumn() database.Column { + panic("unimplemented") +} + +// OrgIDColumn implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) OrgIDColumn() database.Column { + panic("unimplemented") +} + +// UpdatedAtColumn implements [domain.OrganizationDomainRepository]. +// Subtle: this method shadows the method (*org).UpdatedAtColumn of orgDomain.org. +func (o *orgDomain) UpdatedAtColumn() database.Column { + panic("unimplemented") +} + +// VerificationTypeColumn implements [domain.OrganizationDomainRepository]. +func (o *orgDomain) VerificationTypeColumn() database.Column { + panic("unimplemented") +} + +// ------------------------------------------------------------- +// scanners +// -------------------------------------------------------------