7ac9af7c79
Правило продукта: ограничений по количеству проектов нет, лимит только по балансу и заказанным лидам. Убран гейт tenants.limits.max_projects в ProjectService::create и показ лимита проектов на дашборде. Поле limits оставлено как резерв; max_users и api_rps в коде не используются. Заодно фикс типа в EditProjectDialog.spec: sampleProject типизирован настоящим Project, source_locked больше не краснит vue-tsc. Тесты: ProjectsStore 13/13, DashboardSummary 11/11, DashboardView 8/8, EditProjectDialog 7/7; vue-tsc чисто; pint чисто; vite build ок. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import { apiClient } from './client';
|
|
|
|
/**
|
|
* API-клиент дашборда (audit C1/J3). Эндпоинт GET /api/dashboard/summary.
|
|
* На MVP без auth — tenant_id параметром (на prod возьмётся из middleware).
|
|
*/
|
|
|
|
export type DeltaDir = 'up' | 'down' | 'neutral';
|
|
export type DashboardRange = 'today' | '7d' | '30d';
|
|
|
|
export interface DashboardSummary {
|
|
range: string;
|
|
leads_received: { value: number; delta_pct: number; delta_dir: DeltaDir };
|
|
conversion: { value: number; delta_pp: number; delta_dir: DeltaDir };
|
|
active_projects: { active: number };
|
|
balance: { amount_rub: string; runway_days: number | null; runway_leads: number };
|
|
activity: { points: number[]; labels: string[]; max: number };
|
|
funnel: Record<string, number>;
|
|
/** Средняя стоимость лида (₽) за окно периода; null — если в окне нет rub-списаний. */
|
|
avg_lead_cost_rub: number | null;
|
|
}
|
|
|
|
export async function getDashboardSummary(tenantId: number, range: DashboardRange): Promise<DashboardSummary> {
|
|
const { data } = await apiClient.get<DashboardSummary>('/api/dashboard/summary', {
|
|
params: { tenant_id: tenantId, range },
|
|
});
|
|
return data;
|
|
}
|