# 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 <your_token>
```

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
  ]
}
```