# API Backend Documentation This document provides comprehensive documentation for all API endpoints in the `/api/backend/` namespace, with special focus on the Customers API which includes employee visibility control features. ## Table of Contents 1. [Authentication](#authentication) 2. [Common Response Format](#common-response-format) 3. [API Endpoints](#api-endpoints) - [Quick Inputs](#quick-inputs) - [Products](#products) - [Warehouses](#warehouses) - [Product Categories](#product-categories) - [Suppliers](#suppliers) - [Employees](#employees) - [Employee Types](#employee-types) - [Customers](#customers) - [Vehicle Types](#vehicle-types) - [Bank Accounts](#bank-accounts) - [Device Info](#device-info) - [Vehicle Transport Records](#vehicle-transport-records) - [User Profiles](#user-profiles) 4. [Error Handling](#error-handling) 5. [Pagination](#pagination) ## Authentication All API endpoints in the `/api/backend/` namespace require authentication. Requests must include a valid authentication token or session. ```http Authorization: Bearer ``` Or use session cookies for web-based applications. ## Common Response Format Most endpoints follow a standard response format: ### Success Response (200 OK, 201 Created) ```json { "id": 1, "field1": "value1", "field2": "value2", "created_at": "2025-11-24T10:00:00Z", "updated_at": "2025-11-24T10:00:00Z" } ``` ### List Response (200 OK) ```json { "count": 100, "next": "http://example.com/api/backend/endpoint/?page=2", "previous": null, "results": [ { "id": 1, "field1": "value1", ... } ] } ``` ### Error Response (400, 401, 403, 404, 500) ```json { "field_name": ["Error message for this field"], "non_field_errors": ["General error message"] } ``` ## API Endpoints ### Quick Inputs **Base URL**: `/api/backend/quick-inputs/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/quick-inputs/` | List | Retrieve all quick input items | | GET | `/api/backend/quick-inputs/{id}/` | Retrieve | Get a specific quick input item | | POST | `/api/backend/quick-inputs/` | Create | Create a new quick input item | | PUT | `/api/backend/quick-inputs/{id}/` | Update | Update a quick input item | | PATCH | `/api/backend/quick-inputs/{id}/` | Partial Update | Partially update a quick input item | | DELETE | `/api/backend/quick-inputs/{id}/` | Delete | Delete a quick input item | **Query Parameters**: - `group` (optional): Filter items by group **Request/Response Fields**: - `id`: Quick input ID - `name`: Name of the quick input - `value`: Value of the quick input - `group`: Group category for the quick input **Example Response**: ```json { "id": 1, "name": "常用尺寸", "value": "1.5米", "group": "尺寸" } ``` ### Products **Base URL**: `/api/backend/products/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/products/` | List | Retrieve all products | | GET | `/api/backend/products/{id}/` | Retrieve | Get a specific product | | POST | `/api/backend/products/` | Create | Create a new product | | PUT | `/api/backend/products/{id}/` | Update | Update a product | | PATCH | `/api/backend/products/{id}/` | Partial Update | Partially update a product | | DELETE | `/api/backend/products/{id}/` | Delete | Delete a product | **Request/Response Fields**: - `id`: Product ID - `name`: Product name - `category`: Product category (nested object) - `price`: Product price - `unit`: Unit of measurement - `image`: Product image file - `image_url`: URL of product image (generated) - `description`: Product description **Example Response**: ```json { "id": 1, "name": "纯棉印花布", "price": "25.50", "unit": 1, "description": "高品质纯棉印花布料", "image": "/media/products/cotton_fabric.jpg", "image_url": "http://example.com/media/products/cotton_fabric.jpg", "category": { "id": 3, "name": "印花布" }, "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Warehouses **Base URL**: `/api/backend/warehouses/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/warehouses/` | List | Retrieve all warehouses | | GET | `/api/backend/warehouses/{id}/` | Retrieve | Get a specific warehouse | | POST | `/api/backend/warehouses/` | Create | Create a new warehouse | | PUT | `/api/backend/warehouses/{id}/` | Update | Update a warehouse | | PATCH | `/api/backend/warehouses/{id}/` | Partial Update | Partially update a warehouse | | DELETE | `/api/backend/warehouses/{id}/` | Delete | Delete a warehouse | **Request/Response Fields**: - `id`: Warehouse ID - `name`: Warehouse name - `location`: Warehouse location - `type`: Warehouse type (1: Whole, 2: Scattered) **Example Response**: ```json { "id": 1, "name": "主仓库", "location": "园区A区1号", "type": 1, "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Product Categories **Base URL**: `/api/backend/product-categories/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/product-categories/` | List | Retrieve all product categories | | GET | `/api/backend/product-categories/{id}/` | Retrieve | Get a specific product category | | POST | `/api/backend/product-categories/` | Create | Create a new product category | | PUT | `/api/backend/product-categories/{id}/` | Update | Update a product category | | PATCH | `/api/backend/product-categories/{id}/` | Partial Update | Partially update a product category | | DELETE | `/api/backend/product-categories/{id}/` | Delete | Delete a product category | **Request/Response Fields**: - `id`: Category ID - `name`: Category name - `description`: Category description **Example Response**: ```json { "id": 1, "name": "印花布", "description": "各类印花布料", "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Suppliers **Base URL**: `/api/backend/suppliers/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/suppliers/` | List | Retrieve all suppliers | | GET | `/api/backend/suppliers/{id}/` | Retrieve | Get a specific supplier | | POST | `/api/backend/suppliers/` | Create | Create a new supplier | | PUT | `/api/backend/suppliers/{id}/` | Update | Update a supplier | | PATCH | `/api/backend/suppliers/{id}/` | Partial Update | Partially update a supplier | | DELETE | `/api/backend/suppliers/{id}/` | Delete | Delete a supplier | **Request/Response Fields**: - `id`: Supplier ID - `name`: Supplier name - `contact`: Contact person - `mobile`: Mobile phone number - `email`: Email address - `address`: Physical address - `description`: Additional description **Example Response**: ```json { "id": 1, "name": "华美纺织原料厂", "contact": "张经理", "mobile": "13800138001", "email": "zhang@huamei.com", "address": "广州市天河区科技园", "description": "长期合作的优质原料供应商", "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Employees **Base URL**: `/api/backend/employees/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/employees/` | List | Retrieve all employees | | GET | `/api/backend/employees/{id}/` | Retrieve | Get a specific employee | | POST | `/api/backend/employees/` | Create | Create a new employee | | PUT | `/api/backend/employees/{id}/` | Update | Update an employee | | PATCH | `/api/backend/employees/{id}/` | Partial Update | Partially update an employee | | DELETE | `/api/backend/employees/{id}/` | Delete | Delete an employee | **Request/Response Fields**: - `id`: Employee ID - `name`: Employee name - `position`: Employee position (EmployeeType object) - `job_type`: Job type (read-only string derived from position) - `mobile`: Mobile phone number - `status`: Employee status - `sys_user`: Associated Django User ID (nullable) **Example Response**: ```json { "id": 1, "name": "张三", "position": { "id": 2, "title": "打纸工", "description": "负责打纸工作", "merchant": 1 }, "job_type": "打纸工", "mobile": "13800138000", "status": "在职", "sys_user": 5, "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Employee Types **Base URL**: `/api/backend/employee-types/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/employee-types/` | List | Retrieve all employee types | | GET | `/api/backend/employee-types/{id}/` | Retrieve | Get a specific employee type | | POST | `/api/backend/employee-types/` | Create | Create a new employee type | | PUT | `/api/backend/employee-types/{id}/` | Update | Update an employee type | | PATCH | `/api/backend/employee-types/{id}/` | Partial Update | Partially update an employee type | | DELETE | `/api/backend/employee-types/{id}/` | Delete | Delete an employee type | **Request/Response Fields**: - `id`: Employee type ID - `title`: Type title - `description`: Type description **Example Response**: ```json { "id": 1, "title": "打纸工", "description": "负责打纸工作", "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Customers **Base URL**: `/api/backend/customers/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/customers/` | List | Retrieve customers visible to the current employee | | GET | `/api/backend/customers/{id}/` | Retrieve | Get a specific customer (if visible to current employee) | | POST | `/api/backend/customers/` | Create | Create a new customer | | PUT | `/api/backend/customers/{id}/` | Update | Update a customer (if visible to current employee) | | PATCH | `/api/backend/customers/{id}/` | Partial Update | Partially update a customer (if visible to current employee) | | DELETE | `/api/backend/customers/{id}/` | Delete | Delete a customer (if visible to current employee) | #### Customer Visibility System The Customers API implements a visibility control system that restricts which customers are accessible to each employee. This system works as follows: **Visibility Rules**: 1. A customer is visible to an employee if: - The employee created the customer, OR - The employee is explicitly added to the customer's `visible_employees` list, OR - The employee is a superuser or has `basic_info.view_all_customers` permission 2. When listing customers, the API automatically filters to only show customers visible to the current employee. 3. When accessing a specific customer (GET, PUT, PATCH, DELETE), the API checks if the customer is visible to the current employee. If not, a 404 Not Found response is returned. **Request/Response Fields**: - `id`: Customer ID - `name`: Customer name - `mobile`: Mobile phone number - `email`: Email address - `contact`: Contact person - `area`: Geographic area - `description`: Additional description - `visible_employees`: List of employee IDs who can view this customer - `created_by`: ID of the employee who created this customer (auto-set on creation) **Creating a Customer (POST)**: ```json { "name": "Acme Corporation", "mobile": "13800138000", "email": "contact@acme.com", "contact": "John Doe", "area": "Beijing", "description": "Regular wholesale customer", "visible_employees": [1, 2, 3] // Optional: employees who can view this customer } ``` **Updating a Customer (PUT/PATCH)**: When updating a customer, the same visibility rules apply: - The employee must be able to see the customer to update it - The `visible_employees` field can be updated to add or remove access for other employees ```json { "name": "Updated Customer Name", "visible_employees": [1, 4, 5] // Updated list of employees who can view this customer } ``` **Example Response**: ```json { "id": 1, "name": "北京服装批发公司", "mobile": "13800138000", "email": "beijing@clothing.com", "contact": "李经理", "area": "北京朝阳区", "description": "长期合作的服装批发客户", "visible_employees": [1, 3, 5], "created_by": 1, "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` **Security Note**: Customer visibility is enforced at the API level. Attempts to access a customer that isn't visible to the current employee will result in a 404 Not Found response, regardless of whether the customer actually exists in the database. #### Customer Visibility System The Customers API implements a visibility control system that restricts which customers are accessible to each employee. This system works as follows: **Visibility Rules**: 1. A customer is visible to an employee if: - The employee created the customer, OR - The employee is explicitly added to the customer's `visible_employees` list, OR - The employee is a superuser or has `basic_info.view_all_customers` permission 2. When listing customers, the API automatically filters to only show customers visible to the current employee. 3. When accessing a specific customer (GET, PUT, PATCH, DELETE), the API checks if the customer is visible to the current employee. If not, a 404 Not Found response is returned. **Request/Response Fields**: - `id`: Customer ID - `name`: Customer name - `mobile`: Mobile phone number - `email`: Email address - `contact`: Contact person - `area`: Geographic area - `description`: Additional description - `visible_employees`: List of employee IDs who can view this customer - `created_by`: ID of the employee who created this customer (auto-set on creation) **Creating a Customer (POST)**: ```json { "name": "Acme Corporation", "mobile": "13800138000", "email": "contact@acme.com", "contact": "John Doe", "area": "Beijing", "description": "Regular wholesale customer", "visible_employees": [1, 2, 3] // Optional: employees who can view this customer } ``` **Updating a Customer (PUT/PATCH)**: When updating a customer, the same visibility rules apply: - The employee must be able to see the customer to update it - The `visible_employees` field can be updated to add or remove access for other employees ```json { "name": "Updated Customer Name", "visible_employees": [1, 4, 5] // Updated list of employees who can view this customer } ``` **Security Note**: Customer visibility is enforced at the API level. Attempts to access a customer that isn't visible to the current employee will result in a 404 Not Found response, regardless of whether the customer actually exists in the database. ### Vehicle Types **Base URL**: `/api/backend/vehicle-types/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/vehicle-types/` | List | Retrieve all vehicle types | | GET | `/api/backend/vehicle-types/{id}/` | Retrieve | Get a specific vehicle type | | POST | `/api/backend/vehicle-types/` | Create | Create a new vehicle type | | PUT | `/api/backend/vehicle-types/{id}/` | Update | Update a vehicle type | | PATCH | `/api/backend/vehicle-types/{id}/` | Partial Update | Partially update a vehicle type | | DELETE | `/api/backend/vehicle-types/{id}/` | Delete | Delete a vehicle type | **Request/Response Fields**: - `id`: Vehicle type ID - `name`: Type name - `capacity`: Vehicle capacity - `description`: Type description **Example Response**: ```json { "id": 1, "name": "小型货车", "capacity": "500公斤", "description": "适合小批量货物运输", "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Bank Accounts **Base URL**: `/api/backend/bank-accounts/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/bank-accounts/` | List | Retrieve all bank accounts | | GET | `/api/backend/bank-accounts/{id}/` | Retrieve | Get a specific bank account | | POST | `/api/backend/bank-accounts/` | Create | Create a new bank account | | PUT | `/api/backend/bank-accounts/{id}/` | Update | Update a bank account | | PATCH | `/api/backend/bank-accounts/{id}/` | Partial Update | Partially update a bank account | | DELETE | `/api/backend/bank-accounts/{id}/` | Delete | Delete a bank account | **Request/Response Fields**: - `id`: Account ID - `bank_name`: Bank name - `account_number`: Account number - `account_holder`: Account holder name - `branch`: Bank branch - `is_default`: Whether this is the default account **Example Response**: ```json { "id": 1, "bank_name": "中国工商银行", "account_number": "6222021234567890", "account_holder": "张三", "branch": "广州天河支行", "is_default": true, "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Device Info **Base URL**: `/api/backend/device-info/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/device-info/` | List | Retrieve all device information | | GET | `/api/backend/device-info/{id}/` | Retrieve | Get specific device information | | POST | `/api/backend/device-info/` | Create | Create new device information | | PUT | `/api/backend/device-info/{id}/` | Update | Update device information | | PATCH | `/api/backend/device-info/{id}/` | Partial Update | Partially update device information | | DELETE | `/api/backend/device-info/{id}/` | Delete | Delete device information | **Request/Response Fields**: - `id`: Device ID - `name`: Device name - `type`: Device type (ROLLING, PRINTING, etc.) - `status`: Device status (ACTIVE, MAINTENANCE, etc.) - `start_working_at`: Date when device started working - `stop_working_at`: Date when device stopped working - `is_occupied`: Whether device is currently occupied - `description`: Additional description **Example Response**: ```json { "id": 1, "name": "滚筒机A", "type": "ROLLING", "status": "ACTIVE", "start_working_at": "2025-01-15", "stop_working_at": null, "is_occupied": true, "description": "主要生产用滚筒设备", "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### Vehicle Transport Records **Base URL**: `/api/backend/vehicle-transport-records/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/vehicle-transport-records/` | List | Retrieve all transport records | | GET | `/api/backend/vehicle-transport-records/{id}/` | Retrieve | Get a specific transport record | | POST | `/api/backend/vehicle-transport-records/` | Create | Create a new transport record | | PUT | `/api/backend/vehicle-transport-records/{id}/` | Update | Update a transport record | | PATCH | `/api/backend/vehicle-transport-records/{id}/` | Partial Update | Partially update a transport record | | DELETE | `/api/backend/vehicle-transport-records/{id}/` | Delete | Delete a transport record | **Request/Response Fields**: - `id`: Record ID - `vehicle_type`: Vehicle type (nested object) - `driver_name`: Driver name - `driver_mobile`: Driver mobile phone - `transport_date`: Date of transport - `source`: Source location - `destination`: Destination location - `goods_description`: Description of goods being transported - `quantity`: Quantity of goods - `status`: Transport status - `notes`: Additional notes - `vehicle_type_name`: Read-only derived vehicle type name **Example Response**: ```json { "id": 1, "vehicle_type": { "id": 1, "name": "小型货车", "capacity": "500公斤", "description": "适合小批量货物运输" }, "driver_name": "王师傅", "driver_mobile": "13900139000", "transport_date": "2025-11-24", "source": "广州工厂", "destination": "深圳客户", "goods_description": "印花布料", "quantity": "300公斤", "status": "COMPLETED", "notes": "运输顺利", "vehicle_type_name": "小型货车", "merchant": 1, "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ### User Profiles **Base URL**: `/api/backend/user-profiles/` | Method | URL Pattern | Action | Description | |--------|-------------|---------|-------------| | GET | `/api/backend/user-profiles/` | List | Retrieve all user profiles for current merchant | | GET | `/api/backend/user-profiles/{id}/` | Retrieve | Get a specific user profile | | POST | `/api/backend/user-profiles/` | Create | Create a new user profile | | PUT | `/api/backend/user-profiles/{id}/` | Update | Update a user profile | | PATCH | `/api/backend/user-profiles/{id}/` | Partial Update | Partially update a user profile | | DELETE | `/api/backend/user-profiles/{id}/` | Delete | Delete a user profile | **Request/Response Fields**: - `id`: Profile ID - `user`: User ID (for writing) - `user_detail`: User object details (for reading) - `merchant`: Merchant ID (auto-set to current user's merchant) - `description`: Profile description - `created_at`: Creation timestamp - `updated_at`: Last update timestamp **Creating a User Profile (POST)**: ```json { "user": 123, // User ID "description": "User profile for system access" } ``` **Example Response**: ```json { "id": 1, "user": 5, "user_detail": { "id": 5, "username": "testuser", "email": "test@example.com", "is_active": true, "is_superuser": false, "last_login": "2025-11-24T09:00:00Z" }, "merchant": 1, "description": "用户资料描述", "created_at": "2025-11-24T10:30:00Z", "updated_at": "2025-11-24T10:30:00Z" } ``` ## Error Handling All endpoints may return the following error responses: ### 401 Unauthorized ```json { "detail": "Authentication credentials were not provided." } ``` ### 403 Forbidden ```json { "detail": "You do not have permission to perform this action." } ``` ### 404 Not Found ```json { "detail": "Not found." } ``` ### 400 Bad Request ```json { "field_name": ["Error message for this field"], "non_field_errors": ["General error message"] } ``` ### 500 Server Error ```json { "detail": "A server error occurred." } ``` ## Pagination List endpoints support pagination using the LimitOffsetPagination scheme. **Query Parameters**: - `limit`: Number of results to return per page - `offset`: Number of results to skip **Example**: ``` GET /api/backend/products/?limit=20&offset=40 ``` This will return 20 items starting from position 40 (items 41-60). **Response Format**: ```json { "count": 150, "next": "http://example.com/api/backend/products/?limit=20&offset=60", "previous": "http://example.com/api/backend/products/?limit=20&offset=20", "results": [ { "id": 41, "name": "Product 41", ... } // ... up to 20 items ] } ```