домен обновлен

This commit is contained in:
Artem Tsyrulnikov
2026-01-07 15:11:28 +03:00
parent f6669c3f5a
commit e4199fc9c9
30 changed files with 696 additions and 1201 deletions

View File

@@ -1,335 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE TABLE IF NOT EXISTS "channel"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"telegram_id" BIGINT NOT NULL UNIQUE,
"title" VARCHAR(255) NOT NULL,
"username" VARCHAR(255) NOT NULL UNIQUE,
"access_hash" BIGINT,
"pts" INT
);
CREATE INDEX IF NOT EXISTS "idx_channel_telegra_414c3b" ON "channel" ("telegram_id");
CREATE INDEX IF NOT EXISTS "idx_channel_usernam_7fd87a" ON "channel" ("username");
CREATE TABLE IF NOT EXISTS "post"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"message_id" INT NOT NULL,
"text" TEXT NOT NULL,
"deleted_from_channel_at" TIMESTAMPTZ,
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_post_channel_0a2cba" UNIQUE ("channel_id", "message_id")
);
CREATE INDEX IF NOT EXISTS "idx_post_channel_197bed" ON "post" ("channel_id");
CREATE TABLE IF NOT EXISTS "post_views_history"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"views_count" INT NOT NULL,
"fetched_at" TIMESTAMPTZ NOT NULL,
"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");
CREATE TABLE IF NOT EXISTS "user"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"telegram_id" BIGINT NOT NULL UNIQUE,
"username" VARCHAR(255),
"first_name" VARCHAR(255),
"last_name" VARCHAR(255)
);
CREATE INDEX IF NOT EXISTS "idx_user_telegra_66ffbd" ON "user" ("telegram_id");
CREATE TABLE IF NOT EXISTS "login_token"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"token" VARCHAR(255) NOT NULL UNIQUE,
"expires_at" TIMESTAMPTZ NOT NULL,
"used_at" TIMESTAMPTZ,
"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,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"name" VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS "project"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"purchase_invite_type_default" VARCHAR(10) NOT NULL DEFAULT 'approval',
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_project_workspa_2f80f2" UNIQUE ("workspace_id", "channel_id")
);
CREATE INDEX IF NOT EXISTS "idx_project_channel_ce2466" ON "project" ("channel_id");
CREATE INDEX IF NOT EXISTS "idx_project_workspa_2354fd" ON "project" ("workspace_id");
COMMENT ON COLUMN "project"."status" IS 'ACTIVE: active\nINACTIVE: inactive\nARCHIVED: archived';
COMMENT ON COLUMN "project"."purchase_invite_type_default" IS 'PUBLIC: public\nAPPROVAL: approval';
CREATE TABLE IF NOT EXISTS "creative"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"name" VARCHAR(255) NOT NULL,
"text" TEXT NOT NULL,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_creative_project_0766a6" ON "creative" ("project_id");
CREATE INDEX IF NOT EXISTS "idx_creative_workspa_2de546" ON "creative" ("workspace_id");
COMMENT ON COLUMN "creative"."status" IS 'ACTIVE: active\nARCHIVED: archived';
CREATE TABLE IF NOT EXISTS "purchase"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"creative_id" UUID NOT NULL REFERENCES "creative" ("id") ON DELETE CASCADE,
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_purchase_creativ_6829cd" ON "purchase" ("creative_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_project_95b1c2" ON "purchase" ("project_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_workspa_8784a5" ON "purchase" ("workspace_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_project_dee224" ON "purchase" ("project_id", "status");
COMMENT ON COLUMN "purchase"."status" IS 'ACTIVE: active\nARCHIVED: archived';
CREATE TABLE IF NOT EXISTS "purchase_channel"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(11) NOT NULL DEFAULT 'planned',
"planned_cost" DOUBLE PRECISION,
"comment" TEXT,
"invite_link" VARCHAR(512) NOT NULL,
"invite_link_type" VARCHAR(8) NOT NULL,
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
"purchase_id" UUID NOT NULL REFERENCES "purchase" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_purchase_ch_purchas_f7c86e" UNIQUE ("purchase_id", "channel_id")
);
CREATE INDEX IF NOT EXISTS "idx_purchase_ch_channel_2b1264" ON "purchase_channel" ("channel_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_ch_purchas_1fe84a" ON "purchase_channel" ("purchase_id");
COMMENT ON COLUMN "purchase_channel"."status" IS 'PLANNED: planned\nAPPROVED: approved\nREJECTED: rejected\nIN_PROGRESS: in_progress\nCOMPLETED: completed';
COMMENT ON COLUMN "purchase_channel"."invite_link_type" IS 'PUBLIC: public\nAPPROVAL: approval';
CREATE TABLE IF NOT EXISTS "placement"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"wanted_placement_date" TIMESTAMPTZ NOT NULL,
"cost" DOUBLE PRECISION,
"comment" TEXT,
"invite_link" VARCHAR(512) NOT NULL,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"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,
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE,
"purchase_id" UUID REFERENCES "purchase" ("id") ON DELETE CASCADE,
"purchase_channel_id" UUID REFERENCES "purchase_channel" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_placement_creativ_32111d" ON "placement" ("creative_id");
CREATE INDEX IF NOT EXISTS "idx_placement_placeme_20cf53" ON "placement" ("placement_channel_id");
CREATE INDEX IF NOT EXISTS "idx_placement_post_id_e4a16e" ON "placement" ("post_id");
CREATE INDEX IF NOT EXISTS "idx_placement_project_2c6aa4" ON "placement" ("project_id");
CREATE INDEX IF NOT EXISTS "idx_placement_purchas_3e3775" ON "placement" ("purchase_id");
CREATE INDEX IF NOT EXISTS "idx_placement_purchas_61f9e6" ON "placement" ("purchase_channel_id");
CREATE INDEX IF NOT EXISTS "idx_placement_workspa_632b20" ON "placement" ("workspace_id");
COMMENT ON COLUMN "placement"."status" IS 'ACTIVE: active\nARCHIVED: archived';
CREATE TABLE IF NOT EXISTS "subscription"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"invite_link" VARCHAR(512) NOT NULL,
"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,
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");
CREATE INDEX IF NOT EXISTS "idx_subscriptio_subscri_e75729" ON "subscription" ("subscriber_id");
COMMENT ON COLUMN "subscription"."status" IS 'ACTIVE: active\nUNSUBSCRIBED: unsubscribed';
CREATE TABLE IF NOT EXISTS "workspace_invite"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(8) NOT NULL DEFAULT 'pending',
"invited_by_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"user_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_workspace_i_workspa_abd9c4" UNIQUE ("workspace_id", "user_id")
);
CREATE INDEX IF NOT EXISTS "idx_workspace_i_invited_3ed9f8" ON "workspace_invite" ("invited_by_id");
CREATE INDEX IF NOT EXISTS "idx_workspace_i_user_id_a96e1e" ON "workspace_invite" ("user_id");
CREATE INDEX IF NOT EXISTS "idx_workspace_i_workspa_71e9d2" ON "workspace_invite" ("workspace_id");
COMMENT ON COLUMN "workspace_invite"."status" IS 'PENDING: pending\nACCEPTED: accepted\nREVOKED: revoked';
CREATE TABLE IF NOT EXISTS "workspace_user"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(7) NOT NULL DEFAULT 'active',
"user_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_workspace_u_workspa_13c46c" UNIQUE ("workspace_id", "user_id")
);
CREATE INDEX IF NOT EXISTS "idx_workspace_u_user_id_246318" ON "workspace_user" ("user_id");
CREATE INDEX IF NOT EXISTS "idx_workspace_u_workspa_a403b0" ON "workspace_user" ("workspace_id");
COMMENT ON COLUMN "workspace_user"."status" IS 'ACTIVE: active\nINVITED: invited\nBLOCKED: blocked';
CREATE TABLE IF NOT EXISTS "workspace_user_permission"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"permission" VARCHAR(24) NOT NULL,
"workspace_user_id" UUID NOT NULL REFERENCES "workspace_user" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_workspace_u_workspa_86f574" UNIQUE ("workspace_user_id", "permission")
);
CREATE INDEX IF NOT EXISTS "idx_workspace_u_workspa_b9b7b0" ON "workspace_user_permission" ("workspace_user_id");
COMMENT ON COLUMN "workspace_user_permission"."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';
CREATE TABLE IF NOT EXISTS "workspace_user_permission_scope"
(
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"permission" VARCHAR(24) NOT NULL,
"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';
CREATE TABLE IF NOT EXISTS "aerich"
(
"id" SERIAL NOT NULL PRIMARY KEY,
"version" VARCHAR(255) NOT NULL,
"app" VARCHAR(100) NOT NULL,
"content" JSONB NOT NULL
);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
"""
MODELS_STATE = (
'eJztXWtv2zoS/SuGP/UC2SJxnCa3WCxgO26rW8c2/Ei7ty0ERWYcbWTJV5KTBkX/+5KSaI'
'l6WS9HlD1fipTk0OIZkpo5Gg5/NVf6Aqnm296DpGlIbb5v/Gpq0grhP4JVJ42mtF57FaTA'
'ku5Uu63sa3RnWoYkW7j4XlJNhIsWyJQNZW0puoZLtY2qkkJdxg0VbekVbTTlnw0SLX2JrA'
'dk4IpvP3Cxoi3QT2TS/64fxXsFqQvmYZUF+W27XLRe1nbZfC5cf7Bbkp+7E2Vd3aw0r/X6'
'xXrQtW3zzUZZvCUypG6JNGRIFlr4hkGe0h0wLXKeGBdYxgZtH3XhFSzQvbRRCRjNf99vNJ'
'lg0LB/ifzT/k8zAzyyrhFoFc0iWPz67YzKG7Nd2iQ/1fvUmbw5f/eHPUrdtJaGXWkj0vxt'
'C0qW5IjauHpAygYiwxYlKwzoNa6xlBWKBpWVDIC7cEXf0j/ygEwLPJS9GUZhpvDlw7SJx7'
'AYaeqLq8EEjGfCTX8669yMyUhWpvmPakPUmfVJTcsufQmUvnFUouP14aybbSeNL8LsU4P8'
't/H3aNgPKm7bbvZ3kzyTtLF0UdOfRWnhm2y0lAKDW3qK3awXORXLSoJiK1Ws+/CeXvFejP'
'LplZUsQa/u076iWmuiRjrsxAVqYXUsDWklRr3LuspS0KxoPQYEA4rEUO3nhVZwQS7Jr/zr'
'z1br/PyydXr+7uqifXl5cXV6hdvajxSuukxQd1f4KAxnrPZIwW8WY8VSURhdbOMYMdhSgQ'
'CqeCicbnQr6aeoIm1pPeD/ti4uEjC77UxsSwG3Csz7oVvVcupYEDcmMuy/M+DolykHyr1P'
'0P0DKckyMk3xQTIfsq34gGCuFf/6m3U1S35tmWFwY5F1W9cL0dZZ+7J9df6uvQVyW5KEn4'
'MVcanuH32+ACm4k+THZ8lYiEyND1RVktEKaVHYdl3ZD58nSJXsIYURdZ3LMe2Hz830N50e'
'tDTKACN2QFEYcBd1RsDQ/4fkwiA4vdQZh40h4z0ZiS4dUhQQtzsfA1NXYJCxUkwTdy2ask'
'72oELAfNGNR3ONd445tirG276npGsu9+lYkMheq7f0uN03XLVqrYIlkiYt7acmv01+iRJ3'
'hI9RnlAzitSjdSeJrJ6/FdB6QOsB+wO0HigWaD2g9dLTelmZknJZkoMgnCz0M2IVzHBpHC'
'H6M2rucwth0nTvf50xM50C9eam8/UPZrYPRsOPtLkP2N5g1A3gaVqStYmwwcmk7GublY2q'
'gB9R0mQUQteTfj18m9jydA1RFuNmpzcTbvvvG06D7xpBBxdc4xLsPeEiZ3pknMZXKSbxVe'
'wUvgpOYNdBjmT2481ZVqpMszYMecnkaREj1oPtmfp5GYELyh0JdCEmLwLJMIwfdAMpS+0z'
'egkt+x3eN8/whVxtXGxIz1sXMzRH8Dgdw8kGujPtda77zahFXAKCpTJdFeHHbk7R6AGTnI'
'8/LIk3rDMSQBi+PmE40JeKNtMfkdaMoAx9tSdJpKFK2onWtiHwhsAbAr0EvCEoFnhD4A0z'
'hAPSN2jqUDUqAPFVLoTo51rBGsmxFljJeu5xh7QYNma+V5UJ+xlHKjQy8ng+EaDwCBglcE'
'9ztxteQdtJPPkmRVbWaZ/Os8c/RfjODDkV7zqvmWbgOIPjXFfb42D8K3CcD1Sx4DgfqqH5'
'LGlEG9uXqUiQz6rT2E7quWwPSb+ye1giYAiruhQTDkQFAqq7JxJ1W43Xo3l30G+MJ/2eMB'
'VGQ1Y9diUpwgWKYxZP+p1BgBaR9RU1MtNGVPlEcrFLXGG4l5gqRXvCiIuqoj1mIe0CYnWJ'
'WGPJu4uzVgryDreKJe/sOghSqzRIjZ72yEjSBMSOhKhhghW2RoJ77itrnF+M/DFCiauzou'
'eJFABs9wuKT7wgsDQXbPSgZkbcWLEjnG6BA6558Sttn6spjhDYDIHNENjMJ35pApujzOYS'
'4POfyq4tfgF/IMX0C5q/ZSBZZsqEqiZijFuQAlFfAHjRFZ0+lryqd/FuIFmzLT1+JU7I7L'
'k8+Icz87SMJm4zQ5kuWQ6/+HkOK4PZtD9rDOeDQbpzM+bmbvuUBU9HTH1d8Uk3wpkRXs+M'
'2IsxKuLFXaQJwS60RalxLt+a7K60QqaJn5z87wfEwOyaOxADU+J6PJhQCYiBOVDFQgzMoc'
'ZI+F57IUXG5j5lhcpJI/0Kq7GEHKiQbGZ/gRF0Z7g39NXWZcy/wUR0A7tN1RFZub4GHeXH'
'7oRPGcB+MjRyCnKJ1/wiHPn+/mX6pKBnU3xQTEs3lMJJRvDcviUdfrL7e+H6Zff6nAgDTQ'
'w/EoQvmSsR/ep72Qdz4g++QZb84JjzQJsAbQLeNdAmoFigTQ7dkXFesbK+iTodEcubBKSO'
'lTjx2QwZVwEr+Tq72+t5hLVbBZUFYXOltvyO/OvGOfDrwscFOlSdqcENUozyyrz4xQRnzN'
'eoZA8sGLvpI0HADQM3DKx1cMNAseCGHboBeshHf4UhLVE0ro8De1HTzhF10qFIR5xTNbv6'
'fE2FrbEd9ySpESobz7sDofe+sd7cqYqM1TMeT0a3nQFWj18oo3rOTlPo5+w0VkGkKnBgGz'
'67prfz4PAdfLGu/ot15DwsAb9jOrqY5qs/PYRW8CN3uQfyqjkVAferwP0qcFaGi7gQOm+i'
'mEffnEqgHv2t9pkf9puf5XQdqh9AOQLlCMwUUI7Hq1igHIFyrB/lyCW9CNkGIeUbsH7cQp'
'cU3gLpoiBdVHXpooA2DUJYHm0Kh6WC3zZKogpL/b5xUGQYRSaBE/OBt5sa8+fsKv2AFJtI'
'DKLz9m6/AVV24IwKUGUHqligyoAq44Yqw3YtflMvIriy8aAzHBJqzG1Co71stsyO9iJlk/'
'5f/d6MlBmIeHukTBiKuOHHSX86JbF8Im5LUDa/a73RzXjQt5vL+mptT948jNvZWZqIsbP4'
'iLGzUEyfM0gx8xVKQUG4SgmuUrKHCVcpFX7j7/8qJR8yDh459+6ofiqGeU/BumV/7IBI3W'
'aeTx1VX9NSJ+CSGPtK8sHzS5hmTggPgc6QmqtW7CqT0j2CWg2mfI/nVc1gy7I51e0tF850'
'cn/vDhnAqwKvCvQb8KqgWOBVj4FX5Zv2KNnWhAukC4V0zofTeXfamwhdwjJvtK3VlI9oTo'
'N+Avhh7P1PlOeNExaH7anqrGABQz01GxOQOxI6htmJGJ8mA3YhwSMBL4nL8jv7Rcmscs+0'
'Vn5PZFo6y5tWJYBIjnzWGr/QIuMpWZ2NbgSBQ1GPJ242tMU+z4kCHwN8DLjtwMccr2KBjz'
'lUh8fC6lga0irSZu8qy9h84AHBcvKB736hFVyQTjbwP1ut8/PL1un5u6uL9uXlxdXpNi14'
'uCopP3hX+EhShDPaC+cMJ0aK/XcI4HjCyy9Tkwgqlm5pXVyk4Ftwq1jCxa4LZF9XDNMSs2'
'LJSgGaFE1VygEmI3TcWIYc+DTxAKq+VDBi+iMqeqP5gPQ0Ix3xaf2kOoEGN7yHELFJDvt7'
'R1kJqwS7txpj4jv8CcBEA0MMhjITnNUMlH3SU94B6giOijldHU9UMQe6ga0CtioMLpAawF'
'aBYoGtArYqdoFmdVYL+alVLEGOHFXILg3ZpSOwcDJBFUWizJxY1eAAWbaZiE7wyMEjr8Aj'
'd6dLkl/uzagU3rnLL5XvpIevPSTTA07/gP8Obh7476BY8N+PwX+v4WmVNdIWRD0hBTbH/e'
'G1MPz4vuE2+a51er3+2E6JJMkyWltOVqXb0WcnqdKT/pjv6ErJiTocG2ch3r1kjNQPCR5J'
'pH4wmCcjbD6RIwQMcpKXdSoEkkKf5EoKHb33lQBi7U+FhDb03QDSExfHDp1vU+fpKA3LGC'
'XxIrsP17BUFnAiwIkAJ8KVzwWcyNEoFjgR4ES44URSZ/AQhreCzYe4huZ3rTsY9Ww65E7V'
'5Zx0SNKJHEqHXMbSIZehNB7g0YNHDx49H25Vdo8eHNLCDmnUlen7uSydTysxXcQPV7fJ84'
'TSq/EZvnm0i9lgp1xajkNcs2J7ozv8BoT3k0B7AO0B3jHQHqBYoD0OnfZg37R5qA+2h6qv'
'aOlc3whD8cN8QC5lWawUTbzH7b5r48mIXKs1FSf9DrmBy42fF8kK9dV+mQizvq/62VAs9F'
'3rYSlCqVDx7aEMV96rdzvwGrg9jAedXv+mP/SeYHuagT6D14I+hdfE7aUz7Az+OxN6tBNs'
'rqkvliLTPrx6MnNG85nYGwi9z1N/y2cFa2hjibKqyI/kBrFP5FaywXZo7l20dGS0lg6MVt'
'tPlIc2arXTnKZpxx+maQeZo0h7LjsbcnxsUhpKRCzJsd9DDH3l3EgdPj4Hfdr0HtvWB87h'
'tjm+efnOG3hme9gGwDM7eAMePLMDVSx4ZuCZgWcGnhmfnlnFd5Hu3oC4ccUY1NwpmhU2Vu'
'z4cOPg1pC6IufsqllxY6SODzXgnYB34pN3iljbJUCZPl1MVQt69/01zJaV4jJmX9qkguhl'
'yMDELXwBEyPF5KvoBiVuEcx+gVIV94FzC1+x68D3Sbp3kKHID80Iet2tOUki0iWvDTd8ee'
'ydE2mvmnAVWIwnL8jzOTdNtM7al+2r83ft7QUT25KkKHZ6h0Q8Pf6EjHiGJho9n8iR50P0'
'73JkaWQA0W1eTwDPTk9TAIhbxV+CSuoCpIGuWZHv2b+mo2EMYeCJBICca3iA3xaKbJ00VM'
'W0fvAJawKKZNQM00vBe3PT+RrEtTcYdYOuCumgmy1pZ/mvl9//Bz1kVX4='
)

View File

@@ -0,0 +1,342 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
CREATE TABLE IF NOT EXISTS "channel" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"telegram_id" BIGINT NOT NULL UNIQUE,
"title" VARCHAR(255) NOT NULL,
"username" VARCHAR(255) NOT NULL UNIQUE,
"access_hash" BIGINT,
"pts" INT
);
CREATE INDEX IF NOT EXISTS "idx_channel_telegra_414c3b" ON "channel" ("telegram_id");
CREATE INDEX IF NOT EXISTS "idx_channel_usernam_7fd87a" ON "channel" ("username");
CREATE TABLE IF NOT EXISTS "post" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"message_id" INT NOT NULL,
"text" TEXT NOT NULL,
"deleted_from_channel_at" TIMESTAMPTZ,
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_post_channel_0a2cba" UNIQUE ("channel_id", "message_id")
);
CREATE INDEX IF NOT EXISTS "idx_post_channel_197bed" ON "post" ("channel_id");
CREATE TABLE IF NOT EXISTS "post_views_history" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"views_count" INT NOT NULL,
"fetched_at" TIMESTAMPTZ NOT NULL,
"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");
CREATE TABLE IF NOT EXISTS "telegram_user" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"telegram_id" BIGINT NOT NULL UNIQUE,
"username" VARCHAR(255),
"first_name" VARCHAR(255),
"last_name" VARCHAR(255)
);
CREATE INDEX IF NOT EXISTS "idx_telegram_us_telegra_3a3100" ON "telegram_user" ("telegram_id");
CREATE TABLE IF NOT EXISTS "user" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"telegram_user_id" UUID NOT NULL UNIQUE REFERENCES "telegram_user" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_user_telegra_444a03" ON "user" ("telegram_user_id");
CREATE TABLE IF NOT EXISTS "login_token" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"token" VARCHAR(255) NOT NULL UNIQUE,
"expires_at" TIMESTAMPTZ NOT NULL,
"used_at" TIMESTAMPTZ,
"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,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"name" VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS "project" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"purchase_invite_type_default" VARCHAR(10) NOT NULL DEFAULT 'approval',
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_project_workspa_2f80f2" UNIQUE ("workspace_id", "channel_id")
);
CREATE INDEX IF NOT EXISTS "idx_project_channel_ce2466" ON "project" ("channel_id");
CREATE INDEX IF NOT EXISTS "idx_project_workspa_2354fd" ON "project" ("workspace_id");
COMMENT ON COLUMN "project"."status" IS 'ACTIVE: active\nINACTIVE: inactive\nARCHIVED: archived';
COMMENT ON COLUMN "project"."purchase_invite_type_default" IS 'PUBLIC: public\nAPPROVAL: approval';
CREATE TABLE IF NOT EXISTS "creative" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"name" VARCHAR(255) NOT NULL,
"text" TEXT NOT NULL,
"media_type" VARCHAR(32),
"media_file_id" VARCHAR(512),
"media_s3_key" VARCHAR(512),
"buttons" JSONB NOT NULL,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_creative_project_0766a6" ON "creative" ("project_id");
COMMENT ON COLUMN "creative"."status" IS 'ACTIVE: active\nARCHIVED: archived';
CREATE TABLE IF NOT EXISTS "purchase" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"placement_at" TIMESTAMPTZ,
"payment_at" TIMESTAMPTZ,
"cost_type" VARCHAR(8),
"cost_value" DOUBLE PRECISION,
"cost_before_bargain" DOUBLE PRECISION,
"purchase_type" VARCHAR(16),
"format" TEXT,
"comment" TEXT,
"creative_id" UUID NOT NULL REFERENCES "creative" ("id") ON DELETE CASCADE,
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_purchase_creativ_6829cd" ON "purchase" ("creative_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_project_95b1c2" ON "purchase" ("project_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_project_dee224" ON "purchase" ("project_id", "status");
COMMENT ON COLUMN "purchase"."status" IS 'ACTIVE: active\nARCHIVED: archived';
COMMENT ON COLUMN "purchase"."cost_type" IS 'FIXED: fixed\nCPM: cpm';
COMMENT ON COLUMN "purchase"."purchase_type" IS 'SELF_PROMO: self_promo\nSTANDARD: standard';
CREATE TABLE IF NOT EXISTS "purchase_channel" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(11) NOT NULL DEFAULT 'planned',
"placement_at" TIMESTAMPTZ,
"cost_type" VARCHAR(8),
"cost_value" DOUBLE PRECISION,
"cost_before_bargain" DOUBLE PRECISION,
"format" TEXT,
"comment" TEXT,
"invite_link" VARCHAR(512) NOT NULL,
"invite_link_type" VARCHAR(8) NOT NULL,
"channel_id" UUID NOT NULL REFERENCES "channel" ("id") ON DELETE CASCADE,
"purchase_id" UUID NOT NULL REFERENCES "purchase" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_purchase_ch_purchas_f7c86e" UNIQUE ("purchase_id", "channel_id")
);
CREATE INDEX IF NOT EXISTS "idx_purchase_ch_channel_2b1264" ON "purchase_channel" ("channel_id");
CREATE INDEX IF NOT EXISTS "idx_purchase_ch_purchas_1fe84a" ON "purchase_channel" ("purchase_id");
COMMENT ON COLUMN "purchase_channel"."status" IS 'PLANNED: planned\nAPPROVED: approved\nREJECTED: rejected\nIN_PROGRESS: in_progress\nCOMPLETED: completed';
COMMENT ON COLUMN "purchase_channel"."cost_type" IS 'FIXED: fixed\nCPM: cpm';
COMMENT ON COLUMN "purchase_channel"."invite_link_type" IS 'PUBLIC: public\nAPPROVAL: approval';
CREATE TABLE IF NOT EXISTS "placement" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"wanted_placement_date" TIMESTAMPTZ NOT NULL,
"cost" DOUBLE PRECISION,
"comment" TEXT,
"status" VARCHAR(8) NOT NULL DEFAULT 'active',
"creative_id" UUID NOT NULL REFERENCES "creative" ("id") ON DELETE CASCADE,
"post_id" UUID REFERENCES "post" ("id") ON DELETE SET NULL,
"project_id" UUID NOT NULL REFERENCES "project" ("id") ON DELETE CASCADE,
"purchase_channel_id" UUID NOT NULL REFERENCES "purchase_channel" ("id") ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS "idx_placement_creativ_32111d" ON "placement" ("creative_id");
CREATE INDEX IF NOT EXISTS "idx_placement_post_id_e4a16e" ON "placement" ("post_id");
CREATE INDEX IF NOT EXISTS "idx_placement_project_2c6aa4" ON "placement" ("project_id");
CREATE INDEX IF NOT EXISTS "idx_placement_purchas_61f9e6" ON "placement" ("purchase_channel_id");
COMMENT ON COLUMN "placement"."status" IS 'ACTIVE: active\nARCHIVED: archived';
CREATE TABLE IF NOT EXISTS "subscription" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"invite_link" VARCHAR(512) NOT NULL,
"status" VARCHAR(12) NOT NULL DEFAULT 'active',
"unsubscribed_at" TIMESTAMPTZ,
"placement_id" UUID NOT NULL REFERENCES "placement" ("id") ON DELETE CASCADE,
"telegram_user_id" UUID NOT NULL REFERENCES "telegram_user" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_subscriptio_placeme_75b40b" UNIQUE ("placement_id", "telegram_user_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");
CREATE INDEX IF NOT EXISTS "idx_subscriptio_telegra_8be9bb" ON "subscription" ("telegram_user_id");
COMMENT ON COLUMN "subscription"."status" IS 'ACTIVE: active\nUNSUBSCRIBED: unsubscribed';
CREATE TABLE IF NOT EXISTS "workspace_invite" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(8) NOT NULL DEFAULT 'pending',
"invited_by_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"user_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_workspace_i_workspa_abd9c4" UNIQUE ("workspace_id", "user_id")
);
CREATE INDEX IF NOT EXISTS "idx_workspace_i_invited_3ed9f8" ON "workspace_invite" ("invited_by_id");
CREATE INDEX IF NOT EXISTS "idx_workspace_i_user_id_a96e1e" ON "workspace_invite" ("user_id");
CREATE INDEX IF NOT EXISTS "idx_workspace_i_workspa_71e9d2" ON "workspace_invite" ("workspace_id");
COMMENT ON COLUMN "workspace_invite"."status" IS 'PENDING: pending\nACCEPTED: accepted\nREVOKED: revoked';
CREATE TABLE IF NOT EXISTS "workspace_user" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"status" VARCHAR(7) NOT NULL DEFAULT 'active',
"user_id" UUID NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE,
"workspace_id" UUID NOT NULL REFERENCES "workspace" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_workspace_u_workspa_13c46c" UNIQUE ("workspace_id", "user_id")
);
CREATE INDEX IF NOT EXISTS "idx_workspace_u_user_id_246318" ON "workspace_user" ("user_id");
CREATE INDEX IF NOT EXISTS "idx_workspace_u_workspa_a403b0" ON "workspace_user" ("workspace_id");
COMMENT ON COLUMN "workspace_user"."status" IS 'ACTIVE: active\nINVITED: invited\nBLOCKED: blocked';
CREATE TABLE IF NOT EXISTS "workspace_user_permission" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"permission" VARCHAR(24) NOT NULL,
"workspace_user_id" UUID NOT NULL REFERENCES "workspace_user" ("id") ON DELETE CASCADE,
CONSTRAINT "uid_workspace_u_workspa_86f574" UNIQUE ("workspace_user_id", "permission")
);
CREATE INDEX IF NOT EXISTS "idx_workspace_u_workspa_b9b7b0" ON "workspace_user_permission" ("workspace_user_id");
COMMENT ON COLUMN "workspace_user_permission"."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';
CREATE TABLE IF NOT EXISTS "workspace_user_permission_scope" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"permission" VARCHAR(24) NOT NULL,
"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';
CREATE TABLE IF NOT EXISTS "aerich" (
"id" SERIAL NOT NULL PRIMARY KEY,
"version" VARCHAR(255) NOT NULL,
"app" VARCHAR(100) NOT NULL,
"content" JSONB NOT NULL
);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
"""
MODELS_STATE = (
'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'
'v0'
)

View File

@@ -1,99 +0,0 @@
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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'
)

View File

@@ -0,0 +1,107 @@
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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'
'v0'
)

View File

@@ -1,95 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "creative" ADD "buttons" JSONB NOT NULL;
ALTER TABLE "creative" ADD "media_data" BYTEA;
ALTER TABLE "creative" ADD "media_file_id" VARCHAR(512);
ALTER TABLE "creative" ADD "media_type" VARCHAR(32);"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "creative" DROP COLUMN "buttons";
ALTER TABLE "creative" DROP COLUMN "media_data";
ALTER TABLE "creative" DROP COLUMN "media_file_id";
ALTER TABLE "creative" DROP COLUMN "media_type";"""
MODELS_STATE = (
"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"
"a4"
)

View File

@@ -1,90 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "creative" ADD "media_s3_key" VARCHAR(512);
ALTER TABLE "creative" DROP COLUMN "media_data";"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "creative" ADD "media_data" BYTEA;
ALTER TABLE "creative" DROP COLUMN "media_s3_key";"""
MODELS_STATE = (
"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"
"XdLO/D8vv/8PAyERnQ=="
)

View File

@@ -1,149 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "purchase"
ADD "comment" TEXT;
ALTER TABLE "purchase"
ADD "payment_at" TIMESTAMPTZ;
ALTER TABLE "purchase"
ADD "format" TEXT;
ALTER TABLE "purchase"
ADD "cost_before_bargain" DOUBLE PRECISION;
ALTER TABLE "purchase"
ADD "placement_at" TIMESTAMPTZ;
ALTER TABLE "purchase"
ADD "cost_type" VARCHAR(8);
ALTER TABLE "purchase"
ADD "cost_value" DOUBLE PRECISION;
ALTER TABLE "purchase"
ADD "purchase_type" VARCHAR(16);
ALTER TABLE "purchase_channel"
ADD "format" TEXT;
ALTER TABLE "purchase_channel"
ADD "cost_before_bargain" DOUBLE PRECISION;
ALTER TABLE "purchase_channel"
ADD "placement_at" TIMESTAMPTZ;
ALTER TABLE "purchase_channel"
ADD "cost_type" VARCHAR(8);
ALTER TABLE "purchase_channel"
ADD "cost_value" DOUBLE PRECISION;
ALTER TABLE "purchase_channel"
DROP COLUMN "planned_cost";
COMMENT ON COLUMN "purchase"."cost_type" IS 'FIXED: fixed\nCPM: cpm';
COMMENT ON COLUMN "purchase"."purchase_type" IS 'SELF_PROMO: self_promo\nSTANDARD: standard';
COMMENT ON COLUMN "purchase_channel"."cost_type" IS 'FIXED: fixed\nCPM: cpm';"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "purchase"
DROP COLUMN "comment";
ALTER TABLE "purchase"
DROP COLUMN "payment_at";
ALTER TABLE "purchase"
DROP COLUMN "format";
ALTER TABLE "purchase"
DROP COLUMN "cost_before_bargain";
ALTER TABLE "purchase"
DROP COLUMN "placement_at";
ALTER TABLE "purchase"
DROP COLUMN "cost_type";
ALTER TABLE "purchase"
DROP COLUMN "cost_value";
ALTER TABLE "purchase"
DROP COLUMN "purchase_type";
ALTER TABLE "purchase_channel"
ADD "planned_cost" DOUBLE PRECISION;
ALTER TABLE "purchase_channel"
DROP COLUMN "format";
ALTER TABLE "purchase_channel"
DROP COLUMN "cost_before_bargain";
ALTER TABLE "purchase_channel"
DROP COLUMN "placement_at";
ALTER TABLE "purchase_channel"
DROP COLUMN "cost_type";
ALTER TABLE "purchase_channel"
DROP COLUMN "cost_value";"""
MODELS_STATE = (
'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'
'49ruDVq8qUI6aKVL2pn/5+X3/wGuY8FA'
)

View File

@@ -1,151 +0,0 @@
from tortoise import BaseDBAsyncClient
RUN_IN_TRANSACTION = True
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX IF EXISTS "uid_user_telegra_66ffbd";
ALTER TABLE "subscription" DROP CONSTRAINT IF EXISTS "uid_subscriptio_placeme_8fcb8f";
ALTER TABLE "subscription" DROP CONSTRAINT IF EXISTS "fk_subscrip_user_6b9f4b8e";
CREATE TABLE IF NOT EXISTS "telegram_user" (
"id" UUID NOT NULL PRIMARY KEY,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted_at" TIMESTAMPTZ,
"telegram_id" BIGINT NOT NULL UNIQUE,
"username" VARCHAR(255),
"first_name" VARCHAR(255),
"last_name" VARCHAR(255)
);
CREATE INDEX IF NOT EXISTS "idx_telegram_us_telegra_3a3100" ON "telegram_user" ("telegram_id");
INSERT INTO "telegram_user" (
"id",
"created_at",
"updated_at",
"deleted_at",
"telegram_id",
"username",
"first_name",
"last_name"
)
SELECT
"id",
"created_at",
"updated_at",
"deleted_at",
"telegram_id",
"username",
"first_name",
"last_name"
FROM "user"
WHERE "telegram_id" IS NOT NULL
ON CONFLICT ("id") DO NOTHING;
ALTER TABLE "subscription" RENAME COLUMN "subscriber_id" TO "telegram_user_id";
ALTER TABLE "user" ADD "telegram_user_id" UUID UNIQUE;
UPDATE "user" SET "telegram_user_id" = "id";
ALTER TABLE "user" ALTER COLUMN "telegram_user_id" SET NOT NULL;
ALTER TABLE "user" DROP COLUMN "first_name";
ALTER TABLE "user" DROP COLUMN "username";
ALTER TABLE "user" DROP COLUMN "telegram_id";
ALTER TABLE "user" DROP COLUMN "last_name";
ALTER TABLE "subscription" ADD CONSTRAINT "fk_subscrip_telegram_ab72b5bf" FOREIGN KEY ("telegram_user_id") REFERENCES "telegram_user" ("id") ON DELETE CASCADE;
CREATE UNIQUE INDEX IF NOT EXISTS "uid_subscriptio_placeme_75b40b" ON "subscription" ("placement_id", "telegram_user_id");
ALTER TABLE "user" ADD CONSTRAINT "fk_user_telegram_548d951e" FOREIGN KEY ("telegram_user_id") REFERENCES "telegram_user" ("id") ON DELETE CASCADE;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
DROP INDEX IF EXISTS "uid_subscriptio_placeme_75b40b";
ALTER TABLE "subscription" DROP CONSTRAINT IF EXISTS "fk_subscrip_telegram_ab72b5bf";
ALTER TABLE "user" DROP CONSTRAINT IF EXISTS "fk_user_telegram_548d951e";
ALTER TABLE "user" ADD "first_name" VARCHAR(255);
ALTER TABLE "user" ADD "username" VARCHAR(255);
ALTER TABLE "user" ADD "telegram_id" BIGINT NOT NULL UNIQUE;
ALTER TABLE "user" ADD "last_name" VARCHAR(255);
ALTER TABLE "user" DROP COLUMN "telegram_user_id";
ALTER TABLE "subscription" RENAME COLUMN "telegram_user_id" TO "subscriber_id";
DROP TABLE IF EXISTS "telegram_user";
ALTER TABLE "subscription" ADD CONSTRAINT "fk_subscrip_user_6b9f4b8e" FOREIGN KEY ("subscriber_id") REFERENCES "user" ("id") ON DELETE CASCADE;
CREATE UNIQUE INDEX IF NOT EXISTS "uid_subscriptio_placeme_8fcb8f" ON "subscription" ("placement_id", "subscriber_id");"""
MODELS_STATE = (
"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"
"1lQhHbSyJe3k/3n5/X8nR5KJ"
)