Files
portal/app/resources/js/api/reports.ts
T
Дмитрий e746b3c9a4 chore(cleanup): dead code removal + DemoSeeder env-conditional + schema header drift
Closes Audit #3 P2 batch (knip dead exports/components, DemoSeeder
hygiene, schema header drift).

- Remove app/resources/js/views/admin/AdminPlaceholderView.vue
  (unreferenced placeholder view — confirmed via repo-wide grep, only
  doc references remain)
- npm uninstall concurrently (no script invoked it; --legacy-peer-deps
  for Histoire 1.0-beta.1 peerDep quirk)
- 12 unused exports → internal types (remove `export` keyword):
  - api/admin.ts: AdminTenantsStats, ApiTenantMetrics,
    ApiAdminBillingSummary, ApiAdminIncidentsSummary
  - api/notifications.ts: NotificationEvent
  - api/reports.ts: ApiReportType, ApiReportFormat, ApiReportParameters,
    ReportCounts, ReportQuota
  - composables/mockBilling.ts: TxType
  - composables/useStatusPill.ts: StatusPillSlug
  All 12 are used INSIDE their own file (response shapes), just not
  exported externally — converting to internal types satisfies knip
  without losing type-checking inside the file.
- DatabaseSeeder::run() — DemoSeeder runs only in local+testing envs
  (`migrate:fresh --seed` in dev now produces demo tenant + admin@demo.local
  + 3 projects + ~14 demo deals; prod environments skip)
- db/schema.sql header line 4: «62 базовые таблицы» → «63 базовые
  таблицы (61 regular + 2 partitioned parents: deals + supplier_lead_costs)»
  Closes schema header drift finding from Phase 3.

Verification:
- vue-tsc --noEmit: 0 errors
- ESLint on touched files: 0 errors
- Pest --parallel: 742/739/3sk/0 failed (identical to baseline, no regressions)
- 2243 assertions / 34.46s

Plan: docs/superpowers/plans/2026-05-14-audit3-deferred-fixes.md Task 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 08:28:44 +03:00

117 lines
3.2 KiB
TypeScript

import { apiClient, ensureCsrfCookie } from './client';
/**
* Reports API (schema §13.5 report_jobs).
*
* Все endpoint'ы под Sanctum SPA auth. Mutating-вызовы (POST/DELETE)
* делают ensureCsrfCookie().
*
* Backend status: pending|processing|done|failed (schema-канон).
* UI mock использует queued|running|done|failed — конверсия в reportsMapper.
*/
export type ApiReportStatus = 'pending' | 'processing' | 'done' | 'failed';
type ApiReportType = 'deals_export' | 'managers_summary' | 'sources_summary' | 'billing_summary';
type ApiReportFormat = 'csv' | 'xlsx' | 'json' | 'pdf';
interface ApiReportParameters {
format: ApiReportFormat;
date_from: string;
date_to: string;
project_id?: number | null;
manager_id?: number | null;
retry_count?: number;
retry_of?: number;
}
export interface ApiReportJob {
id: number;
type: ApiReportType;
parameters: ApiReportParameters;
status: ApiReportStatus;
file_path: string | null;
file_size: number | null;
generation_seconds: number | null;
error_message: string | null;
created_at: string | null;
finished_at: string | null;
expires_at: string | null;
is_expired: boolean;
retry_count: number;
retry_max: number;
}
interface ReportCounts {
pending: number;
processing: number;
done: number;
failed: number;
}
interface ReportQuota {
active: number;
max_active: number;
}
export interface ListReportJobsResponse {
jobs: ApiReportJob[];
total: number;
limit: number;
offset: number;
counts: ReportCounts;
quota: ReportQuota;
}
export interface ListReportJobsParams {
status?: ApiReportStatus;
limit?: number;
offset?: number;
}
export async function listReportJobs(params: ListReportJobsParams = {}): Promise<ListReportJobsResponse> {
const { data } = await apiClient.get<ListReportJobsResponse>('/api/reports/jobs', {
params: {
status: params.status,
limit: params.limit,
offset: params.offset,
},
});
return data;
}
export interface CreateReportJobPayload {
type: ApiReportType;
format: ApiReportFormat;
parameters: {
date_from: string;
date_to: string;
project_id?: number | null;
manager_id?: number | null;
};
}
export async function createReportJob(payload: CreateReportJobPayload): Promise<ApiReportJob> {
await ensureCsrfCookie();
const { data } = await apiClient.post<{ job: ApiReportJob }>('/api/reports/jobs', payload);
return data.job;
}
export async function retryReportJob(id: number): Promise<ApiReportJob> {
await ensureCsrfCookie();
const { data } = await apiClient.post<{ job: ApiReportJob }>(`/api/reports/jobs/${id}/retry`);
return data.job;
}
export async function cancelReportJob(id: number): Promise<ApiReportJob> {
await ensureCsrfCookie();
const { data } = await apiClient.post<{ job: ApiReportJob }>(`/api/reports/jobs/${id}/cancel`);
return data.job;
}
export async function deleteReportJob(id: number): Promise<void> {
await ensureCsrfCookie();
await apiClient.delete(`/api/reports/jobs/${id}`);
}