# API Template Documentation ## Base URL ``` http://api.yourdomain.com/ ``` --- ## General Notes - All requests and responses use JSON. - Set `Content-Type: application/json` in your requests. - CORS is enabled for all origins. - All timestamps are in UTC. - For POST, PUT, and DELETE, always include `performed_by` (user ID) and `reference` (e.g., invoice or PO number) in the request body for inventory tracking. --- ## Authentication Authentication is required for all endpoints except for `POST /login`, `POST /account`, and `GET /products`. The API uses token-based authentication. Include the token in the `Authorization` header: `Authorization: Bearer ` ### 1. Login **POST** `/login` **Request Example:** ```json { "email": "user@example.com", "password": "password123" } ``` **Response:** ```json { "success": true, "data": { "token": "your-auth-token", "id": 1, "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "created_at": "2025-08-25T12:00:00Z", "is_email_verified": true, "phone_number": "", "is_phone_verified": false, "role_id": 1, "role_name": "admin", "privileges": [ "create_account", "read_account", "update_account", "delete_account", "create_product", "read_product", "update_product", "delete_product", "create_invoice", "read_invoice", "update_invoice", "delete_invoice", "create_purchase_order", "read_purchase_order", "update_purchase_order", "delete_purchase_order" ] } } ``` ### 2. Logout **POST** `/logout` **Response:** ```json { "success": true } ``` --- ## Endpoints ### Accounts #### 1. Get Account by ID **GET** `/account/{id}` **Response:** ```json { "id": 1, "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "created_at": "2025-08-25T12:00:00Z", "role_id": 1, "role_name": "admin", "privileges": [ "create_account", "read_account", "update_account", "delete_account", "create_product", "read_product", "update_product", "delete_product", "create_invoice", "read_invoice", "update_invoice", "delete_invoice", "create_purchase_order", "read_purchase_order", "update_purchase_order", "delete_purchase_order" ] } ``` **If not found:** ```json { "error": "Account not found" } ``` --- #### 2. Add Account **POST** `/account` **Request Example:** ```json { "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.com", "password": "password123", "role_id": 2 } ``` **Response:** ```json { "success": true, "account_id": 2 } ``` **On error:** ```json { "error": "Missing required fields" } ``` --- #### 3. Verify Email **POST** `/account/verify-email` **Request Example:** ```json { "email": "jane.doe@example.com", "email_verification_code": "123456" } ``` **Response:** ```json { "success": true } ``` **On error:** ```json { "error": "Invalid or expired verification code" } ``` **Note:** The verification code expires in 15 minutes. --- #### 4. Update Account **PUT** `/account/{id}` **Request Example:** ```json { "first_name": "Jane", "last_name": "Smith", "role_id": 1 } ``` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Account not found" } ``` --- #### 5. Update Password **PUT** `/account/{id}/password` **Request Example:** ```json { "password": "new_password" } ``` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Account not found" } ``` --- #### 6. Delete Account **DELETE** `/account/{id}` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Account not found" } ``` --- ### Roles #### 1. List Roles **GET** `/roles` **Response:** ```json { "records": [ { "id": 1, "name": "admin", "privileges": [ "create_account", "read_account", "update_account", "delete_account", "create_product", "read_product", "update_product", "delete_product", "create_invoice", "read_invoice", "update_invoice", "delete_invoice", "create_purchase_order", "read_purchase_order", "update_purchase_order", "delete_purchase_order" ] }, { "id": 2, "name": "user", "privileges": [ "read_account", "update_account", "read_product", "read_invoice", "read_purchase_order" ] } ] } ``` --- ### Products #### 1. List Products **GET** `/products` **Response:** ```json { "data": [ { "product_id": 1, "sku": "LENS-001", "name": "Single Vision Lens", "category": "lens", "price": "120.00", "cost_price": "80.00", "created_at": "2025-08-25T12:00:00Z", "lens": { "lens_type": "Single Vision", "spherical_power": "-2.00", "cylindrical_power": "-0.50" } }, { "product_id": 2, "sku": "FRAME-001", "name": "Classic Frame", "category": "frame", "price": "200.00", "cost_price": "120.00", "created_at": "2025-08-25T12:05:00Z", "frame": { "brand_name": "RayBan", "model_number": "RB1234", "frame_type": "Full Rim" } } // ...more products ] } ``` --- #### 2. Get Product by ID **GET** `/products/{id}` **Response:** ```json { "product_id": 1, "sku": "LENS-001", "name": "Single Vision Lens", "category": "lens", "price": "120.00", "cost_price": "80.00", "created_at": "2025-08-25T12:00:00Z", "lens": { "lens_type": "Single Vision", "spherical_power": "-2.00", "cylindrical_power": "-0.50" } } ``` **If not found:** ```json { "error": "Product not found" } ``` --- #### 3. Add Product **POST** `/products` **Request Example (Lens):** ```json { "sku": "LENS-002", "name": "Progressive Lens", "category": "lens", "price": "150.00", "cost_price": "100.00", "lens_type": "Progressive", "spherical_power": "-1.50", "cylindrical_power": "-0.75", "performed_by": 5, "reference": "PO-2025-002" } ``` **Note:** Initial stock quantity should be set via the `/inventory/adjust` endpoint after creating the product. ``` **Request Example (Frame):** ```json { "sku": "FRAME-002", "name": "Modern Frame", "category": "frame", "quantity": 15, "price": "180.00", "cost_price": "110.00", "brand_name": "Oakley", "model_number": "OK2025", "frame_type": "Half Rim", "performed_by": 5, "reference": "PO-2025-003" } ``` **Request Example (Accessory):** ```json { "sku": "ACC-002", "name": "Microfiber Cloth", "category": "accessory", "quantity": 100, "price": "10.00", "cost_price": "3.00", "accessory_name": "Microfiber Cloth", "performed_by": 5, "reference": "PO-2025-004" } ``` **Response:** ```json { "success": true, "product_id": 2 } ``` **On error:** ```json { "error": "Missing required fields" } ``` --- #### 4. Update Product **PUT** `/products/{id}` **Request Example:** ```json { "quantity": 40, "price": "155.00", "performed_by": 5, "reference": "PO-2025-002" } ``` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Product not found" } ``` --- #### 5. Delete Product **DELETE** `/products/{id}` **Request Example:** ```json { "performed_by": 5, "reference": "PO-2025-002" } ``` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Product not found" } ``` --- ## Invoices ### 1. List Invoices **GET** `/invoices` **Response:** ```json { "data": [ { "invoice_id": 1, "invoice_number": "INV-2025-001", "customer_name": "John Doe", "mode_of_payment": "cash", "total_amount": "250.00", "created_at": "2025-08-25T12:00:00Z", "items": [ { "invoice_item_id": 1, "product_id": 1, "quantity": 2, "unit_price": "120.00" } ] } // ...more invoices ] } ``` --- ### 2. Get Invoice by ID **GET** `/invoices/{id}` **Response:** ```json { "invoice_id": 1, "invoice_number": "INV-2025-001", "customer_name": "John Doe", "mode_of_payment": "cash", "total_amount": "250.00", "created_at": "2025-08-25T12:00:00Z", "items": [ { "invoice_item_id": 1, "product_id": 1, "quantity": 2, "unit_price": "120.00" } ] } ``` **If not found:** ```json { "error": "Invoice not found" } ``` --- ### 3. Add Invoice **POST** `/invoices` **Request Example:** ```json { "invoice_number": "INV-2025-002", "customer_name": "Jane Smith", "mode_of_payment": "card", "total_amount": 300.00, "performed_by": 5, "items": [ { "product_id": 2, "quantity": 3, "unit_price": 100.00 } ] } ``` **Response:** ```json { "success": true, "invoice_id": 2 } ``` **On error:** ```json { "error": "Missing required fields" } ``` --- ### 4. Update Invoice **PUT** `/invoices/{id}` **Request Example:** ```json { "customer_name": "Jane Doe", "mode_of_payment": "cash" } ``` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Invoice not found" } ``` --- ### 5. Delete Invoice **DELETE** `/invoices/{id}` **Response:** ```json { "success": true } ``` **If not found:** ```json { "error": "Invoice not found" } ``` --- ## Purchase Orders ### 1. List Purchase Orders **GET** `/purchase-orders` **Response:** ```json { "data": [ { "po_id": 1, "po_number": "PO-2025-001", "supplier_name": "Acme Supplies", "order_date": "2025-08-20T10:00:00Z", "status": "pending", "total_amount": "500.00", "created_at": "2025-08-20T10:00:00Z", "items": [ { "po_item_id": 1, "product_id": 1, "quantity": 10, "unit_cost": "50.00", "total_cost": "500.00" } ] } // ...more purchase orders ] } ``` --- ### 2. Get Purchase Order by ID **GET** `/purchase-orders/{id}` **Response:** ```json { "po_id": 1, "po_number": "PO-2025-001", "supplier_name": "Acme Supplies", "order_date": "2025-08-20T10:00:00Z", "status": "pending", "total_amount": "500.00", "created_at": "2025-08-20T10:00:00Z", "items": [ { "po_item_id": 1, "product_id": 1, "quantity": 10, "unit_cost": "50.00", "total_cost": "500.00" } ] } ``` **If not found:** ```json { "error": "Purchase order not found" } ``` --- ### 3. Add Purchase Order **POST** `/purchase-orders` **Request Example:** ```json { "po_number": "PO-2025-002", "supplier_name": "Best Optics", "order_date": "2025-08-26T09:00:00Z", "status": "pending", "total_amount": 1000.00, "items": [ { "product_id": 2, "quantity": 20, "unit_cost": 50.00 } ] } ``` **Response:** ```json { "success": true, "po_id": 2 } ``` **On error:** ```json { "error": "Missing required fields" } ``` --- ### 4. Receive Purchase Order **PUT** `/purchase-orders/{id}/receive` **Request Example:** ```json { "performed_by": 5 } ``` **Response:** ```json { "success": true } ``` **If not found or already received:** ```json { "error": "Purchase order not found" } ``` or ```json { "error": "Purchase order already received" } ``` --- ## Inventory - Inventory movements are logged automatically when you add, update, or delete products, receive purchase orders, or create invoices. - You do not need to call inventory endpoints directly. - Each movement logs: `product_id`, `movement_type` (`in`, `out`, `adjust`), `quantity`, `reference`, `performed_by`. --- ## Error Responses **Example:** ```json { "error": "Product not found" } ``` --- ## Notes - Always include `performed_by` and `reference` in POST/PUT/DELETE requests for audit trails. - Attribute fields (e.g., `lens_type`, `brand_name`) must be included according to the product category. - All timestamps are in UTC. --- ## Other Endpoints - **Accounts:** `/account` - **Lens Stock:** `/lens-stock` - **Reports:** `/reports` > See similar patterns for GET, POST, PUT, DELETE as above. ---