mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-05-27 09:49:26 -04:00
Add comprehensive OpenAPI specification for OSPOS REST API including: - Customers API (CRUD operations) - Suppliers API (CRUD operations) - Items API (CRUD operations with inventory quantities) - Inventory API (stock adjustments) - Sales API (read-only queries) - Receivings API (read-only queries) Features: - API Key authentication via X-API-Key header - Pagination with offset/limit parameters - Soft delete support for customers, suppliers, items - Batch operations for delete and update - Search/suggest endpoints for autocomplete - Comprehensive schema definitions based on existing models Includes documentation with: - Endpoint reference tables - Schema field descriptions - Implementation notes and discussion topics - HTTP status codes and response formats This is a design proposal for discussion before implementation.
295 lines
13 KiB
Markdown
295 lines
13 KiB
Markdown
# OSPOS REST API Design
|
|
|
|
This document describes the proposed REST API for Open Source Point of Sale (OSPOS).
|
|
|
|
## Overview
|
|
|
|
The OSPOS REST API provides programmatic access to:
|
|
|
|
- **Customers** - Full CRUD operations
|
|
- **Suppliers** - Full CRUD operations
|
|
- **Items** - Full CRUD operations
|
|
- **Inventory** - Stock adjustments (update only)
|
|
- **Sales** - Read-only queries
|
|
- **Receivings** - Read-only queries
|
|
|
|
## Authentication
|
|
|
|
All API endpoints require authentication via an API Key passed in the `X-API-Key` header.
|
|
|
|
```
|
|
X-API-Key: your-api-key-here
|
|
```
|
|
|
|
> **Note:** API Key authentication implementation will be added in a subsequent phase. The spec documents the intended authentication mechanism.
|
|
|
|
## Base URL
|
|
|
|
All API endpoints are relative to `/api/v1`.
|
|
|
|
```
|
|
https://your-domain.com/api/v1/customers
|
|
```
|
|
|
|
## Pagination
|
|
|
|
List endpoints support pagination using `offset` and `limit` query parameters:
|
|
|
|
| Parameter | Type | Default | Maximum | Description |
|
|
|-----------|---------|---------|---------|------------------------------|
|
|
| `offset` | integer | 0 | - | Number of records to skip |
|
|
| `limit` | integer | 25 | 100 | Number of records to return |
|
|
|
|
**Example Request:**
|
|
```
|
|
GET /api/v1/customers?offset=0&limit=25
|
|
```
|
|
|
|
**Example Response:**
|
|
```json
|
|
{
|
|
"total": 150,
|
|
"offset": 0,
|
|
"limit": 25,
|
|
"rows": [
|
|
{ "person_id": 1, "first_name": "John", ... },
|
|
{ "person_id": 2, "first_name": "Jane", ... }
|
|
]
|
|
}
|
|
```
|
|
|
|
## Response Format
|
|
|
|
### Success Response
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Customer created successfully",
|
|
"id": 42
|
|
}
|
|
```
|
|
|
|
### Error Response
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Error description here"
|
|
}
|
|
```
|
|
|
|
### HTTP Status Codes
|
|
|
|
| Status Code | Description |
|
|
|-------------|--------------------------------------------------|
|
|
| 200 | Success |
|
|
| 201 | Resource created successfully |
|
|
| 400 | Bad request / Invalid input |
|
|
| 401 | Unauthorized / Invalid API key |
|
|
| 404 | Resource not found |
|
|
| 409 | Conflict (e.g., duplicate unique field) |
|
|
| 500 | Internal server error |
|
|
|
|
## Endpoints Summary
|
|
|
|
### Customers
|
|
|
|
| Method | Endpoint | Description | Access |
|
|
|--------|-------------------------------|--------------------------------|---------|
|
|
| GET | `/customers` | List customers | Read |
|
|
| POST | `/customers` | Create customer | Write |
|
|
| GET | `/customers/{id}` | Get customer by ID | Read |
|
|
| PUT | `/customers/{id}` | Update customer | Write |
|
|
| DELETE | `/customers/{id}` | Delete customer (soft delete) | Write |
|
|
| POST | `/customers/batch-delete` | Delete multiple customers | Write |
|
|
| GET | `/customers/suggest` | Autocomplete suggestions | Read |
|
|
|
|
### Suppliers
|
|
|
|
| Method | Endpoint | Description | Access |
|
|
|--------|-------------------------------|--------------------------------|---------|
|
|
| GET | `/suppliers` | List suppliers | Read |
|
|
| POST | `/suppliers` | Create supplier | Write |
|
|
| GET | `/suppliers/{id}` | Get supplier by ID | Read |
|
|
| PUT | `/suppliers/{id}` | Update supplier | Write |
|
|
| DELETE | `/suppliers/{id}` | Delete supplier (soft delete) | Write |
|
|
| POST | `/suppliers/batch-delete` | Delete multiple suppliers | Write |
|
|
| GET | `/suppliers/suggest` | Autocomplete suggestions | Read |
|
|
|
|
### Items
|
|
|
|
| Method | Endpoint | Description | Access |
|
|
|--------|-------------------------------|--------------------------------|---------|
|
|
| GET | `/items` | List items | Read |
|
|
| POST | `/items` | Create item | Write |
|
|
| GET | `/items/{id}` | Get item by ID | Read |
|
|
| PUT | `/items/{id}` | Update item | Write |
|
|
| DELETE | `/items/{id}` | Delete item (soft delete) | Write |
|
|
| POST | `/items/batch-delete` | Delete multiple items | Write |
|
|
| POST | `/items/batch-update` | Update multiple items | Write |
|
|
| GET | `/items/suggest` | Autocomplete suggestions | Read |
|
|
| GET | `/items/{id}/quantities` | Get stock quantities | Read |
|
|
|
|
### Inventory
|
|
|
|
| Method | Endpoint | Description | Access |
|
|
|--------|-------------------------------|--------------------------------|---------|
|
|
| GET | `/inventory` | List inventory transactions | Read |
|
|
| POST | `/inventory` | Create inventory adjustment | Write |
|
|
| POST | `/inventory/bulk` | Bulk inventory adjustments | Write |
|
|
|
|
### Sales (Read-Only)
|
|
|
|
| Method | Endpoint | Description | Access |
|
|
|--------|-------------------------------|--------------------------------|---------|
|
|
| GET | `/sales` | List sales | Read |
|
|
| GET | `/sales/{id}` | Get sale details | Read |
|
|
| GET | `/sales/{id}/items` | Get sale items | Read |
|
|
| GET | `/sales/{id}/payments` | Get sale payments | Read |
|
|
|
|
### Receivings (Read-Only)
|
|
|
|
| Method | Endpoint | Description | Access |
|
|
|--------|-------------------------------|--------------------------------|---------|
|
|
| GET | `/receivings` | List receivings | Read |
|
|
| GET | `/receivings/{id}` | Get receiving details | Read |
|
|
| GET | `/receivings/{id}/items` | Get receiving items | Read |
|
|
|
|
## Schema Reference
|
|
|
|
### Common Fields
|
|
|
|
#### Person Fields (base for Customer, Supplier)
|
|
|
|
| Field | Type | Description |
|
|
|---------------|-----------|------------------------------|
|
|
| `first_name` | string | First name (required) |
|
|
| `last_name` | string | Last name (required) |
|
|
| `gender` | integer | Gender (0=male, 1=female) |
|
|
| `phone_number`| string | Phone number |
|
|
| `email` | string | Email address |
|
|
| `address_1` | string | Address line 1 |
|
|
| `address_2` | string | Address line 2 |
|
|
| `city` | string | City |
|
|
| `state` | string | State/Province |
|
|
| `zip` | string | Postal/ZIP code |
|
|
| `country` | string | Country |
|
|
| `comments` | string | Additional notes |
|
|
|
|
### Customer Fields
|
|
|
|
Extends Person fields with:
|
|
|
|
| Field | Type | Description |
|
|
|--------------------|-----------|------------------------------------|
|
|
| `person_id` | integer | Unique identifier (read-only) |
|
|
| `account_number` | string | Customer account number |
|
|
| `taxable` | integer | Taxable status (0/1) |
|
|
| `tax_id` | string | Tax identification number |
|
|
| `sales_tax_code_id`| integer | Sales tax code ID |
|
|
| `discount` | decimal | Discount percentage/amount |
|
|
| `discount_type` | integer | Discount type (0=percent, 1=fixed) |
|
|
| `company_name` | string | Company name |
|
|
| `package_id` | integer | Rewards package ID |
|
|
| `points` | integer | Rewards points balance |
|
|
| `consent` | integer | Consent status (0/1) |
|
|
|
|
### Supplier Fields
|
|
|
|
Extends Person fields with:
|
|
|
|
| Field | Type | Description |
|
|
|-----------------|-----------|-------------------------------------|
|
|
| `person_id` | integer | Unique identifier (read-only) |
|
|
| `company_name` | string | Company name |
|
|
| `account_number`| string | Supplier account number |
|
|
| `tax_id` | string | Tax identification number |
|
|
| `agency_name` | string | Agency name |
|
|
| `category` | integer | Category (0=goods, 1=cost) |
|
|
|
|
### Item Fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|----------------------|-----------|----------|--------------------------------------|
|
|
| `item_id` | integer | auto | Unique identifier (read-only) |
|
|
| `name` | string | yes | Item name |
|
|
| `category` | string | yes | Item category |
|
|
| `supplier_id` | integer | no | Supplier ID |
|
|
| `item_number` | string | no | Barcode/SKU |
|
|
| `description` | string | no | Item description |
|
|
| `cost_price` | decimal | no | Cost price |
|
|
| `unit_price` | decimal | yes | Selling price |
|
|
| `reorder_level` | decimal | no | Reorder threshold |
|
|
| `receiving_quantity` | decimal | no | Receiving quantity (default 1) |
|
|
| `allow_alt_description`| integer | no | Allow alt description (0/1) |
|
|
| `is_serialized` | integer | no | Has serial number (0/1) |
|
|
| `stock_type` | integer | no | Stock type (0=stocked, 1=non-stocked)|
|
|
| `item_type` | integer | no | Item type (0=standard, 1=kit, 2=temp)|
|
|
| `tax_category_id` | integer | no | Tax category ID |
|
|
| `qty_per_pack` | decimal | no | Quantity per pack |
|
|
| `pack_name` | string | no | Pack name |
|
|
| `hsn_code` | string | no | HSN code |
|
|
|
|
### Inventory Adjustment
|
|
|
|
| Field | Type | Required | Description |
|
|
|------------------|-----------|----------|--------------------------------------|
|
|
| `item_id` | integer | yes | Item ID to adjust |
|
|
| `trans_inventory`| decimal | yes | Quantity change (+ add, - remove) |
|
|
| `trans_location` | integer | no | Stock location ID |
|
|
| `trans_comment` | string | no | Reason for adjustment |
|
|
|
|
## OpenAPI Specification
|
|
|
|
The complete OpenAPI 3.1.0 specification is available at:
|
|
|
|
- **YAML format:** `/public/api/openapi.yaml`
|
|
|
|
This specification can be used with:
|
|
- [Swagger UI](https://swagger.io/tools/swagger-ui/) for interactive documentation
|
|
- [Swagger Codegen](https://swagger.io/tools/swagger-codegen/) to generate client SDKs
|
|
- [OpenAPI Generator](https://openapi-generator.tech/) for code generation
|
|
- API testing tools like Postman or Insomnia
|
|
|
|
## Implementation Notes
|
|
|
|
### Phase 1: Core Endpoints (Proposed)
|
|
|
|
1. Customers API (full CRUD)
|
|
2. Suppliers API (full CRUD)
|
|
3. Items API (full CRUD)
|
|
4. Inventory adjustments API (create only)
|
|
|
|
### Phase 2: Read-Only Endpoints (Proposed)
|
|
|
|
1. Sales API (read-only)
|
|
2. Receivings API (read-only)
|
|
|
|
### Phase 3: Extended Features (Future)
|
|
|
|
1. Batch operations for all endpoints
|
|
2. Search/filter capabilities
|
|
3. Authorization/permissions integration
|
|
4. Rate limiting
|
|
5. API key management interface
|
|
|
|
## Discussion Topics
|
|
|
|
The following aspects of the API design are open for discussion:
|
|
|
|
1. **Field naming conventions**: Currently following existing database column names. Should we use camelCase for JSON?
|
|
|
|
2. **Batch operations**: Current design separates batch-delete and batch-update. Should we consolidate?
|
|
|
|
3. **Date formats**: Using ISO 8601 (date-time). Is timezone handling needed?
|
|
|
|
4. **Error response structure**: Current format uses `{success, message}`. Should we include error codes?
|
|
|
|
5. **Relationship representations**: Should nested resources (e.g., sale items) always be included?
|
|
|
|
6. **Inventory adjustments**: Should we support setting absolute quantities vs. relative changes?
|
|
|
|
7. **Authorization integration**: How should API access integrate with existing employee permissions?
|
|
|
|
8. **Stock locations**: Multiple locations per item - do we need location-specific endpoints? |