/** * 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 { return get('/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 { return get(`/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 { return patch(`/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 { return del(`/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 { return get('/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 { return get(`/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 { return get('/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 { return get(`/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 { return post( `/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 { return post(`/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 { return del(`/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 { return del(`/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 { return post('/api/v1/admin/blog', data); } export async function updateBlogPost(id: string, data: UpdateBlogPostRequest): Promise { return patch(`/api/v1/admin/blog/${id}`, data); } /** Move a post to the trash (soft delete). */ export async function deleteBlogPost(id: string): Promise { return del(`/api/v1/admin/blog/${id}`); } /** Restore a post from the trash. */ export async function restoreBlogPost(id: string): Promise { return post(`/api/v1/admin/blog/${id}/restore`, {}); } /** Permanently delete a post from the trash. */ export async function permanentlyDeleteBlogPost(id: string): Promise { return del(`/api/v1/admin/blog/${id}/permanent`); } /** Duplicate a post as a new draft. */ export async function duplicateBlogPost(id: string): Promise { return post(`/api/v1/admin/blog/${id}/duplicate`, {}); }