package setup import ( "fmt" "github.com/zitadel/zitadel/internal/api/scim/metadata" "github.com/zitadel/zitadel/internal/database" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/migration" "github.com/zitadel/zitadel/internal/query/projection" "github.com/zitadel/zitadel/internal/serviceping" ) // triggerSteps defines the repeatable migrations that set up triggers // for counting resources in the database. func triggerSteps(db *database.DB) []migration.RepeatableMigration { return []migration.RepeatableMigration{ // Delete parent count triggers for instances and organizations migration.DeleteParentCountsTrigger(db, projection.InstanceProjectionTable, domain.CountParentTypeInstance, projection.InstanceColumnID, projection.InstanceColumnID, serviceping.ResourceCountInstance, ), migration.DeleteParentCountsTrigger(db, projection.OrgProjectionTable, domain.CountParentTypeOrganization, projection.OrgColumnInstanceID, projection.OrgColumnID, serviceping.ResourceCountOrganization, ), // Count triggers for all the resources migration.CountTrigger(db, projection.OrgProjectionTable, domain.CountParentTypeInstance, projection.OrgColumnInstanceID, projection.OrgColumnInstanceID, serviceping.ResourceCountOrganization, ), migration.CountTrigger(db, projection.ProjectProjectionTable, domain.CountParentTypeOrganization, projection.ProjectColumnInstanceID, projection.ProjectColumnResourceOwner, serviceping.ResourceCountProject, ), migration.CountTrigger(db, projection.UserTable, domain.CountParentTypeOrganization, projection.UserInstanceIDCol, projection.UserResourceOwnerCol, serviceping.ResourceCountUser, ), migration.CountTriggerConditional(db, projection.UserTable, domain.CountParentTypeOrganization, projection.UserInstanceIDCol, projection.UserResourceOwnerCol, serviceping.ResourceCountUserMachine, false, // the user type cannot change, so we do not need to track updates &migration.TriggerCondition{ Column: projection.UserTypeCol, // since we marshal the value into and from json, // we directly use the float64 value to prevent issues with the comparison of the previous migration Value: float64(2), }, ), migration.CountTrigger(db, projection.InstanceMemberProjectionTable, domain.CountParentTypeInstance, projection.MemberInstanceID, projection.MemberResourceOwner, serviceping.ResourceCountIAMAdmin, ), migration.CountTrigger(db, projection.IDPTable, domain.CountParentTypeInstance, projection.IDPInstanceIDCol, projection.IDPInstanceIDCol, serviceping.ResourceCountIdentityProvider, ), migration.CountTrigger(db, projection.IDPTemplateLDAPTable, domain.CountParentTypeInstance, projection.LDAPInstanceIDCol, projection.LDAPInstanceIDCol, serviceping.ResourceCountIdentityProviderLDAP, ), migration.CountTrigger(db, projection.ActionTable, domain.CountParentTypeInstance, projection.ActionInstanceIDCol, projection.ActionInstanceIDCol, serviceping.ResourceCountActionV1, ), migration.CountTrigger(db, projection.ExecutionTable, domain.CountParentTypeInstance, projection.ExecutionInstanceIDCol, projection.ExecutionInstanceIDCol, serviceping.ResourceCountActionExecution, ), migration.CountTrigger(db, fmt.Sprintf("%s_%s", projection.ExecutionTable, projection.ExecutionTargetSuffix), domain.CountParentTypeInstance, projection.ExecutionTargetInstanceIDCol, projection.ExecutionTargetInstanceIDCol, serviceping.ResourceCountActionExecutionTarget, ), migration.CountTrigger(db, projection.LoginPolicyTable, domain.CountParentTypeInstance, projection.LoginPolicyInstanceIDCol, projection.LoginPolicyInstanceIDCol, serviceping.ResourceCountLoginPolicy, ), migration.CountTriggerConditional(db, projection.LoginPolicyTable, domain.CountParentTypeInstance, projection.LoginPolicyInstanceIDCol, projection.LoginPolicyInstanceIDCol, serviceping.ResourceCountEnforceMFA, true, &migration.OrCondition{ Conditions: []migration.TriggerCondition{ {Column: projection.LoginPolicyForceMFACol, Value: true}, {Column: projection.LoginPolicyForceMFALocalOnlyCol, Value: true}, }, }, ), migration.CountTrigger(db, projection.PasswordComplexityTable, domain.CountParentTypeInstance, projection.ComplexityPolicyInstanceIDCol, projection.ComplexityPolicyInstanceIDCol, serviceping.ResourceCountPasswordComplexityPolicy, ), migration.CountTrigger(db, projection.PasswordAgeTable, domain.CountParentTypeInstance, projection.AgePolicyInstanceIDCol, projection.AgePolicyInstanceIDCol, serviceping.ResourceCountPasswordExpiryPolicy, ), migration.CountTrigger(db, projection.LockoutPolicyTable, domain.CountParentTypeInstance, projection.LockoutPolicyInstanceIDCol, projection.LockoutPolicyInstanceIDCol, serviceping.ResourceCountLockoutPolicy, ), migration.CountTriggerConditional(db, projection.NotificationPolicyProjectionTable, domain.CountParentTypeInstance, projection.NotificationPolicyColumnInstanceID, projection.NotificationPolicyColumnInstanceID, serviceping.ResourceCountPasswordChangeNotification, true, &migration.TriggerCondition{ Column: projection.NotificationPolicyColumnPasswordChange, Value: true, }, ), migration.CountTriggerConditional(db, projection.UserMetadataProjectionTable, domain.CountParentTypeOrganization, projection.UserMetadataColumnInstanceID, projection.LockoutPolicyResourceOwnerCol, serviceping.ResourceCountScimProvisionedUser, false, // the key cannot change, so we do not need to track updates &migration.TriggerCondition{ Column: projection.UserMetadataColumnKey, Value: metadata.KeyEmails, }, ), } }