feat: переименование доменной области
This commit is contained in:
@@ -19,6 +19,9 @@ class Postgres(DatabaseBase):
|
||||
async def create_user(self, user: domain.User) -> None:
|
||||
await user.save()
|
||||
|
||||
async def update_user(self, user: domain.User) -> None:
|
||||
await user.save()
|
||||
|
||||
async def create_workspace(self, workspace: domain.Workspace) -> None:
|
||||
await workspace.save()
|
||||
|
||||
@@ -28,10 +31,12 @@ class Postgres(DatabaseBase):
|
||||
async def delete_workspace(self, workspace_id: uuid.UUID) -> None:
|
||||
await domain.Workspace.filter(id=workspace_id).delete()
|
||||
|
||||
async def add_user_to_workspace(
|
||||
self, workspace_id: uuid.UUID, user_id: uuid.UUID, *, is_owner: bool = False
|
||||
) -> None:
|
||||
await domain.WorkspaceUser.create(workspace_id=workspace_id, user_id=user_id, is_owner=is_owner)
|
||||
async def add_user_to_workspace(self, workspace_id: uuid.UUID, user_id: uuid.UUID) -> None:
|
||||
await domain.WorkspaceUser.create(
|
||||
workspace_id=workspace_id,
|
||||
user_id=user_id,
|
||||
status=domain.WorkspaceUserStatus.ACTIVE,
|
||||
)
|
||||
|
||||
async def get_user_workspaces(self, user_id: uuid.UUID) -> list[domain.WorkspaceUser]:
|
||||
return (
|
||||
@@ -71,9 +76,6 @@ class Postgres(DatabaseBase):
|
||||
async def create_login_token(self, login_token: domain.LoginToken) -> None:
|
||||
await login_token.save()
|
||||
|
||||
async def create_external_channel(self, channel: domain.ExternalChannel) -> None:
|
||||
await channel.save()
|
||||
|
||||
async def create_creative(self, creative: domain.Creative) -> None:
|
||||
await creative.save()
|
||||
|
||||
@@ -94,120 +96,165 @@ class Postgres(DatabaseBase):
|
||||
if updated == 0:
|
||||
raise domain.LoginTokenAlreadyUsed() # либо нет токена, либо он уже использован
|
||||
|
||||
async def get_target_channel(
|
||||
self, workspace_id: uuid.UUID, channel_id: uuid.UUID | None = None, telegram_id: int | None = None
|
||||
) -> domain.TargetChannel | None:
|
||||
if not channel_id and not telegram_id:
|
||||
raise ValueError('Either channel_id or telegram_id must be provided')
|
||||
|
||||
q = domain.TargetChannel.filter(workspace_id=workspace_id)
|
||||
if channel_id:
|
||||
q = q.filter(id=channel_id)
|
||||
if telegram_id:
|
||||
q = q.filter(telegram_id=telegram_id)
|
||||
|
||||
return await q.first()
|
||||
|
||||
async def get_target_channel_for_user_by_telegram(
|
||||
self, user_id: uuid.UUID, telegram_id: int
|
||||
) -> domain.TargetChannel | None:
|
||||
return (
|
||||
await domain.TargetChannel.filter(telegram_id=telegram_id, workspace__workspace_users__user_id=user_id)
|
||||
.prefetch_related('workspace')
|
||||
.first()
|
||||
)
|
||||
|
||||
async def upsert_target_channel(self, channel: domain.TargetChannel) -> None:
|
||||
existing = await self.get_target_channel(workspace_id=channel.workspace_id, telegram_id=channel.telegram_id)
|
||||
|
||||
if not existing:
|
||||
await channel.save()
|
||||
return
|
||||
|
||||
existing.title = channel.title
|
||||
existing.username = channel.username
|
||||
existing.workspace_id = channel.workspace_id
|
||||
existing.status = channel.status
|
||||
existing.deleted_at = None
|
||||
existing.updated_at = timezone.now()
|
||||
await existing.save()
|
||||
|
||||
async def get_workspace_target_channels(self, workspace_id: uuid.UUID) -> list[domain.TargetChannel]:
|
||||
return await domain.TargetChannel.filter(
|
||||
workspace_id=workspace_id, status=domain.TargetChannelStatus.ACTIVE
|
||||
).all()
|
||||
|
||||
async def update_target_channel(self, channel: domain.TargetChannel) -> None:
|
||||
await channel.save()
|
||||
|
||||
async def get_external_channel(
|
||||
self, workspace_id: uuid.UUID, channel_id: uuid.UUID | None = None, telegram_id: int | None = None
|
||||
) -> domain.ExternalChannel | None:
|
||||
query = domain.ExternalChannel.filter(workspace_id=workspace_id)
|
||||
async def get_channel(
|
||||
self,
|
||||
workspace_id: uuid.UUID,
|
||||
channel_id: uuid.UUID | None = None,
|
||||
telegram_id: int | None = None,
|
||||
username: str | None = None,
|
||||
) -> domain.Channel | None:
|
||||
query = domain.Channel.filter(workspace_id=workspace_id)
|
||||
if channel_id:
|
||||
query = query.filter(id=channel_id)
|
||||
if telegram_id:
|
||||
query = query.filter(telegram_id=telegram_id)
|
||||
|
||||
if username:
|
||||
query = query.filter(username=username)
|
||||
return await query.first()
|
||||
|
||||
async def get_external_channels_for_target(self, target_channel_id: uuid.UUID) -> list[domain.ExternalChannel]:
|
||||
return await domain.ExternalChannel.filter(target_channels__id=target_channel_id).all()
|
||||
async def get_workspace_channels(self, workspace_id: uuid.UUID) -> list[domain.Channel]:
|
||||
return await domain.Channel.filter(workspace_id=workspace_id).all()
|
||||
|
||||
async def get_workspace_external_channels(self, workspace_id: uuid.UUID) -> list[domain.ExternalChannel]:
|
||||
return await domain.ExternalChannel.filter(workspace_id=workspace_id).all()
|
||||
|
||||
async def add_external_channel_to_targets(
|
||||
self, external_channel: domain.ExternalChannel, target_channel_ids: list[uuid.UUID]
|
||||
) -> None:
|
||||
target_channels = await domain.TargetChannel.filter(id__in=target_channel_ids).all()
|
||||
await external_channel.target_channels.add(*target_channels)
|
||||
|
||||
async def remove_external_channel_from_target(
|
||||
self, external_channel_id: uuid.UUID, target_channel_id: uuid.UUID
|
||||
) -> None:
|
||||
external_channel = await domain.ExternalChannel.get_or_none(id=external_channel_id)
|
||||
|
||||
if not external_channel:
|
||||
raise ValueError(f'ExternalChannel {external_channel_id} not found')
|
||||
|
||||
target_channel = await domain.TargetChannel.get_or_none(id=target_channel_id)
|
||||
if target_channel:
|
||||
await external_channel.target_channels.remove(target_channel)
|
||||
|
||||
async def delete_external_channel(self, channel_id: uuid.UUID) -> None:
|
||||
await domain.ExternalChannel.filter(id=channel_id).delete()
|
||||
|
||||
async def update_external_channel(self, channel: domain.ExternalChannel) -> None:
|
||||
async def create_channel(self, channel: domain.Channel) -> None:
|
||||
await channel.save()
|
||||
|
||||
async def update_channel(self, channel: domain.Channel) -> None:
|
||||
await channel.save()
|
||||
|
||||
async def delete_channel(self, channel_id: uuid.UUID) -> None:
|
||||
await domain.Channel.filter(id=channel_id).delete()
|
||||
|
||||
async def search_channels(self, username_query: str | None = None) -> list[domain.Channel]:
|
||||
query = domain.Channel.all()
|
||||
|
||||
if username_query:
|
||||
# Частичный поиск (case-insensitive)
|
||||
query = query.filter(username__icontains=username_query)
|
||||
|
||||
return await query.all()
|
||||
|
||||
async def get_project(
|
||||
self, workspace_id: uuid.UUID, project_id: uuid.UUID | None = None, channel_id: uuid.UUID | None = None
|
||||
) -> domain.Project | None:
|
||||
query = domain.Project.filter(workspace_id=workspace_id).prefetch_related('channel')
|
||||
if project_id:
|
||||
query = query.filter(id=project_id)
|
||||
if channel_id:
|
||||
query = query.filter(channel_id=channel_id)
|
||||
return await query.first()
|
||||
|
||||
async def get_project_for_user_by_telegram(
|
||||
self, user_id: uuid.UUID, channel_telegram_id: int
|
||||
) -> domain.Project | None:
|
||||
return (
|
||||
await domain.Project.filter(
|
||||
channel__telegram_id=channel_telegram_id, workspace__workspace_users__user_id=user_id
|
||||
)
|
||||
.prefetch_related('channel')
|
||||
.first()
|
||||
)
|
||||
|
||||
async def get_project_by_channel_telegram(self, channel_telegram_id: int) -> domain.Project | None:
|
||||
return await domain.Project.filter(channel__telegram_id=channel_telegram_id).prefetch_related('channel').first()
|
||||
|
||||
async def create_project(self, project: domain.Project) -> None:
|
||||
await project.save()
|
||||
|
||||
async def update_project(self, project: domain.Project) -> None:
|
||||
await project.save()
|
||||
|
||||
async def get_workspace_projects(self, workspace_id: uuid.UUID) -> list[domain.Project]:
|
||||
return (
|
||||
await domain.Project.filter(workspace_id=workspace_id)
|
||||
.prefetch_related('channel')
|
||||
.order_by('created_at')
|
||||
.all()
|
||||
)
|
||||
|
||||
async def get_active_purchase_plan(self, project_id: uuid.UUID) -> domain.PurchasePlan | None:
|
||||
return await domain.PurchasePlan.get_or_none(project_id=project_id, status=domain.PurchasePlanStatus.ACTIVE)
|
||||
|
||||
async def get_purchase_plan(self, workspace_id: uuid.UUID, plan_id: uuid.UUID) -> domain.PurchasePlan | None:
|
||||
return await domain.PurchasePlan.get_or_none(id=plan_id, workspace_id=workspace_id)
|
||||
|
||||
async def create_purchase_plan(self, plan: domain.PurchasePlan) -> None:
|
||||
await plan.save()
|
||||
|
||||
async def get_purchase_plan_channels(self, plan_id: uuid.UUID) -> list[domain.PurchasePlanChannel]:
|
||||
return await domain.PurchasePlanChannel.filter(purchase_plan_id=plan_id).prefetch_related('channel').all()
|
||||
|
||||
async def get_purchase_plan_channel(
|
||||
self, plan_channel_id: uuid.UUID, plan_id: uuid.UUID
|
||||
) -> domain.PurchasePlanChannel | None:
|
||||
return (
|
||||
await domain.PurchasePlanChannel.filter(id=plan_channel_id, purchase_plan_id=plan_id)
|
||||
.prefetch_related('channel')
|
||||
.first()
|
||||
)
|
||||
|
||||
async def add_channel_to_purchase_plan(
|
||||
self,
|
||||
plan_id: uuid.UUID,
|
||||
channel_id: uuid.UUID,
|
||||
*,
|
||||
status: domain.PurchasePlanChannelStatus | None = None,
|
||||
planned_cost: float | None = None,
|
||||
comment: str | None = None,
|
||||
) -> domain.PurchasePlanChannel:
|
||||
defaults: dict[str, object | None] = {}
|
||||
if status is not None:
|
||||
defaults['status'] = status
|
||||
if planned_cost is not None:
|
||||
defaults['planned_cost'] = planned_cost
|
||||
if comment is not None:
|
||||
defaults['comment'] = comment
|
||||
|
||||
plan_channel, created = await domain.PurchasePlanChannel.get_or_create(
|
||||
purchase_plan_id=plan_id,
|
||||
channel_id=channel_id,
|
||||
defaults=defaults,
|
||||
)
|
||||
|
||||
if not created and defaults:
|
||||
for field, value in defaults.items():
|
||||
setattr(plan_channel, field, value)
|
||||
await plan_channel.save()
|
||||
|
||||
return plan_channel
|
||||
|
||||
async def update_purchase_plan_channel(self, plan_channel: domain.PurchasePlanChannel) -> None:
|
||||
await plan_channel.save()
|
||||
|
||||
async def remove_channel_from_purchase_plan(self, plan_id: uuid.UUID, channel_id: uuid.UUID) -> None:
|
||||
await domain.PurchasePlanChannel.filter(purchase_plan_id=plan_id, channel_id=channel_id).delete()
|
||||
|
||||
async def get_creative(self, workspace_id: uuid.UUID, creative_id: uuid.UUID) -> domain.Creative | None:
|
||||
return await domain.Creative.get_or_none(id=creative_id, workspace_id=workspace_id).prefetch_related(
|
||||
'target_channel'
|
||||
'project', 'project__channel'
|
||||
)
|
||||
|
||||
async def update_creative(self, creative: domain.Creative) -> None:
|
||||
await creative.save()
|
||||
|
||||
async def get_workspace_creatives(
|
||||
self, workspace_id: uuid.UUID, target_channel_id: uuid.UUID | None = None, include_archived: bool = False
|
||||
self, workspace_id: uuid.UUID, project_id: uuid.UUID | None = None, include_archived: bool = False
|
||||
) -> list[domain.Creative]:
|
||||
query = domain.Creative.filter(workspace_id=workspace_id)
|
||||
|
||||
if target_channel_id:
|
||||
query = query.filter(target_channel_id=target_channel_id)
|
||||
if project_id:
|
||||
query = query.filter(project_id=project_id)
|
||||
|
||||
if not include_archived:
|
||||
query = query.filter(status=domain.CreativeStatus.ACTIVE)
|
||||
|
||||
return await query.prefetch_related('target_channel').order_by('-created_at').all()
|
||||
return await query.prefetch_related('project', 'project__channel').order_by('-created_at').all()
|
||||
|
||||
async def delete_creative(self, creative_id: uuid.UUID) -> None:
|
||||
await domain.Creative.filter(id=creative_id).delete()
|
||||
|
||||
async def get_placement(self, workspace_id: uuid.UUID, placement_id: uuid.UUID) -> domain.Placement | None:
|
||||
return await domain.Placement.get_or_none(id=placement_id, workspace_id=workspace_id).prefetch_related(
|
||||
'target_channel', 'external_channel', 'creative'
|
||||
'project', 'project__channel', 'placement_channel', 'creative'
|
||||
)
|
||||
|
||||
async def create_placement(self, placement: domain.Placement) -> None:
|
||||
@@ -219,17 +266,17 @@ class Postgres(DatabaseBase):
|
||||
async def get_workspace_placements(
|
||||
self,
|
||||
workspace_id: uuid.UUID,
|
||||
target_channel_id: uuid.UUID | None = None,
|
||||
external_channel_id: uuid.UUID | None = None,
|
||||
project_id: uuid.UUID | None = None,
|
||||
placement_channel_id: uuid.UUID | None = None,
|
||||
creative_id: uuid.UUID | None = None,
|
||||
include_archived: bool = False,
|
||||
) -> list[domain.Placement]:
|
||||
query = domain.Placement.filter(workspace_id=workspace_id)
|
||||
|
||||
if target_channel_id:
|
||||
query = query.filter(target_channel_id=target_channel_id)
|
||||
if external_channel_id:
|
||||
query = query.filter(external_channel_id=external_channel_id)
|
||||
if project_id:
|
||||
query = query.filter(project_id=project_id)
|
||||
if placement_channel_id:
|
||||
query = query.filter(placement_channel_id=placement_channel_id)
|
||||
if creative_id:
|
||||
query = query.filter(creative_id=creative_id)
|
||||
|
||||
@@ -237,7 +284,7 @@ class Postgres(DatabaseBase):
|
||||
query = query.filter(status=domain.PlacementStatus.ACTIVE)
|
||||
|
||||
return (
|
||||
await query.prefetch_related('target_channel', 'external_channel', 'creative')
|
||||
await query.prefetch_related('project', 'project__channel', 'placement_channel', 'creative')
|
||||
.order_by('-placement_date')
|
||||
.all()
|
||||
)
|
||||
@@ -247,23 +294,9 @@ class Postgres(DatabaseBase):
|
||||
|
||||
async def get_placement_by_invite_link(self, invite_link: str) -> domain.Placement | None:
|
||||
return await domain.Placement.get_or_none(invite_link=invite_link).prefetch_related(
|
||||
'target_channel', 'external_channel', 'creative'
|
||||
'project', 'project__channel', 'placement_channel', 'creative'
|
||||
)
|
||||
|
||||
async def get_subscriber(self, telegram_id: int) -> domain.Subscriber | None:
|
||||
return await domain.Subscriber.get_or_none(telegram_id=telegram_id)
|
||||
|
||||
async def upsert_subscriber(self, subscriber: domain.Subscriber) -> None:
|
||||
existing = await self.get_subscriber(subscriber.telegram_id)
|
||||
if not existing:
|
||||
await subscriber.save()
|
||||
return
|
||||
|
||||
existing.username = subscriber.username
|
||||
existing.first_name = subscriber.first_name
|
||||
existing.last_name = subscriber.last_name
|
||||
await existing.save()
|
||||
|
||||
async def create_subscription(self, subscription: domain.Subscription) -> None:
|
||||
await subscription.save()
|
||||
|
||||
@@ -275,26 +308,26 @@ class Postgres(DatabaseBase):
|
||||
async def update_subscription(self, subscription: domain.Subscription) -> None:
|
||||
await subscription.save()
|
||||
|
||||
async def get_active_subscriptions_by_subscriber_and_channel(
|
||||
self, subscriber_id: uuid.UUID, channel_telegram_id: int
|
||||
async def get_active_subscriptions_by_subscriber_and_project(
|
||||
self, subscriber_id: uuid.UUID, project_id: uuid.UUID
|
||||
) -> list[domain.Subscription]:
|
||||
return (
|
||||
await domain.Subscription.filter(
|
||||
subscriber_id=subscriber_id,
|
||||
target_channel__telegram_id=channel_telegram_id,
|
||||
placement__project_id=project_id,
|
||||
status=domain.SubscriptionStatus.ACTIVE,
|
||||
)
|
||||
.prefetch_related('placement', 'subscriber')
|
||||
.all()
|
||||
)
|
||||
|
||||
async def get_active_subscription_by_subscriber_and_channel(
|
||||
self, subscriber_id: uuid.UUID, channel_telegram_id: int
|
||||
async def get_active_subscription_by_subscriber_and_project(
|
||||
self, subscriber_id: uuid.UUID, project_id: uuid.UUID
|
||||
) -> domain.Subscription | None:
|
||||
return (
|
||||
await domain.Subscription.filter(
|
||||
subscriber_id=subscriber_id,
|
||||
target_channel__telegram_id=channel_telegram_id,
|
||||
placement__project_id=project_id,
|
||||
status=domain.SubscriptionStatus.ACTIVE,
|
||||
)
|
||||
.prefetch_related('placement', 'subscriber')
|
||||
|
||||
Reference in New Issue
Block a user