правки имен

This commit is contained in:
Artem Tsyrulnikov
2026-01-18 13:18:00 +03:00
parent 4705e88663
commit c304ba4ec7
10 changed files with 108 additions and 146 deletions

View File

@@ -97,17 +97,17 @@ from .error import (
WorkspaceNotFound,
)
from .login_token import LoginToken
from .placement import PostViewsAvailability, Publication, PublicationStatus
from .post import Post
from .post_views_history import PostViewsHistory
from .project import Project, ProjectStatus
from .purchase import (
from .placement import (
CostType,
InviteLinkType,
Placement,
PlacementStatus,
PlacementType,
)
from .post import Post
from .post_views_history import PostViewsHistory
from .project import Project, ProjectStatus
from .publication import PostViewsAvailability, Publication, PublicationStatus
from .subscription import Subscription, SubscriptionStatus
from .telegram_user import TelegramUser
from .user import User

View File

@@ -1,60 +1,71 @@
import enum
import uuid
from typing import TYPE_CHECKING
from uuid import UUID
from tortoise import fields
from .base import TimestampedModel
if TYPE_CHECKING:
from .channel import Channel
from .creative import Creative
from .post import Post
from .project import Project
from .purchase import Placement
__all__ = ['Publication', 'PublicationStatus', 'PostViewsAvailability']
__all__ = ['Placement', 'PlacementStatus', 'PlacementType', 'InviteLinkType', 'CostType']
class PublicationStatus(str, enum.Enum):
ACTIVE = 'active' # Пост найден и отслеживается
ARCHIVED = 'archived' # Вручную архивировано
class CostType(enum.StrEnum):
FIXED = 'fixed'
CPM = 'cpm'
class PostViewsAvailability(str, enum.Enum):
UNKNOWN = 'unknown' # Ещё не проверялось
AVAILABLE = 'available' # Просмотры доступны
UNAVAILABLE = 'unavailable' # Нет доступа / битая ссылка / приватный канал
MANUAL = 'manual' # Просмотры вводятся вручную
class PlacementStatus(enum.StrEnum):
PLANNED = 'planned'
APPROVED = 'approved'
REJECTED = 'rejected'
IN_PROGRESS = 'in_progress'
COMPLETED = 'completed'
class Publication(TimestampedModel):
"""Публикация, мониторимая системой (бывший Placement)"""
class PlacementType(enum.StrEnum):
SELF_PROMO = 'self_promo'
STANDARD = 'standard'
wanted_placement_date = fields.DatetimeField(db_column='placement_date')
cost = fields.FloatField(null=True)
class InviteLinkType(enum.StrEnum):
PUBLIC = 'public' # открытая ссылка
APPROVAL = 'approval' # с одобрением ботом
class Placement(TimestampedModel):
status = fields.CharEnumField(PlacementStatus, default=PlacementStatus.PLANNED)
placement_at = fields.DatetimeField(null=True)
payment_at = fields.DatetimeField(null=True)
cost_type = fields.CharEnumField(CostType, null=True, max_length=8)
cost_value = fields.FloatField(null=True)
cost_before_bargain = fields.FloatField(null=True)
placement_type = fields.CharEnumField(PlacementType, null=True, max_length=16)
format = fields.TextField(null=True)
comment = fields.TextField(null=True)
status = fields.CharEnumField(PublicationStatus, default=PublicationStatus.ACTIVE)
invite_link = fields.CharField(max_length=512)
invite_link_type = fields.CharEnumField(InviteLinkType)
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
'models.Project', related_name='publications', on_delete=fields.CASCADE, index=True
'models.Project', related_name='placements', on_delete=fields.CASCADE, index=True
)
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
'models.Creative', related_name='publications', on_delete=fields.CASCADE, index=True
'models.Creative', related_name='placements', on_delete=fields.CASCADE, index=True
)
placement: fields.ForeignKeyRelation['Placement'] = fields.ForeignKeyField(
'models.Placement', related_name='publications', on_delete=fields.CASCADE, index=True
)
post: fields.ForeignKeyRelation['Post'] | None = fields.ForeignKeyField(
'models.Post', related_name='publications', on_delete=fields.SET_NULL, null=True, index=True
channel: fields.ForeignKeyRelation['Channel'] = fields.ForeignKeyField(
'models.Channel', related_name='placements', on_delete=fields.CASCADE, index=True
)
if TYPE_CHECKING:
project_id: UUID
creative_id: UUID
post_id: UUID | None
placement_id: UUID
project_id: uuid.UUID
creative_id: uuid.UUID
channel_id: uuid.UUID
class Meta:
table = 'publication'
table = 'placement'
indexes = (('project', 'status'),)

View File

@@ -5,7 +5,7 @@ from uuid import UUID
from tortoise import fields
from .base import TimestampedModel
from .purchase import InviteLinkType
from .placement import InviteLinkType
if TYPE_CHECKING:
from .channel import Channel

58
src/domain/publication.py Normal file
View File

@@ -0,0 +1,58 @@
import enum
from typing import TYPE_CHECKING
from uuid import UUID
from tortoise import fields
from .base import TimestampedModel
if TYPE_CHECKING:
from .creative import Creative
from .placement import Placement
from .post import Post
from .project import Project
__all__ = ['Publication', 'PublicationStatus', 'PostViewsAvailability']
class PublicationStatus(str, enum.Enum):
ACTIVE = 'active' # Пост найден и отслеживается
ARCHIVED = 'archived' # Вручную архивировано
class PostViewsAvailability(str, enum.Enum):
UNKNOWN = 'unknown' # Ещё не проверялось
AVAILABLE = 'available' # Просмотры доступны
UNAVAILABLE = 'unavailable' # Нет доступа / битая ссылка / приватный канал
MANUAL = 'manual' # Просмотры вводятся вручную
class Publication(TimestampedModel):
wanted_placement_date = fields.DatetimeField(db_column='placement_date')
cost = fields.FloatField(null=True)
comment = fields.TextField(null=True)
status = fields.CharEnumField(PublicationStatus, default=PublicationStatus.ACTIVE)
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
'models.Project', related_name='publications', on_delete=fields.CASCADE, index=True
)
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
'models.Creative', related_name='publications', on_delete=fields.CASCADE, index=True
)
placement: fields.ForeignKeyRelation['Placement'] = fields.ForeignKeyField(
'models.Placement', related_name='publications', on_delete=fields.CASCADE, index=True
)
post: fields.ForeignKeyRelation['Post'] | None = fields.ForeignKeyField(
'models.Post', related_name='publications', on_delete=fields.SET_NULL, null=True, index=True
)
if TYPE_CHECKING:
project_id: UUID
creative_id: UUID
post_id: UUID | None
placement_id: UUID
class Meta:
table = 'publication'

View File

@@ -1,97 +0,0 @@
import enum
import uuid
from typing import TYPE_CHECKING
from tortoise import fields
from .base import TimestampedModel
if TYPE_CHECKING:
from .channel import Channel
from .creative import Creative
from .project import Project
__all__ = ['Placement', 'PlacementStatus', 'PlacementType', 'InviteLinkType', 'CostType']
class CostType(enum.StrEnum):
FIXED = 'fixed'
CPM = 'cpm'
class PlacementStatus(enum.StrEnum):
PLANNED = 'planned'
APPROVED = 'approved'
REJECTED = 'rejected'
IN_PROGRESS = 'in_progress'
COMPLETED = 'completed'
class PlacementType(enum.StrEnum):
SELF_PROMO = 'self_promo'
STANDARD = 'standard'
class InviteLinkType(enum.StrEnum):
PUBLIC = 'public' # открытая ссылка
APPROVAL = 'approval' # с одобрением ботом
class Placement(TimestampedModel):
"""Размещение, управляемое пользователем (бывший PurchaseChannel + Purchase)"""
status = fields.CharEnumField(PlacementStatus, default=PlacementStatus.PLANNED)
placement_at = fields.DatetimeField(null=True)
payment_at = fields.DatetimeField(null=True)
cost_type = fields.CharEnumField(CostType, null=True, max_length=8)
cost_value = fields.FloatField(null=True)
cost_before_bargain = fields.FloatField(null=True)
placement_type = fields.CharEnumField(PlacementType, null=True, max_length=16)
format = fields.TextField(null=True)
comment = fields.TextField(null=True)
invite_link = fields.CharField(max_length=512)
invite_link_type = fields.CharEnumField(InviteLinkType)
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
'models.Project', related_name='placements', on_delete=fields.CASCADE, index=True
)
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
'models.Creative', related_name='placements', on_delete=fields.CASCADE, index=True
)
channel: fields.ForeignKeyRelation['Channel'] = fields.ForeignKeyField(
'models.Channel', related_name='placements', on_delete=fields.CASCADE, index=True
)
if TYPE_CHECKING:
project_id: uuid.UUID
creative_id: uuid.UUID
channel_id: uuid.UUID
class Meta:
table = 'placement'
indexes = (('project', 'status'),)
# DEPRECATED: старые модели, будут удалены после миграции
# class PurchaseStatus(enum.StrEnum):
# ACTIVE = 'active'
# ARCHIVED = 'archived'
#
# class PurchaseChannelStatus(enum.StrEnum):
# PLANNED = 'planned'
# APPROVED = 'approved'
# REJECTED = 'rejected'
# IN_PROGRESS = 'in_progress'
# COMPLETED = 'completed'
#
# class PurchaseType(enum.StrEnum):
# SELF_PROMO = 'self_promo'
# STANDARD = 'standard'
#
# class Purchase(TimestampedModel):
# ...
#
# class PurchaseChannel(TimestampedModel):
# ...

View File

@@ -7,7 +7,7 @@ from tortoise import fields
from .base import TimestampedModel
if TYPE_CHECKING:
from .placement import Publication
from .publication import Publication
from .telegram_user import TelegramUser

View File

@@ -11,8 +11,8 @@ from .base import TimestampedModel
if TYPE_CHECKING:
from .channel import Channel
from .creative import Creative
from .placement import Placement
from .project import Project
from .purchase import Placement
from .user import User

View File

@@ -3,7 +3,7 @@ import uuid
import pydantic
from src.domain.purchase import CostType, InviteLinkType, PlacementStatus, PlacementType
from src.domain.placement import CostType, InviteLinkType, PlacementStatus, PlacementType
from .channel import ChannelOutput

View File

@@ -1,5 +0,0 @@
from .fetch_publication_post_cycle import fetch_publication_post_cycle
from .get_publication import get_publication
from .get_publications import get_publications
__all__ = ['fetch_publication_post_cycle', 'get_publication', 'get_publications']

View File

@@ -1,5 +0,0 @@
from .create_placements import create_placements
from .get_placement import get_placement_user
from .get_placements import get_placements
__all__ = ['create_placements', 'get_placement_user', 'get_placements']