Files
tgex-frontend/lib/types/api.ts
2026-02-02 11:17:50 +03:00

563 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================================
// API Types - Based on actual API responses
// ============================================================================
// ----------------------------------------------------------------------------
// User & Auth
// ----------------------------------------------------------------------------
export interface User {
id: string; // UUID
telegram_id: number;
username: string | null;
first_name: string | null;
last_name: string | null;
}
export interface AuthCompleteResponse {
access_token: string;
}
// ----------------------------------------------------------------------------
// Pagination
// ----------------------------------------------------------------------------
export interface PaginatedResponse<T> {
items: T[];
total: number;
page: number;
size: number;
pages: number;
}
export interface PaginationParams {
page?: number;
size?: number;
}
// ----------------------------------------------------------------------------
// Workspaces
// ----------------------------------------------------------------------------
export interface Workspace {
id: string; // UUID
name: string;
avatar_url?: string | null;
}
export interface WorkspaceCreateRequest {
name: string;
avatar_file?: File | null;
}
export interface WorkspaceUpdateRequest {
name?: string;
}
// ----------------------------------------------------------------------------
// Workspace Members & Permissions
// ----------------------------------------------------------------------------
export type WorkspaceUserStatus = "active" | "invited";
export type PermissionKey =
| "admin_full"
| "projects_read"
| "projects_write"
| "placements_read"
| "placements_write"
| "analytics_read";
export type PermissionScopeType = "project";
export interface PermissionScope {
type: PermissionScopeType;
id: string; // UUID
}
export interface Permission {
key: PermissionKey;
scopes?: PermissionScope[];
}
export interface WorkspaceMemberUser {
id: string; // user_id
telegram_id: number;
username: string | null;
first_name: string | null;
last_name: string | null;
}
export interface WorkspaceMember {
id: string; // member record id
status: WorkspaceUserStatus;
user: WorkspaceMemberUser;
permissions: Permission[];
}
export interface UpdatePermissionsRequest {
permissions: Permission[];
}
// ----------------------------------------------------------------------------
// Workspace Invites
// ----------------------------------------------------------------------------
export type WorkspaceInviteStatus = "pending" | "accepted" | "rejected";
export interface WorkspaceInvite {
id: string; // UUID
username: string;
status: WorkspaceInviteStatus;
created_at: string;
}
export interface WorkspaceInviteCreateRequest {
username: string; // без @
}
// ----------------------------------------------------------------------------
// Projects (Target Channels)
// ----------------------------------------------------------------------------
export type ProjectStatus = "active" | "inactive" | "archived";
export interface Project {
id: string; // UUID
telegram_id: number;
title: string;
username: string | null;
status: ProjectStatus;
subscribers_count?: number;
purchase_invite_type_default?: "public" | "approval";
}
// ----------------------------------------------------------------------------
// Channels (Catalog for Placements)
// ----------------------------------------------------------------------------
export type ChannelStatus = "active" | "inactive" | "archived";
export interface Channel {
id: string; // UUID
telegram_id: number;
title: string;
username: string | null;
description?: string | null;
subscribers_count?: number;
}
export interface ChannelsQueryParams extends PaginationParams {
username?: string;
}
// ----------------------------------------------------------------------------
// Purchase Plan
// ----------------------------------------------------------------------------
export type PurchasePlanStatus = "planned" | "completed" | "cancelled";
export interface PurchasePlanChannel {
id: string; // UUID
status: PurchasePlanStatus;
planned_cost: number | null;
comment: string | null;
channel: {
id: string;
telegram_id: number;
title: string;
username: string | null;
};
}
export interface PurchasePlanChannelCreateRequest {
channel_id: string;
planned_cost?: number;
comment?: string;
}
export interface PurchasePlanChannelUpdateRequest {
planned_cost?: number;
comment?: string;
}
// ----------------------------------------------------------------------------
// Creatives
// ----------------------------------------------------------------------------
export type CreativeStatus = "active" | "archived";
export interface CreativeMediaItem {
media_type: string;
media_file_id: string;
position: number;
}
export interface CreativeButton {
text: string;
url: string;
}
export interface Creative {
id: string; // UUID
name: string;
text: string; // Contains {invite_link} placeholder
media_items: CreativeMediaItem[];
buttons: CreativeButton[];
project_id: string;
project_channel_title: string;
created_at: string;
status: CreativeStatus;
placements_count: number;
}
export interface CreativeCreateRequest {
name: string;
text: string;
}
export interface CreativeUpdateRequest {
name?: string;
text?: string;
status?: CreativeStatus;
media_items?: CreativeMediaItem[];
buttons?: CreativeButton[];
}
export interface CreativesQueryParams extends PaginationParams {
project_id?: string;
include_archived?: boolean;
}
// ----------------------------------------------------------------------------
// Placements
// ----------------------------------------------------------------------------
export type PlacementStatus =
| "Без статуса"
| "Написать"
| "Ждём ответа"
| "Согласование условий"
| "Оплатить"
| "Оплачено"
| "Отмена"
| "Не подходит цена"
| "Неактуально"
| "Не отвечает";
export type InviteLinkType = "public" | "approval";
export type PostViewsAvailability =
| "unknown"
| "available"
| "unavailable"
| "manual";
export interface PlacementChannel {
id: string;
telegram_id: number;
title: string;
username: string | null;
subscribers_count?: number;
}
export interface PlacementCostInfo {
type: "fixed" | "cpm";
value: number;
}
export interface PlacementDetails {
placement_at: string | null; // ISO 8601
payment_at: string | null; // ISO 8601
cost: PlacementCostInfo | null;
cost_before_bargain: number | null;
placement_type: string | null;
format: string | null;
comment: string | null;
creative_id: string | null;
}
export interface PlacementPost {
subscriptions_count: number;
views_count: number | null;
created_at: string;
post: {
id: string;
message_id: number;
text: string;
url: string | null;
deleted_from_channel_at: string | null;
created_at: string;
updated_at: string;
} | null;
}
export interface Placement {
id: string;
status: PlacementStatus;
creative_id: string | null;
comment: string | null;
invite_link: string | null;
invite_link_type: InviteLinkType;
channel: PlacementChannel;
details: PlacementDetails | null;
placement_post: PlacementPost | null;
created_at: string;
}
export interface PlacementWithStats extends Placement {
cpf: number | null;
cpm: number | null;
}
export interface PlacementsGroupedByChannel {
channel: PlacementChannel;
placements: PlacementWithStats[];
total_cost: number;
total_subscriptions: number;
total_views: number;
}
export interface ProjectPlacementsSummary {
total_placements: number;
total_channels: number;
total_cost: number;
total_subscriptions: number;
total_views: number;
avg_cpf: number | null;
avg_cpm: number | null;
}
export interface PlacementCreateRequest {
project_id: string;
placement_channel_id: string;
creative_id: string;
placement_date: string; // ISO 8601
cost?: number;
comment?: string;
ad_post_url?: string;
invite_link_type: InviteLinkType;
}
export interface PlacementUpdateRequest {
placement_date?: string;
cost?: number;
comment?: string;
ad_post_url?: string;
}
export interface PlacementsQueryParams extends PaginationParams {
project_id?: string;
placement_channel_id?: string;
creative_id?: string;
include_archived?: boolean;
}
// ----------------------------------------------------------------------------
// Views History
// ----------------------------------------------------------------------------
export interface ViewsHistoryItem {
id: string; // UUID
views_count: number;
fetched_at: string; // ISO 8601
}
export interface ViewsHistoryQueryParams extends PaginationParams {
from_date?: string;
to_date?: string;
}
// ----------------------------------------------------------------------------
// Analytics
// ----------------------------------------------------------------------------
export type DateGrouping = "day" | "week" | "month" | "DAY" | "WEEK" | "MONTH";
// Placements Analytics (Projects Analytics)
export interface PlacementAnalyticsItem {
id: string; // UUID
project_id: string; // UUID
project_channel_title: string;
placement_channel_id: string; // UUID
placement_channel_title: string;
creative_id: string; // UUID
creative_name: string;
placement_date: string; // ISO 8601
cost: number;
subscriptions_count: number;
views_count: number;
cpf: number;
cpm: number;
post_url?: string | null;
}
export interface PlacementsAnalyticsQueryParams extends PaginationParams {
project_id?: string;
placement_channel_id?: string;
creative_id?: string;
date_from?: string;
date_to?: string;
}
// Creatives Analytics (matches actual API response)
export interface CreativeAnalyticsItem {
id: string;
name: string;
placements_count: number;
total_cost: number;
total_subscriptions: number;
total_views: number;
avg_cpf: number | null; // cost per follower (same as CPS)
avg_cpm: number | null;
}
// Channels Analytics
export interface ChannelAnalyticsItem {
channel_id: string;
channel_title: string;
channel_username: string | null;
placements_count: number;
total_cost: number;
total_subscriptions: number;
total_views: number;
avg_cps: number | null;
avg_cpm: number | null;
}
// Spending Analytics
export interface SpendingDataPoint {
period: string;
cost: number;
subscriptions: number;
views: number;
cpf: number | null;
cpm: number | null;
}
export interface SpendingAnalytics {
chart_data: SpendingDataPoint[];
total_cost: number;
total_subscriptions: number;
total_views: number;
avg_cpf: number | null;
avg_cpm: number | null;
placements_count: number;
}
export interface AnalyticsQueryParams extends PaginationParams {
project_id?: string;
}
// Projects Analytics Chart API
export interface ProjectsAnalyticsMetrics {
total_cost: number;
purchases_count: number;
total_subscriptions: number;
total_views: number;
avg_cpf: number | null;
avg_cpm: number | null;
avg_post_cost: number | null;
clicks_count: number;
reach_volume: number;
total_discounts: number | null;
avg_discount_percent: number | null;
avg_conversion: number | null;
}
export interface ProjectsAnalyticsPeriod {
period: string;
period_label: string;
metrics: ProjectsAnalyticsMetrics;
}
export interface ProjectsAnalyticsResponse {
periods: ProjectsAnalyticsPeriod[];
totals: ProjectsAnalyticsMetrics;
}
export interface ProjectsAnalyticsQueryParams {
project_ids?: string[];
date_from?: string;
date_to?: string;
grouping: "day" | "week" | "month" | "quarter";
date_grouping: "purchase_date" | "link_date" | "placement_date";
metrics?: string[];
}
export interface SpendingAnalyticsQueryParams {
project_id?: string;
date_from?: string;
date_to?: string;
grouping?: DateGrouping;
}
// Overview Analytics
export interface OverviewMetric {
value: number;
delta_percent: number;
}
export interface OverviewDailyStat {
date: string; // YYYY-MM-DD
cost: number;
subscriptions: number;
subscriptions_delta: number;
cpf: number;
}
export interface OverviewChannelCpf {
channel_id: string;
title: string;
username: string | null;
cpf: number;
total_cost: number;
subscriptions: number;
}
export interface OverviewProjectSpending {
project_id: string;
project_title: string;
project_username: string | null;
total_cost: number;
}
export interface OverviewAnalytics {
total_cost: OverviewMetric;
total_reach: OverviewMetric;
placements_count: OverviewMetric;
subscriptions_count: OverviewMetric;
avg_cpm: OverviewMetric;
avg_cpf: OverviewMetric;
daily_stats: OverviewDailyStat[];
top_channels_by_cpf: OverviewChannelCpf[];
worst_channels_by_cpf: OverviewChannelCpf[];
project_spending: OverviewProjectSpending[];
}
export interface OverviewAnalyticsQueryParams {
project_id?: string;
date_from?: string;
date_to?: string;
}
// ----------------------------------------------------------------------------
// Common Types
// ----------------------------------------------------------------------------
export interface ApiError {
detail: string;
}
// ----------------------------------------------------------------------------
// Legacy Aliases (for backwards compatibility during migration)
// ----------------------------------------------------------------------------
/** @deprecated Use Project instead */
export type TargetChannel = Project;
/** @deprecated Use Channel instead */
export type ExternalChannel = Channel;
/** @deprecated Use PlacementCreateRequest with new fields */
export type PurchaseCreateRequest = PlacementCreateRequest;