Files
tgex-frontend/lib/types/api.ts
2026-01-12 12:46:29 +03:00

471 lines
12 KiB
TypeScript

// ============================================================================
// 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;
}
export interface WorkspaceCreateRequest {
name: string;
}
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 Creative {
id: string; // UUID
name: string;
text: string; // Contains {invite_link} placeholder
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;
}
export interface CreativesQueryParams extends PaginationParams {
project_id?: string;
include_archived?: boolean;
}
// ----------------------------------------------------------------------------
// Placements
// ----------------------------------------------------------------------------
export type PlacementStatus = "active" | "archived";
export type InviteLinkType = "public" | "approval";
export type PostViewsAvailability =
| "unknown"
| "available"
| "unavailable"
| "manual";
export interface Placement {
id: string; // UUID
project_id: string;
project_channel_title: string;
placement_channel_id: string;
placement_channel_title: string;
creative_id: string;
creative_name: string;
placement_date: string; // ISO 8601
cost: number | null;
comment: string | null;
ad_post_url: string | null;
invite_link_type: InviteLinkType;
invite_link: string;
status: PlacementStatus;
subscriptions_count: number;
views_count?: number | null;
views_availability?: PostViewsAvailability;
last_views_fetch_at?: string | null;
created_at: string;
}
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;
}
// 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;
}
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;