# File Management API Documentation ## Overview The File Management API provides a complete CRUD system for handling file uploads with organized storage, metadata management, and file organization by categories and clients. ## Base URL ``` /api/files ``` ## Authentication All file routes require authentication using Sanctum tokens. ## File Organization Structure Files are automatically organized in storage following this structure: ``` storage/app/public/ ├── client/{client_id}/{category}/{subcategory}/filename.pdf ├── client/{client_id}/devis/DEVIS_2024_12_01_10_30_45.pdf ├── client/{client_id}/facture/FACT_2024_12_01_10_30_45.pdf └── general/{category}/{subcategory}/filename.pdf ``` ### Supported Categories - `devis` - Quotes/Devis - `facture` - Invoices/Factures - `contrat` - Contracts - `document` - General Documents - `image` - Images - `autre` - Other files ## Endpoints Overview ### 1. List All Files ```http GET /api/files ``` **Parameters:** - `per_page` (optional): Number of files per page (default: 15) - `search` (optional): Search by filename - `mime_type` (optional): Filter by MIME type - `uploaded_by` (optional): Filter by uploader user ID - `category` (optional): Filter by category - `client_id` (optional): Filter by client ID - `date_from` (optional): Filter files uploaded after date (YYYY-MM-DD) - `date_to` (optional): Filter files uploaded before date (YYYY-MM-DD) - `sort_by` (optional): Sort field (default: uploaded_at) - `sort_direction` (optional): Sort direction (default: desc) **Response:** ```json { "data": [ { "id": 1, "file_name": "document.pdf", "mime_type": "application/pdf", "size_bytes": 1024000, "size_formatted": "1000.00 KB", "extension": "pdf", "storage_uri": "client/123/devis/DEVIS_2024_12_01_10_30_45.pdf", "organized_path": "client/123/devis/DEVIS_2024_12_01_10_30_45.pdf", "sha256": "abc123...", "uploaded_by": 1, "uploader_name": "John Doe", "uploaded_at": "2024-12-01 10:30:45", "is_image": false, "is_pdf": true, "category": "devis", "subcategory": "general" } ], "pagination": { "current_page": 1, "from": 1, "last_page": 5, "per_page": 15, "to": 15, "total": 75, "has_more_pages": true }, "summary": { "total_files": 15, "total_size": 15360000, "total_size_formatted": "14.65 MB", "categories": { "devis": { "count": 8, "total_size_formatted": "8.24 MB" }, "facture": { "count": 7, "total_size_formatted": "6.41 MB" } } } } ``` ### 2. Upload File ```http POST /api/files ``` **Content-Type:** `multipart/form-data` **Parameters:** - `file` (required): The file to upload (max 10MB) - `file_name` (optional): Custom filename (uses original name if not provided) - `category` (required): File category (devis|facture|contrat|document|image|autre) - `client_id` (optional): Associated client ID - `subcategory` (optional): Subcategory for better organization - `description` (optional): File description (max 500 chars) - `tags` (optional): Array of tags (max 10 tags, 50 chars each) - `is_public` (optional): Whether file is publicly accessible **Example Request:** ```bash curl -X POST \ http://localhost/api/files \ -H "Authorization: Bearer {token}" \ -F "file=@/path/to/document.pdf" \ -F "category=devis" \ -F "client_id=123" \ -F "subcategory=annual" \ -F "description=Annual quote for client" \ -F 'tags[]=quote' \ -F 'tags[]=annual' ``` **Success Response (201):** ```json { "data": { "id": 1, "file_name": "document.pdf", "mime_type": "application/pdf", "size_bytes": 1024000, "storage_uri": "client/123/devis/annual/document_2024_12_01_10_30_45.pdf", "category": "devis", "subcategory": "annual", "uploaded_at": "2024-12-01 10:30:45" }, "message": "Fichier téléchargé avec succès." } ``` ### 3. Get File Details ```http GET /api/files/{id} ``` **Response:** Same as file object in list endpoint ### 4. Update File Metadata ```http PUT /api/files/{id} ``` **Parameters:** - `file_name` (optional): New filename - `description` (optional): Updated description - `tags` (optional): Updated tags array - `is_public` (optional): Updated public status - `category` (optional): Move to new category - `client_id` (optional): Change associated client - `subcategory` (optional): Update subcategory **Note:** If category, client_id, or subcategory are changed, the file will be automatically moved to the new location. ### 5. Delete File ```http DELETE /api/files/{id} ``` **Response:** ```json { "message": "Fichier supprimé avec succès." } ``` ### 6. Get Files by Category ```http GET /api/files/by-category/{category} ``` **Parameters:** Same as list endpoint with additional `per_page` ### 7. Get Files by Client ```http GET /api/files/by-client/{clientId} ``` **Parameters:** Same as list endpoint with additional `per_page` ### 8. Get Organized File Structure ```http GET /api/files/organized ``` **Response:** ```json { "data": { "devis/general": { "category": "devis", "subcategory": "general", "files": [...], "count": 25 }, "facture/annual": { "category": "facture", "subcategory": "annual", "files": [...], "count": 15 } }, "message": "Structure de fichiers récupérée avec succès." } ``` ### 9. Get Storage Statistics ```http GET /api/files/statistics ``` **Response:** ```json { "data": { "total_files": 150, "total_size_bytes": 1073741824, "total_size_formatted": "1.00 GB", "by_type": { "application/pdf": { "count": 85, "total_size": 734003200 }, "image/jpeg": { "count": 45, "total_size": 209715200 } }, "by_category": { "devis": { "count": 60, "total_size": 429496729 }, "facture": { "count": 50, "total_size": 322122547 } } }, "message": "Statistiques de stockage récupérées avec succès." } ``` ### 10. Generate Download URL ```http GET /api/files/{id}/download ``` **Response:** ```json { "data": { "download_url": "/storage/client/123/devis/document_2024_12_01_10_30_45.pdf", "file_name": "document.pdf", "mime_type": "application/pdf" }, "message": "URL de téléchargement générée avec succès." } ``` ## Error Responses ### Validation Error (422) ```json { "message": "Les données fournies ne sont pas valides.", "errors": { "file": ["Le fichier est obligatoire."], "category": ["La catégorie est obligatoire."] } } ``` ### Not Found (404) ```json { "message": "Fichier non trouvé." } ``` ### Server Error (500) ```json { "message": "Une erreur est survenue lors du traitement de la requête.", "error": "Detailed error message (only in debug mode)" } ``` ## File Features ### Automatic Organization - Files are automatically organized by category and client - Timestamps are added to prevent filename conflicts - Safe slug generation for subcategories ### Security - SHA256 hash calculation for file integrity - User-based access control - File size validation (10MB limit) ### Metadata Support - MIME type detection - File size tracking - Upload timestamp - User attribution - Custom tags and descriptions ### Storage Management - Public storage disk usage - Efficient path organization - Duplicate prevention through hashing - Automatic file moving on metadata updates ## Usage Examples ### Upload a Quote for Client ```bash curl -X POST \ http://localhost/api/files \ -H "Authorization: Bearer {token}" \ -F "file=@quote_2024.pdf" \ -F "category=devis" \ -F "client_id=123" \ -F "subcategory=annual_2024" \ -F 'tags[]=quote' \ -F 'tags[]=annual' ``` ### Get All Client Files ```bash curl -X GET \ "http://localhost/api/files/by-client/123?per_page=20&sort_by=uploaded_at&sort_direction=desc" \ -H "Authorization: Bearer {token}" ``` ### Get File Statistics ```bash curl -X GET \ "http://localhost/api/files/statistics" \ -H "Authorization: Bearer {token}" ``` ### Search Files ```bash curl -X GET \ "http://localhost/api/files?search=annual&category=devis" \ -H "Authorization: Bearer {token}" ``` ## Notes - All file operations are logged for audit purposes - Files are stored in `storage/app/public/` directory - The system automatically handles file moving when categories change - Download URLs are generated on-demand for security - Pagination is applied to all list endpoints - French language is used for all API messages and validations