xpeditis2.0/apps/frontend/src/lib/api/admin.ts
2026-09-14 20:02:12 +02:00

299 lines
8.6 KiB
TypeScript

/**
* Admin API
*
* Dedicated endpoints for admin-only operations that return ALL data from the database
* without organization filtering.
*
* All endpoints require ADMIN role.
*/
import { get, post, patch, del } from './client';
import type { BlogPost, BlogPostCategory, BlogPostStatus } from './blog';
import type {
UserResponse,
UserListResponse,
OrganizationResponse,
OrganizationListResponse,
BookingResponse,
BookingListResponse,
UpdateUserRequest,
} from '@/types/api';
// ==================== USERS ====================
/**
* Get ALL users from database (admin only)
* GET /api/v1/admin/users
* Returns all users regardless of status or organization
* Requires: ADMIN role
*/
export async function getAllUsers(): Promise<UserListResponse> {
return get<UserListResponse>('/api/v1/admin/users');
}
/**
* Get user by ID (admin only)
* GET /api/v1/admin/users/:id
* Requires: ADMIN role
*/
export async function getAdminUser(id: string): Promise<UserResponse> {
return get<UserResponse>(`/api/v1/admin/users/${id}`);
}
/**
* Update user (admin only)
* PATCH /api/v1/admin/users/:id
* Can update any user from any organization
* Requires: ADMIN role
*/
export async function updateAdminUser(id: string, data: UpdateUserRequest): Promise<UserResponse> {
return patch<UserResponse>(`/api/v1/admin/users/${id}`, data);
}
/**
* Delete user (admin only)
* DELETE /api/v1/admin/users/:id
* Permanently deletes user from database
* Requires: ADMIN role
*/
export async function deleteAdminUser(id: string): Promise<void> {
return del<void>(`/api/v1/admin/users/${id}`);
}
// ==================== ORGANIZATIONS ====================
/**
* Get ALL organizations from database (admin only)
* GET /api/v1/admin/organizations
* Returns all organizations regardless of status
* Requires: ADMIN role
*/
export async function getAllOrganizations(): Promise<OrganizationListResponse> {
return get<OrganizationListResponse>('/api/v1/admin/organizations');
}
/**
* Get organization by ID (admin only)
* GET /api/v1/admin/organizations/:id
* Requires: ADMIN role
*/
export async function getAdminOrganization(id: string): Promise<OrganizationResponse> {
return get<OrganizationResponse>(`/api/v1/admin/organizations/${id}`);
}
/**
* Verify SIRET for an organization via Pappers API (admin only)
* POST /api/v1/admin/organizations/:id/verify-siret
* Requires: ADMIN role
*/
export async function verifySiret(
organizationId: string
): Promise<{ verified: boolean; companyName?: string; address?: string; message: string }> {
return post(`/api/v1/admin/organizations/${organizationId}/verify-siret`, {});
}
/**
* Manually approve SIRET/SIREN for an organization (admin only)
* POST /api/v1/admin/organizations/:id/approve-siret
* Requires: ADMIN role
*/
export async function approveSiret(
organizationId: string
): Promise<{ approved: boolean; message: string; organizationName: string }> {
return post(`/api/v1/admin/organizations/${organizationId}/approve-siret`, {});
}
/**
* Reject SIRET/SIREN for an organization (admin only)
* POST /api/v1/admin/organizations/:id/reject-siret
* Requires: ADMIN role
*/
export async function rejectSiret(
organizationId: string
): Promise<{ rejected: boolean; message: string; organizationName: string }> {
return post(`/api/v1/admin/organizations/${organizationId}/reject-siret`, {});
}
// ==================== BOOKINGS ====================
/**
* Get ALL bookings from database (admin only)
* GET /api/v1/admin/bookings
* Returns all bookings from all organizations
* Requires: ADMIN role
*/
export async function getAllBookings(): Promise<BookingListResponse> {
return get<BookingListResponse>('/api/v1/admin/bookings');
}
/**
* Get booking by ID (admin only)
* GET /api/v1/admin/bookings/:id
* Requires: ADMIN role
*/
export async function getAdminBooking(id: string): Promise<BookingResponse> {
return get<BookingResponse>(`/api/v1/admin/bookings/${id}`);
}
/**
* Validate bank transfer for a booking (admin only)
* POST /api/v1/admin/bookings/:id/validate-transfer
* Confirms receipt of wire transfer and activates the booking
* Requires: ADMIN role
*/
export async function validateBankTransfer(
bookingId: string
): Promise<BookingResponse & { carrierEmailSent?: boolean }> {
return post<BookingResponse & { carrierEmailSent?: boolean }>(
`/api/v1/admin/bookings/${bookingId}/validate-transfer`,
{}
);
}
/**
* Resend the booking request email to the carrier (admin only)
* POST /api/v1/admin/bookings/:id/resend-carrier-email
* Useful when the email failed at transfer validation.
* Requires: ADMIN role
*/
export async function resendCarrierEmail(bookingId: string): Promise<void> {
return post<void>(`/api/v1/admin/bookings/${bookingId}/resend-carrier-email`, {});
}
/**
* Delete a booking (admin only)
* DELETE /api/v1/admin/bookings/:id
* Permanently deletes a booking from the database
* Requires: ADMIN role
*/
export async function deleteAdminBooking(bookingId: string): Promise<void> {
return del<void>(`/api/v1/admin/bookings/${bookingId}`);
}
/**
* Delete a document from a booking (admin only)
* DELETE /api/v1/admin/bookings/:bookingId/documents/:documentId
* Bypasses ownership and status restrictions
* Requires: ADMIN role
*/
export async function deleteAdminDocument(bookingId: string, documentId: string): Promise<void> {
return del<void>(`/api/v1/admin/bookings/${bookingId}/documents/${documentId}`);
}
// ==================== DOCUMENTS ====================
/**
* Get ALL documents from all organizations (admin only)
* GET /api/v1/admin/documents
* Returns documents grouped by organization
* Requires: ADMIN role
*/
export async function getAllDocuments(): Promise<{
documents: any[];
total: number;
organizationCount: number;
}> {
return get('/api/v1/admin/documents');
}
/**
* Get documents for a specific organization (admin only)
* GET /api/v1/admin/organizations/:id/documents
* Requires: ADMIN role
*/
export async function getOrganizationDocuments(organizationId: string): Promise<{
organizationId: string;
organizationName: string;
documents: any[];
total: number;
}> {
return get(`/api/v1/admin/organizations/${organizationId}/documents`);
}
// ==================== BLOG ====================
export interface BlogFaqItem {
question: string;
answer: string;
}
export interface BlogPostSeoFields {
metaTitle?: string;
metaDescription?: string;
primaryKeyword?: string;
secondaryKeywords?: string[];
scheduledAt?: string;
// GEO (Generative Engine Optimisation)
aiSummary?: string | null;
faq?: BlogFaqItem[];
keyTakeaways?: string[];
aiEntities?: string[];
}
export interface CreateBlogPostRequest extends BlogPostSeoFields {
title: string;
slug: string;
excerpt: string;
content: string;
coverImageUrl?: string | null;
category: BlogPostCategory;
tags?: string[];
authorName: string;
}
export interface UpdateBlogPostRequest extends BlogPostSeoFields {
title?: string;
slug?: string;
excerpt?: string;
content?: string;
coverImageUrl?: string | null;
category?: BlogPostCategory;
tags?: string[];
authorName?: string;
status?: BlogPostStatus;
isFeatured?: boolean;
}
export async function getAllBlogPosts(params?: {
status?: BlogPostStatus;
category?: BlogPostCategory;
search?: string;
trashed?: boolean;
}): Promise<{ posts: BlogPost[]; total: number }> {
const query = new URLSearchParams();
if (params?.status) query.set('status', params.status);
if (params?.category) query.set('category', params.category);
if (params?.search) query.set('search', params.search);
if (params?.trashed) query.set('trashed', 'true');
const qs = query.toString();
return get(`/api/v1/admin/blog${qs ? `?${qs}` : ''}`);
}
export async function createBlogPost(data: CreateBlogPostRequest): Promise<BlogPost> {
return post<BlogPost>('/api/v1/admin/blog', data);
}
export async function updateBlogPost(id: string, data: UpdateBlogPostRequest): Promise<BlogPost> {
return patch<BlogPost>(`/api/v1/admin/blog/${id}`, data);
}
/** Move a post to the trash (soft delete). */
export async function deleteBlogPost(id: string): Promise<void> {
return del<void>(`/api/v1/admin/blog/${id}`);
}
/** Restore a post from the trash. */
export async function restoreBlogPost(id: string): Promise<BlogPost> {
return post<BlogPost>(`/api/v1/admin/blog/${id}/restore`, {});
}
/** Permanently delete a post from the trash. */
export async function permanentlyDeleteBlogPost(id: string): Promise<void> {
return del<void>(`/api/v1/admin/blog/${id}/permanent`);
}
/** Duplicate a post as a new draft. */
export async function duplicateBlogPost(id: string): Promise<BlogPost> {
return post<BlogPost>(`/api/v1/admin/blog/${id}/duplicate`, {});
}