feat: db constistancy
This commit is contained in:
@@ -39,7 +39,8 @@ CREATE TABLE IF NOT EXISTS "post_views_history" (
|
||||
"deleted_at" TIMESTAMPTZ,
|
||||
"views_count" INT NOT NULL,
|
||||
"fetched_at" TIMESTAMPTZ NOT NULL,
|
||||
"post_id" UUID NOT NULL REFERENCES "post" ("id") ON DELETE CASCADE
|
||||
"post_id" UUID NOT NULL REFERENCES "post" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "uid_post_views__post_id_c6cc9f" UNIQUE ("post_id", "fetched_at")
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "idx_post_views__fetched_103eb5" ON "post_views_history" ("fetched_at");
|
||||
CREATE INDEX IF NOT EXISTS "idx_post_views__post_id_dfb1ca" ON "post_views_history" ("post_id");
|
||||
@@ -76,6 +77,7 @@ CREATE TABLE IF NOT EXISTS "login_token" (
|
||||
"user_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "idx_login_token_token_2582d2" ON "login_token" ("token");
|
||||
CREATE INDEX IF NOT EXISTS "idx_login_token_user_id_c85d7c" ON "login_token" ("user_id");
|
||||
CREATE TABLE IF NOT EXISTS "workspace" (
|
||||
"id" UUID NOT NULL PRIMARY KEY,
|
||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -104,7 +106,6 @@ CREATE TABLE IF NOT EXISTS "creative" (
|
||||
"name" VARCHAR(255) NOT NULL,
|
||||
"text" TEXT NOT NULL,
|
||||
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
|
||||
"placements_count" INT NOT NULL DEFAULT 0,
|
||||
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE,
|
||||
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE
|
||||
);
|
||||
@@ -122,7 +123,6 @@ CREATE TABLE IF NOT EXISTS "placement" (
|
||||
"invite_link_type" VARCHAR(8) NOT NULL,
|
||||
"invite_link" VARCHAR(512) NOT NULL,
|
||||
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
|
||||
"subscriptions_count" INT NOT NULL DEFAULT 0,
|
||||
"creative_id" UUID NOT NULL REFERENCES "creative" ("id") ON DELETE CASCADE,
|
||||
"placement_channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
|
||||
"post_id" UUID REFERENCES "post" ("id") ON DELETE SET NULL,
|
||||
@@ -135,7 +135,7 @@ CREATE INDEX IF NOT EXISTS "idx_placement_post_id_e4a16e" ON "placement" ("post_
|
||||
CREATE INDEX IF NOT EXISTS "idx_placement_project_2c6aa4" ON "placement" ("project_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_placement_workspa_632b20" ON "placement" ("workspace_id");
|
||||
COMMENT ON COLUMN "placement"."invite_link_type" IS 'PUBLIC: public\nAPPROVAL: approval';
|
||||
COMMENT ON COLUMN "placement"."status" IS 'PENDING: pending\nACTIVE: active\nDELETED: deleted\nARCHIVED: archived';
|
||||
COMMENT ON COLUMN "placement"."status" IS 'ACTIVE: active\nARCHIVED: archived';
|
||||
CREATE TABLE IF NOT EXISTS "purchase_plan" (
|
||||
"id" UUID NOT NULL PRIMARY KEY,
|
||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -173,7 +173,8 @@ CREATE TABLE IF NOT EXISTS "subscription" (
|
||||
"status" VARCHAR(12) NOT NULL DEFAULT 'active',
|
||||
"unsubscribed_at" TIMESTAMPTZ,
|
||||
"placement_id" UUID NOT NULL REFERENCES "placement" ("id") ON DELETE CASCADE,
|
||||
"subscriber_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE
|
||||
"subscriber_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "uid_subscriptio_placeme_8fcb8f" UNIQUE ("placement_id", "subscriber_id")
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "idx_subscriptio_invite__f2058d" ON "subscription" ("invite_link");
|
||||
CREATE INDEX IF NOT EXISTS "idx_subscriptio_placeme_5decb2" ON "subscription" ("placement_id");
|
||||
@@ -224,14 +225,18 @@ CREATE TABLE IF NOT EXISTS "workspace_user_permission_scope" (
|
||||
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"deleted_at" TIMESTAMPTZ,
|
||||
"permission" VARCHAR(24) NOT NULL,
|
||||
"scope_type" VARCHAR(9) NOT NULL,
|
||||
"scope_id" UUID NOT NULL,
|
||||
"workspace_user_id" UUID NOT NULL REFERENCES "workspace_user" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "uid_workspace_u_workspa_488ed3" UNIQUE ("workspace_user_id", "permission", "scope_type", "scope_id")
|
||||
"channel_id" UUID REFERENCES "channel" ("id") ON DELETE CASCADE,
|
||||
"creative_id" UUID REFERENCES "creative" ("id") ON DELETE CASCADE,
|
||||
"placement_id" UUID REFERENCES "placement" ("id") ON DELETE CASCADE,
|
||||
"project_id" UUID REFERENCES "project" ("id") ON DELETE CASCADE,
|
||||
"workspace_user_id" UUID NOT NULL REFERENCES "workspace_user" ("id") ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "idx_workspace_u_channel_d94b48" ON "workspace_user_permission_scope" ("channel_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_workspace_u_creativ_8da562" ON "workspace_user_permission_scope" ("creative_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_workspace_u_placeme_ea1846" ON "workspace_user_permission_scope" ("placement_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_workspace_u_project_bd7fea" ON "workspace_user_permission_scope" ("project_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_workspace_u_workspa_82a35a" ON "workspace_user_permission_scope" ("workspace_user_id");
|
||||
COMMENT ON COLUMN "workspace_user_permission_scope"."permission" IS 'ADMIN_FULL: admin_full\nPROJECTS_READ: projects_read\nPROJECTS_WRITE: projects_write\nCREATIVES_READ: creatives_read\nCREATIVES_WRITE: creatives_write\nPLACEMENTS_READ: placements_read\nPLACEMENTS_WRITE: placements_write\nANALYTICS_READ: analytics_read\nANALYTICS_WITHOUT_CLICKS: analytics_without_clicks\nCHANNELS_READ: channels_read\nCHANNELS_WRITE: channels_write';
|
||||
COMMENT ON COLUMN "workspace_user_permission_scope"."scope_type" IS 'PROJECT: project\nCREATIVE: creative\nPLACEMENT: placement\nCHANNEL: channel';
|
||||
CREATE TABLE IF NOT EXISTS "aerich" (
|
||||
"id" SERIAL NOT NULL PRIMARY KEY,
|
||||
"version" VARCHAR(255) NOT NULL,
|
||||
@@ -246,74 +251,74 @@ async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
|
||||
|
||||
MODELS_STATE = (
|
||||
'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'
|
||||
'37jnCt9x2t7SO8Gzcb/f4/gXYk2A=='
|
||||
'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'
|
||||
)
|
||||
@@ -1,98 +0,0 @@
|
||||
# ruff: noqa
|
||||
# mypy: ignore-errors
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
RUN_IN_TRANSACTION = True
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
ALTER TABLE "creative" DROP COLUMN "placements_count";
|
||||
ALTER TABLE "placement" DROP COLUMN "subscriptions_count";
|
||||
COMMENT ON COLUMN "placement"."status" IS 'ACTIVE: active
|
||||
ARCHIVED: archived';
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "uid_subscriptio_placeme_8fcb8f" ON "subscription" ("placement_id", "subscriber_id");"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
DROP INDEX IF EXISTS "uid_subscriptio_placeme_8fcb8f";
|
||||
ALTER TABLE "creative" ADD "placements_count" INT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE "placement" ADD "subscriptions_count" INT NOT NULL DEFAULT 0;
|
||||
COMMENT ON COLUMN "placement"."status" IS 'PENDING: pending
|
||||
ACTIVE: active
|
||||
DELETED: deleted
|
||||
ARCHIVED: archived';"""
|
||||
|
||||
|
||||
MODELS_STATE = (
|
||||
'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'
|
||||
'aq33Ha3tI7wbNxv9/j9vKFN0'
|
||||
)
|
||||
103
migrations/models/1_20251223103601_add_check_constraint.py
Normal file
103
migrations/models/1_20251223103601_add_check_constraint.py
Normal file
@@ -0,0 +1,103 @@
|
||||
# ruff: noqa
|
||||
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
RUN_IN_TRANSACTION = True
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
-- Add CHECK constraint: exactly one FK must be set
|
||||
ALTER TABLE "workspace_user_permission_scope"
|
||||
ADD CONSTRAINT "check_exactly_one_scope"
|
||||
CHECK (
|
||||
(("project_id" IS NOT NULL)::int +
|
||||
("creative_id" IS NOT NULL)::int +
|
||||
("placement_id" IS NOT NULL)::int +
|
||||
("channel_id" IS NOT NULL)::int) = 1
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "workspace_user_permission_scope"
|
||||
IS 'Permission scoped to specific entity (project/creative/placement/channel)';
|
||||
"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
ALTER TABLE "workspace_user_permission_scope"
|
||||
DROP CONSTRAINT IF EXISTS "check_exactly_one_scope";
|
||||
"""
|
||||
|
||||
|
||||
MODELS_STATE = (
|
||||
'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'
|
||||
)
|
||||
@@ -138,17 +138,24 @@ class Postgres(DatabaseBase, Database):
|
||||
)
|
||||
|
||||
if scoped_permissions:
|
||||
await domain.WorkspaceUserPermissionScope.bulk_create(
|
||||
[
|
||||
domain.WorkspaceUserPermissionScope(
|
||||
workspace_user_id=workspace_user_id,
|
||||
permission=permission,
|
||||
scope_type=scope_type,
|
||||
scope_id=scope_id,
|
||||
)
|
||||
for permission, scope_type, scope_id in scoped_permissions
|
||||
]
|
||||
)
|
||||
scope_objects = []
|
||||
for permission, scope_type, scope_id in scoped_permissions:
|
||||
kwargs = {
|
||||
'workspace_user_id': workspace_user_id,
|
||||
'permission': permission,
|
||||
}
|
||||
if scope_type == domain.PermissionScopeType.PROJECT:
|
||||
kwargs['project_id'] = scope_id
|
||||
elif scope_type == domain.PermissionScopeType.CREATIVE:
|
||||
kwargs['creative_id'] = scope_id
|
||||
elif scope_type == domain.PermissionScopeType.PLACEMENT:
|
||||
kwargs['placement_id'] = scope_id
|
||||
elif scope_type == domain.PermissionScopeType.CHANNEL:
|
||||
kwargs['channel_id'] = scope_id
|
||||
|
||||
scope_objects.append(domain.WorkspaceUserPermissionScope(**kwargs))
|
||||
|
||||
await domain.WorkspaceUserPermissionScope.bulk_create(scope_objects)
|
||||
|
||||
async def create_login_token(self, login_token: domain.LoginToken) -> None:
|
||||
await login_token.save()
|
||||
|
||||
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
class LoginToken(TimestampedModel):
|
||||
token = fields.CharField(max_length=255, unique=True, index=True)
|
||||
user: fields.ForeignKeyRelation['User'] = fields.ForeignKeyField(
|
||||
'models.User', related_name='login_tokens', on_delete=fields.CASCADE
|
||||
'models.User', related_name='login_tokens', on_delete=fields.CASCADE, index=True
|
||||
)
|
||||
expires_at = fields.DatetimeField()
|
||||
used_at = fields.DatetimeField(null=True)
|
||||
|
||||
@@ -22,3 +22,4 @@ class PostViewsHistory(TimestampedModel):
|
||||
|
||||
class Meta:
|
||||
table = 'post_views_history'
|
||||
unique_together = (('post_id', 'fetched_at'),)
|
||||
|
||||
@@ -9,6 +9,10 @@ from tortoise import fields
|
||||
from .base import TimestampedModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .channel import Channel
|
||||
from .creative import Creative
|
||||
from .placement import Placement
|
||||
from .project import Project
|
||||
from .user import User
|
||||
|
||||
|
||||
@@ -117,16 +121,31 @@ class WorkspaceUserPermission(TimestampedModel):
|
||||
|
||||
class WorkspaceUserPermissionScope(TimestampedModel):
|
||||
permission = fields.CharEnumField(PermissionKey)
|
||||
scope_type = fields.CharEnumField(PermissionScopeType)
|
||||
scope_id = fields.UUIDField()
|
||||
|
||||
workspace_user: fields.ForeignKeyRelation[WorkspaceUser] = fields.ForeignKeyField(
|
||||
'models.WorkspaceUser', related_name='permission_scopes', on_delete=fields.CASCADE, index=True
|
||||
)
|
||||
|
||||
# Exactly one of these must be set (enforced by CHECK constraint in migration)
|
||||
project: fields.ForeignKeyRelation[Project] | None = fields.ForeignKeyField(
|
||||
'models.Project', related_name='permission_scopes', on_delete=fields.CASCADE, null=True, index=True
|
||||
)
|
||||
creative: fields.ForeignKeyRelation[Creative] | None = fields.ForeignKeyField(
|
||||
'models.Creative', related_name='permission_scopes', on_delete=fields.CASCADE, null=True, index=True
|
||||
)
|
||||
placement: fields.ForeignKeyRelation[Placement] | None = fields.ForeignKeyField(
|
||||
'models.Placement', related_name='permission_scopes', on_delete=fields.CASCADE, null=True, index=True
|
||||
)
|
||||
channel: fields.ForeignKeyRelation[Channel] | None = fields.ForeignKeyField(
|
||||
'models.Channel', related_name='permission_scopes', on_delete=fields.CASCADE, null=True, index=True
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
workspace_user_id: uuid.UUID
|
||||
project_id: uuid.UUID | None
|
||||
creative_id: uuid.UUID | None
|
||||
placement_id: uuid.UUID | None
|
||||
channel_id: uuid.UUID | None
|
||||
|
||||
class Meta:
|
||||
table = 'workspace_user_permission_scope'
|
||||
unique_together = (('workspace_user_id', 'permission', 'scope_type', 'scope_id'),)
|
||||
|
||||
@@ -23,8 +23,18 @@ class WorkspacePermissions:
|
||||
|
||||
scoped_permissions: dict[tuple[PermissionKey, PermissionScopeType], set[UUID]] = {}
|
||||
for scope in getattr(membership, 'permission_scopes', []) or []:
|
||||
key = (scope.permission, scope.scope_type)
|
||||
scoped_permissions.setdefault(key, set()).add(scope.scope_id)
|
||||
if scope.project_id:
|
||||
key = (scope.permission, PermissionScopeType.PROJECT)
|
||||
scoped_permissions.setdefault(key, set()).add(scope.project_id)
|
||||
elif scope.creative_id:
|
||||
key = (scope.permission, PermissionScopeType.CREATIVE)
|
||||
scoped_permissions.setdefault(key, set()).add(scope.creative_id)
|
||||
elif scope.placement_id:
|
||||
key = (scope.permission, PermissionScopeType.PLACEMENT)
|
||||
scoped_permissions.setdefault(key, set()).add(scope.placement_id)
|
||||
elif scope.channel_id:
|
||||
key = (scope.permission, PermissionScopeType.CHANNEL)
|
||||
scoped_permissions.setdefault(key, set()).add(scope.channel_id)
|
||||
|
||||
return cls(global_permissions=global_permissions, scoped_permissions=scoped_permissions)
|
||||
|
||||
|
||||
@@ -37,6 +37,17 @@ async def fetch_placement_post_cycle(self: 'Usecase', interval_seconds: int) ->
|
||||
).first()
|
||||
|
||||
if matching_post:
|
||||
# Validate channel consistency
|
||||
if matching_post.channel_id != placement.placement_channel_id:
|
||||
log.error(
|
||||
'Post %s channel_id mismatch: expected %s, got %s. Skipping placement %s',
|
||||
matching_post.id,
|
||||
placement.placement_channel_id,
|
||||
matching_post.channel_id,
|
||||
placement.id,
|
||||
)
|
||||
continue
|
||||
|
||||
placement.post = matching_post
|
||||
await placement.save()
|
||||
updated_count += 1
|
||||
|
||||
Reference in New Issue
Block a user