Files
tgex-frontend/lib/types/api.ts
2025-11-10 12:07:24 +03:00

411 lines
9.9 KiB
TypeScript

// ============================================================================
// API Types - Generated from API_DOCUMENTATION.md
// ============================================================================
// ----------------------------------------------------------------------------
// User & Auth
// ----------------------------------------------------------------------------
export interface User {
id: string;
telegram_id: number;
username: string | null;
first_name: string;
last_name: string | null;
created_at: string; // ISO 8601
}
export interface AuthInitResponse {
bot_username: string;
start_param: string; // "login"
}
export interface AuthCompleteRequest {
token: string; // one-time token from bot
}
export interface AuthCompleteResponse {
access_token: string;
refresh_token: string;
user: User;
}
export interface AuthRefreshRequest {
refresh_token: string;
}
export interface AuthRefreshResponse {
access_token: string;
}
// ----------------------------------------------------------------------------
// Target Channel
// ----------------------------------------------------------------------------
export interface TargetChannel {
id: string;
telegram_id: number;
title: string;
username: string | null; // @channel_name
description: string | null;
is_active: boolean;
created_at: string;
updated_at: string;
// Stats
total_purchases: number;
total_subscriptions: number;
avg_cpf: number | null; // Average Cost Per Follower
}
export interface TargetChannelDetail extends TargetChannel {
recent_purchases: Purchase[]; // last 5
stats_by_period: {
period: "day" | "week" | "month";
subscriptions: number;
cost: number;
cpf: number;
}[];
}
export interface TargetChannelUpdateRequest {
is_active: boolean;
}
// ----------------------------------------------------------------------------
// External Channel
// ----------------------------------------------------------------------------
export interface ExternalChannel {
id: string;
telegram_id: number | null;
title: string;
username: string | null;
link: string; // t.me link or custom
subscribers_count: number | null;
description: string | null;
created_at: string;
updated_at: string;
// Relations
target_channels: string[]; // IDs of target channels
// Stats
total_purchases: number;
avg_cpf: number | null;
avg_cpm: number | null;
}
export interface ExternalChannelDetail extends ExternalChannel {
purchases: Purchase[];
}
export interface ExternalChannelCreateRequest {
title: string;
username?: string;
link: string;
subscribers_count?: number;
description?: string;
target_channel_ids: string[]; // Привязка к целевым каналам
}
export interface ExternalChannelUpdateRequest {
title?: string;
username?: string;
link?: string;
subscribers_count?: number;
description?: string;
target_channel_ids?: string[];
}
export interface ExternalChannelImportResponse {
imported: number;
skipped: number;
errors: string[];
channels: ExternalChannel[];
}
// ----------------------------------------------------------------------------
// Creative
// ----------------------------------------------------------------------------
export interface Creative {
id: string;
name: string;
text: string; // Template with {link} placeholder
target_channel_id: string;
is_archived: boolean;
created_at: string;
updated_at: string;
// Relations
target_channel: TargetChannel;
// Stats
total_purchases: number;
total_subscriptions: number;
avg_cpf: number | null;
}
export interface CreativeDetail extends Creative {
purchases: Purchase[];
}
export interface CreativeCreateRequest {
name: string;
text: string; // Must contain {link} placeholder
target_channel_id: string;
}
export interface CreativeUpdateRequest {
name?: string;
text?: string;
is_archived?: boolean;
}
// ----------------------------------------------------------------------------
// Purchase
// ----------------------------------------------------------------------------
export type InviteLinkType = "public" | "private";
export interface Purchase {
id: string;
target_channel_id: string;
external_channel_id: string;
creative_id: string;
// Purchase details
scheduled_date: string | null; // ISO 8601
actual_date: string | null;
cost: number | null; // in rubles
comment: string | null;
post_link: string | null; // Link to ad post in external channel
invite_link: string; // Generated invite link
invite_link_type: InviteLinkType; // with bot approval or not
is_archived: boolean;
created_at: string;
updated_at: string;
// Relations
target_channel: TargetChannel;
external_channel: ExternalChannel;
creative: Creative;
// Stats
subscriptions_count: number;
views_count: number | null;
cpf: number | null; // Cost Per Follower
cpm: number | null; // Cost Per Mile (1000 views)
conversion_rate: number | null; // subscriptions / views * 100
}
export interface PurchaseDetail extends Purchase {
subscriptions: Subscription[];
views_history: ViewsSnapshot[];
}
export interface PurchaseCreateRequest {
target_channel_id: string;
external_channel_id: string;
creative_id: string;
scheduled_date?: string;
actual_date?: string;
cost?: number;
comment?: string;
post_link?: string;
invite_link_type: InviteLinkType;
}
export interface PurchaseCreateResponse extends Purchase {
formatted_message: string; // Creative text with invite_link inserted
}
export interface PurchaseUpdateRequest {
scheduled_date?: string;
actual_date?: string;
cost?: number;
comment?: string;
post_link?: string;
is_archived?: boolean;
}
export interface PurchaseRefreshViewsResponse {
views: number;
fetched_at: string;
}
// ----------------------------------------------------------------------------
// Subscription
// ----------------------------------------------------------------------------
export interface Subscription {
id: string;
purchase_id: string;
telegram_user_id: number;
user_first_name: string;
user_last_name: string | null;
user_username: string | null;
subscribed_at: string; // ISO 8601
is_active: boolean;
event_type: "chat_member" | "join_request";
}
// ----------------------------------------------------------------------------
// Views Snapshot
// ----------------------------------------------------------------------------
export interface ViewsSnapshot {
id: string;
purchase_id: string;
views: number;
fetched_at: string; // ISO 8601
}
// ----------------------------------------------------------------------------
// Analytics
// ----------------------------------------------------------------------------
export interface AnalyticsOverview {
totalPurchases: number;
purchasesChange: number;
totalFollowers: number;
followersChange: number;
averageCpf: number;
cpfChange: number;
averageCpm: number;
cpmChange: number;
topChannelsByCpf: {
channel_id: string;
channel_name: string;
total_purchases: number;
avg_cpf: number;
}[];
topCreativesByCpf: {
creative_id: string;
creative_name: string;
total_subscriptions: number;
avg_cpf: number;
}[];
}
export type GroupByPeriod = "day" | "week" | "month" | "quarter" | "year";
export interface AnalyticsCostsDataPoint {
period: string; // ISO 8601 date (start of period)
cost: number;
purchases_count: number;
subscriptions: number;
}
export interface AnalyticsCostsResponse {
data: AnalyticsCostsDataPoint[];
}
export interface CostsReport {
totalCost: number;
averageCost: number;
periods: {
date: string;
total_cost: number;
purchases_count: number;
avg_cost: number;
}[];
}
export interface AnalyticsChannelData {
channel_id: string;
channel_name: string;
purchases_count: number;
total_cost: number;
total_subscriptions: number;
avg_cpf: number;
avg_cpm: number;
}
export interface AnalyticsChannelsResponse {
data: AnalyticsChannelData[];
}
export interface AnalyticsCreativeData {
creative_id: string;
creative_name: string;
purchases_count: number;
total_cost: number;
total_subscriptions: number;
avg_cpf: number;
conversion_rate: number;
}
export interface AnalyticsCreativesResponse {
data: AnalyticsCreativeData[];
}
// ----------------------------------------------------------------------------
// Common API Responses
// ----------------------------------------------------------------------------
export interface ListResponse<T> {
data: T[];
total: number;
}
export interface SuccessResponse {
success: boolean;
}
export interface ApiError {
error: {
code: string;
message: string;
details?: any;
};
}
// ----------------------------------------------------------------------------
// Query Parameters
// ----------------------------------------------------------------------------
export interface TargetChannelQueryParams {
is_active?: boolean;
}
export interface ExternalChannelQueryParams {
target_channel_id?: string;
search?: string;
}
export interface CreativeQueryParams {
target_channel_id?: string;
is_archived?: boolean;
}
export interface PurchaseQueryParams {
target_channel_id?: string;
external_channel_id?: string;
creative_id?: string;
is_archived?: boolean;
date_from?: string; // ISO 8601
date_to?: string; // ISO 8601
sort?: "date" | "cost" | "cpf" | "subscriptions";
order?: "asc" | "desc";
}
export interface AnalyticsOverviewQueryParams {
target_channel_id?: string;
date_from?: string;
date_to?: string;
}
export interface AnalyticsCostsQueryParams {
target_channel_id?: string;
date_from: string; // required
date_to: string; // required
group_by: GroupByPeriod;
}
export interface AnalyticsChannelsQueryParams {
target_channel_id?: string;
date_from?: string;
date_to?: string;
type: "external" | "target";
}
export interface AnalyticsCreativesQueryParams {
target_channel_id?: string;
date_from?: string;
date_to?: string;
}