Jump to [Database Documentation](#database-documentation) # LCC Backend API Documentation **API Version:** v1.0 **Last Updated:** March 16, 2025 ## Table of Contents 1. [Overview API](#overview-api) 2. [Authentication](#authentication) 3. [Request and Response Conventions](#request-and-response-conventions) 4. [System Configuration Endpoints](#system-configuration-endpoints) 5. [Transportation Rate Endpoints](#transportation-rate-endpoints) 6. [User Management Endpoints](#user-management-endpoints) 7. [Calculation Endpoints](#calculation-endpoints) 8. [Reporting Endpoints](#reporting-endpoints) 9. [Glossary](#glossary) ## Overview API This document provides a comprehensive description of the LCC Backend API endpoints, their functionality, parameters, and response formats. The API is structured around several core domains: System Configuration, Transportation Rates, User Management, and Calculation. ## Authentication ### Authentication Methods The LCC API uses two primary authentication methods: 1. **Pre-Shared Key (PSK)** \- Required for administrative endpoints such as User Management 2. **Session-based Authentication** \- Standard user authentication for most operations #### Pre-Shared Key Authentication For endpoints that require PSK authentication, include the following header in your request: ```javascript Authorization: PSK your_psk_here ``` Contact your system administrator to obtain a valid PSK. #### Session-based Authentication Most API endpoints require a valid session, which can be obtained by authenticating through the organization's identity provider. ## Request and Response Conventions ### Common Response Format All API responses follow a consistent structure. #### Success Response - HTTP Status Code: 200 OK - Response Body: Varies by endpoint (details provided in specific endpoint documentation) #### Error Response - HTTP Status Code: Varies (400, 401, 403, 404, 500, etc.) - Response Body: ```javascript { "error": { "code": "ERROR_CODE", "message": "User-friendly message", "details": { } } } ``` ### Common HTTP Status Codes | Status Code | Description | | :---- | :---- | | 200 | Success | | 400 | Bad Request (client error) | | 401 | Unauthorized (authentication required) | | 403 | Forbidden (insufficient permissions) | | 404 | Resource Not Found | | 409 | Conflict (e.g., resource already exists) | | 500 | Internal Server Error | ### Pagination Endpoints that return lists of resources support pagination using the following query parameters: - `limit`: Maximum number of items to return (default: 20, maximum: 100\) - `offset`: Number of items to skip for pagination (default: 0\) Example: `/api/materials?limit=20&offset=40` will return items 41-60. Pagination metadata is included in the response header: ```javascript X-Total-Count: 243 X-Page-Count: 13 X-Current-Page: 3 ``` ## System Configuration Endpoints {#system-configuration-endpoints} ### Bulk Operations #### Upload Template Data - **URL**: `/api/bulk/upload/{$type}` - **Method**: POST - **Description**: Uploads a filled-out template for batch processing - **Path Parameters**: - `$type`: The type of data being uploaded (valid values: `container_rate`, `country_matrix`, `material`, `packaging`, `node`) - **Response**: Returns a processing ID for status tracking #### Get Template - **URL**: `/api/bulk/templates/{$type}` - **Method**: GET - **Description**: Returns a template for the specified data type - **Path Parameters**: - `$type`: The template type (valid values: `container_rate`, `country_matrix`, `material`, `packaging`, `node`) #### Check Processing Status - **URL**: `/api/bulk/status/{$processing_id}` - **Method**: GET - **Description**: Returns the processing status of a bulk upload - **Path Parameters**: - `$processing_id`: The ID returned from a bulk upload request ### Materials Management #### List Materials - **URL**: `/api/materials/` - **Method**: GET - **Description**: Returns a list of all materials - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - **Response Format**: ```javascript [ { "id": "string", "part_number": "string", "name": "string" }, ... ] ``` #### Get Material Details - **URL**: `/api/materials/{id}` - **Method**: GET - **Description**: Returns detailed information about a specific material - **Path Parameters**: - `id`: Material ID - **Response Format**: ```javascript { "id": "string", "part_number": "string", "name": "string", "hs_code": "string", "handling_units": [ { "id": "string", "supplier_name": "string", "parent_id": "string", "length": "number", "width": "number", "height": "number", "dimension_unit": "string", "weight": "number", "weight_unit": "string", "content_unit_count": "number" }, ... ] } ``` #### Update Material - **URL**: `/api/materials/{id}` - **Method**: PUT - **Description**: Updates the material with the specified ID - **Path Parameters**: - `id`: Material ID #### Delete Material - **URL**: `/api/materials/{id}` - **Method**: DELETE - **Description**: Sets the material to deprecated (soft delete) - **Path Parameters**: - `id`: Material ID ### Packaging Management #### List Packagings - **URL**: `/api/packaging/` - **Method**: GET - **Description**: Returns a list of all packagings (handling units) - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - `supplier`: Filter by supplier ID - `material`: Filter by material ID - **Response Format**: ```javascript [ { "id": "string", "supplier_name": "string", "part_number": "string", "material_name": "string", "length": "number", "width": "number", "height": "number", "dimension_unit": "string", "weight": "number", "weight_unit": "string", "content_unit_count": "number" }, ... ] ``` #### Get Packaging Details - **URL**: `/api/packaging/{id}` - **Method**: GET - **Description**: Returns detailed information about a specific packaging - **Path Parameters**: - `id`: Packaging ID - **Response Format**: ```javascript { "id": "string", "supplier": { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string" }, "name": "string", "address": "string" }, "material": { "id": "string", "part_number": "string", "name": "string", "hs_code": "string" }, "handling_unit": { "length": "number", "width": "number", "height": "number", "dimension_unit": "string", "weight": "number", "weight_unit": "string", "content_unit_count": "number" }, "small_handling_unit": { "length": "number", "width": "number", "height": "number", "dimension_unit": "string", "weight": "number", "weight_unit": "string", "content_unit_count": "number" } } ``` #### Update Packaging - **URL**: `/api/packaging/{id}` - **Method**: PUT - **Description**: Updates the packaging with the specified ID - **Path Parameters**: - `id`: Packaging ID #### Delete Packaging - **URL**: `/api/packaging/{id}` - **Method**: DELETE - **Description**: Sets the packaging to deprecated (soft delete) - **Path Parameters**: - `id`: Packaging ID ### Country Management #### List Countries - **URL**: `/api/country/` - **Method**: GET - **Description**: Returns a list of all countries - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - **Response Format**: ```javascript [ { "id": "string", "iso_code": "string", "name": "string", "region_code": "string" }, ... ] ``` #### Get Country Details - **URL**: `/api/country/{id}` - **Method**: GET - **Description**: Returns detailed information about a specific country - **Path Parameters**: - `id`: Country ID - **Response Format**: ```javascript { "id": "string", "iso_code": "string", "name": "string", "region_code": "string", "properties": [ { "id": "string", "mapping_id": "string", "name": "string", "datatype": "string", "current_value": "any", "draft_value": "any", "is_required": "boolean" }, ... ] } ``` #### Update Country - **URL**: `/api/country/{id}` - **Method**: PUT - **Description**: Updates the country with the specified ID - **Path Parameters**: - `id`: Country ID #### Delete Country - **URL**: `/api/country/{id}` - **Method**: DELETE - **Description**: Sets the country to deprecated (soft delete) - **Path Parameters**: - `id`: Country ID ### System Properties Management #### List System Properties - **URL**: `/api/properties/system/` - **Method**: GET - **Description**: Returns property set including properties - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - **Response Format**: ```javascript [ { "id": "string", "mapping_id": "string", "name": "string", "data_type": "string", "current_value": "any", "draft_value": "any" }, ... ] ``` #### Get System Property Details - **URL**: `/api/properties/system/{id}` - **Method**: GET - **Description**: Returns detailed information about a specific system property - **Path Parameters**: - `id`: Property ID - **Response Format**: ```javascript { "id": "string", "mapping_id": "string", "name": "string", "data_type": "string", "current_value": "any", "draft_value": "any" } ``` #### Update System Property - **URL**: `/api/properties/system/{id}` - **Method**: PUT - **Description**: Updates the system property with the specified ID - **Path Parameters**: - `id`: Property ID #### List Property Types - **URL**: `/api/properties/types/{$system_part}/` - **Method**: GET - **Description**: Returns a list of all property types for the specified system part - **Path Parameters**: - `$system_part`: The system part to get properties for (valid values: `system`, `packaging`, `country`) - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - **Response Format**: ```javascript [ { "id": "string", "mapping_id": "string", "name": "string", "data_type": "string" }, ... ] ``` #### Create Property Type - **URL**: `/api/properties/types/{$system_part}/` - **Method**: PUT - **Description**: Creates a new system property type - **Path Parameters**: - `$system_part`: The system part to create a property for (valid values: `system`, `packaging`, `country`) #### Get Property Type Details - **URL**: `/api/properties/types/{$system_part}/{id}` - **Method**: GET - **Description**: Returns detailed information about a specific property type - **Path Parameters**: - `$system_part`: System part (valid values: `system`, `packaging`, `country`) - `id`: Property type ID - **Response Format**: ```javascript { "id": "string", "mapping_id": "string", "name": "string", "data_type": "string" } ``` #### Update Property Type - **URL**: `/api/properties/types/{$system_part}/{id}` - **Method**: PUT - **Description**: Updates the property type with the specified ID - **Path Parameters**: - `$system_part`: System part (valid values: `system`, `packaging`, `country`) - `id`: Property type ID #### Check Staged Property Changes - **URL**: `/api/properties/staged_changes/` - **Method**: GET - **Description**: Returns true if there are any unapproved "drafts" properties, false otherwise #### Approve Property Changes - **URL**: `/api/properties/staged_changes/` - **Method**: PUT - **Description**: Approves drafts and sets current "draft" properties to current valid properties ### Node Management #### List Nodes - **URL**: `/api/nodes/` - **Method**: GET - **Description**: Returns a list of all active nodes (with deprecated \= false) - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - `filter`: Search text to filter nodes - **Response Format**: ```javascript [ { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string", "name": "string" }, "address": "string", "location": { "longitude": "number", "latitude": "number" }, "types": ["sink", "source", "intermediate"] }, ... ] ``` #### Get Node Details - **URL**: `/api/nodes/{$id}` - **Method**: GET - **Description**: Returns detailed information about a specific node - **Path Parameters**: - `$id`: Node ID - **Response Format**: ```javascript { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string", "name": "string" }, "name": "string", "address": "string", "location": { "longitude": "number", "latitude": "number" }, "types": ["sink", "source", "intermediate"], "predecessors": { "1": { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string", "name": "string" }, "name": "string", "address": "string", "location": { "longitude": "number", "latitude": "number" } }, "2": { ... } }, "outbound_countries": [ { "id": "string", "iso_code": "string", "region_code": "string", "name": "string" }, ... ] } ``` #### Update Node - **URL**: `/api/nodes/{$id}` - **Method**: PUT - **Description**: Updates the node with the specified ID - **Path Parameters**: - `$id`: Node ID #### Delete Node - **URL**: `/api/nodes/{$id}` - **Method**: DELETE - **Description**: Sets the node with the specified ID to deprecated (soft delete) - **Path Parameters**: - `$id`: Node ID #### Search Nodes - **URL**: `/api/nodes/search` - **Method**: GET - **Description**: Returns a list of nodes matching the search conditions - **Query Parameters**: - `filter`: Search string - `limit`: Maximum number of items to return - `node_type`: Type filter (valid values: `source`, `sink`, `intermediate`) - `include_user_nodes`: Boolean to include user-specific nodes - **Response Format**: ```javascript [ { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string", "name": "string" }, "name": "string", "address": "string", "location": { "longitude": "number", "latitude": "number" }, "types": ["sink", "source", "intermediate"], "predecessors": { ... }, "outbound_countries": [ ... ], "is_user_node": "boolean" }, ... ] ``` ## Transportation Rate Endpoints {#transportation-rate-endpoints} ### Rate Validity Periods #### List Validity Periods - **URL**: `/api/rates/periods` - **Method**: GET - **Description**: Returns a list of validity periods for transportation rates - **Response Format**: ```javascript [ { "id": "string", "start_date": "date", "end_date": "date", "state": "string" }, ... ] ``` - **Note**: State can have the following values: `draft`, `valid`, `invalid`, `expired` #### Create Validity Period - **URL**: `/api/rates/periods` - **Method**: PUT - **Description**: Creates a new validity period (only possible if no validity period with state "draft" exists) #### Invalidate Validity Period - **URL**: `/api/rates/periods/{$id}` - **Method**: DELETE - **Description**: Invalidates the validity period with the specified ID (must be in state "valid" or "expired") - **Path Parameters**: - `$id`: Validity period ID ### Container Rates #### List Container Rates - **URL**: `/api/rates/container/` - **Method**: GET - **Description**: Returns a list of container rates associated with a specific validity period - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - `valid`: Validity period filter (values: validity\_period\_id, "current", "draft") - `validAt`: Timestamp to find rates valid at a specific time - **Response Format**: ```javascript [ { "id": "string", "origin": { "id": "string", "country": { ... }, "address": "string", "location": { ... }, "types": ["sink", "source", "intermediate"] }, "destination": { "id": "string", "country": { ... }, "address": "string", "location": { ... }, "types": ["sink", "source", "intermediate"] }, "type": "string", "rates": { "40": "number", "20": "number", "40_HC": "number" }, "lead_time": "number", "validity_period": { "id": "string", "start_date": "date", "end_date": "date", "state": "string" } }, ... ] ``` - **Note**: Type can have the following values: `rail`, `sea`, `post-run`, `road` #### Get Container Rate Details - **URL**: `/api/rates/container/{$id}` - **Method**: GET - **Description**: Returns detailed information about a specific container rate - **Path Parameters**: - `$id`: Container rate ID - **Response Format**: Same as list container rates #### Update Container Rate - **URL**: `/api/rates/container/{$id}` - **Method**: PUT - **Description**: Updates the container rate with the specified ID (only possible if the validity period is in state "draft") - **Path Parameters**: - `$id`: Container rate ID #### Delete Container Rate - **URL**: `/api/rates/container/{$id}` - **Method**: DELETE - **Description**: Deletes the container rate with the specified ID (only possible if the validity period is in state "draft") - **Path Parameters**: - `$id`: Container rate ID ### Country Matrix Rates #### List Country Matrix Rates - **URL**: `/api/rates/matrix/` - **Method**: GET - **Description**: Returns a list of country matrix rates associated with a specific validity period - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - `valid`: Validity period filter (values: validity\_period\_id, "current", "draft") - `validAt`: Timestamp to find rates valid at a specific time - **Response Format**: ```javascript [ { "id": "string", "origin": { "id": "string", "country": { ... }, "address": "string", "location": { ... }, "types": ["sink", "source", "intermediate"] }, "destination": { "id": "string", "country": { ... }, "address": "string", "location": { ... }, "types": ["sink", "source", "intermediate"] }, "rate": "number" }, ... ] ``` #### Get Country Matrix Rate Details - **URL**: `/api/rates/matrix/{$id}` - **Method**: GET - **Description**: Returns detailed information about a specific country matrix rate - **Path Parameters**: - `$id`: Country matrix rate ID - **Response Format**: Same as list country matrix rates #### Update Country Matrix Rate - **URL**: `/api/rates/matrix/{$id}` - **Method**: PUT - **Description**: Updates the country matrix rate with the specified ID (only possible if the validity period is in state "draft") - **Path Parameters**: - `$id`: Country matrix rate ID #### Delete Country Matrix Rate - **URL**: `/api/rates/matrix/{$id}` - **Method**: DELETE - **Description**: Deletes the country matrix rate with the specified ID (only possible if the validity period is in state "draft") - **Path Parameters**: - `$id`: Country matrix rate ID #### Check Staged Rate Changes - **URL**: `/api/rates/staged_changes/` - **Method**: GET - **Description**: Returns true if there are any unapproved "draft" rates, false otherwise #### Approve Rate Changes - **URL**: `/api/rates/staged_changes/` - **Method**: PUT - **Description**: Approves drafts and sets current "draft" validity period to current valid validity period ## User Management Endpoints ### User Operations {#user-operations} #### List Users - **URL**: `/api/users/` - **Method**: GET - **Description**: Lists all users - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - **Authorization**: PSK (Pre-Shared Key) - **Response Format**: ```javascript [ { "firstname": "string", "lastname": "string", "mail": "string", "workday_id": "string", "is_active": "boolean", "groups": ["string", ...] }, ... ] ``` #### Create or Update User - **URL**: `/api/users/` - **Method**: PUT - **Description**: Updates an existing user or creates a new one - **Authorization**: PSK (Pre-Shared Key) ### Group Operations #### List Groups - **URL**: `/api/groups/` - **Method**: GET - **Description**: Lists all user groups - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - **Authorization**: PSK (Pre-Shared Key) - **Response Format**: ```javascript [ { "group_name": "string", "group_description": "string" }, ... ] ``` #### Create or Update Group - **URL**: `/api/groups/` - **Method**: PUT - **Description**: Updates an existing group or creates a new one - **Authorization**: PSK (Pre-Shared Key) ## Calculation Endpoints {#calculation-endpoints} ### Calculation Operations #### View Calculation Premises - **URL**: `/api/calculation/view` - **Method**: GET - **Description**: Lists a preview of all premises for the current user (or another user with elevated rights) - **Query Parameters**: - `limit`: Maximum number of items to return (default: 20\) - `offset`: Number of items to skip (for pagination) - `filter`: Search string - `user`: User ID filter - `deleted`: Boolean to include deleted premises (default: false) - `archived`: Boolean to include archived premises (default: false) - `done`: Boolean to include completed premises (default: true) - **Response Format**: ```javascript [ { "id": "string", "material": { "id": "string", "part_number": "string", "name": "string" }, "supplier": { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string" }, "name": "string", "address": "string" }, "state": "string" }, ... ] ``` - **Note**: State can have the following values: `draft`, `completed`, `archived`, `deleted` #### Search for Materials and Suppliers - **URL**: `/api/calculation/search` - **Method**: GET - **Description**: Parses the given search string and returns the found materials and associated suppliers - **Query Parameters**: - `material`: Search string for materials - **Response Format**: ```javascript { "materials": [ { "id": "string", "part_number": "string", "name": "string" }, ... ], "supplier": [ { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string" }, "name": "string", "address": "string" }, ... ], "user_supplier": [ { "id": "string", "country": { "id": "string", "iso_code": "string", "region_code": "string" }, "name": "string", "address": "string" }, ... ] } ``` #### Create Calculation Premises - **URL**: `/api/calculation/create` - **Method**: GET - **Description**: Returns a list of premises based on the provided parameters - **Query Parameters**: - `material`: Array of material IDs - `supplier`: Array of supplier IDs - `user_supplier`: Array of user supplier IDs - `from_scratch`: Boolean to create empty premises - **Response Format**: Detailed premise data including routes and transit nodes #### Edit Calculation Premises - **URL**: `/api/calculation/edit` - **Method**: GET - **Description**: Returns a list of premises based on the provided premise IDs - **Query Parameters**: - `premiss_ids`: Array of premise IDs - **Response Format**: Detailed premise data including routes and transit nodes #### Save Calculation Premises - **URL**: `/api/calculation/edit` - **Method**: PUT - **Description**: Saves the provided premises - **Request Body**: Array of premise objects with detailed route information ## Reporting Endpoints ### Reporting Operations {#reporting-operations} #### Download Report - **URL**: `/api/reports/download` - **Method**: GET - **Description**: Returns an Excel-file based report - **Query Parameters**: - `material`: Material ID - `sources`: Array of source IDs #### Search Report Sources - **URL**: `/api/reports/search` - **Method**: GET - **Description**: Returns a list of source groups based on the given material ID - **Query Parameters**: - `material`: Material ID - **Response Format**: ```javascript [ ["source_id", ...],c ... ] ``` #### View Report - **URL**: `/api/reports/view` - **Method**: GET - **Description**: Returns a detailed cost and risk report - **Query Parameters**: - `material`: Material ID - `sources`: Array of source IDs - **Response Format**: ```javascript [ { "cost": { "material_cost": { "total": "number", "percentage": "number" }, "fca_fees": { "total": "number", "percentage": "number" }, "pre_run_cost": { "total": "number", "percentage": "number" }, "main_run_cost": { "total": "number", "percentage": "number" }, "post_run_cost": { "total": "number", "percentage": "number" }, "repacking_cost": { "total": "number", "percentage": "number" }, "handling_cost": { "total": "number", "percentage": "number" }, "storage_cost": { "total": "number", "percentage": "number" }, "captial_cost": { "total": "number", "percentage": "number" }, "disposal_cost": { "total": "number", "percentage": "number" }, "total_cost": { "total": "number", "percentage": "number" } }, "risk": { "air_freight_cost": { "total": "number", "percentage": "number" }, "best_case_cost": { "total": "number", "percentage": "number" }, "worst_case_cost": { "total": "number", "percentage": "number" } }, "premisses": { "quantities": [ { "destination": "string", "quantity": "number", "route": [ { "name": "string", "type": "string", "cost": { "total": "number", "percentage": "number" } }, "..." ] } ], "hs_code": "string", "custom_rate": "number", "container": { "type": "string", "rate": "number", "unit_count": "number", "weight_exceeded": "boolean", "utilization": "number", "mixed": "boolean" }, "packaging": { "width": "number", "height": "number", "length": "number", "weight": "number", "dimension_unit": "string", "weight_unit": "string", "unit_count": "number", "layers": "number" }, "qouta_share": { "oversea_share": "number", "air_freight_share": "number", "transport_time": "number", "safety_stock": "number" } } }, "..." ] ``` ## Glossary {#glossary} | Term | Definition | | :---- | :---- | | **API** | Application Programming Interface. A set of rules that allows programs to talk to each other. | | **Calculation Premises** | The foundational data and assumptions used for logistics cost calculations. | | **Container Rate** | Pricing for transportation of goods via standard shipping containers (20ft, 40ft, 40ft High Cube). | | **Country Matrix** | A grid representing transportation rates between country pairs. | | **Draft** | A working state for rates, properties, or other data that is not yet approved or in production. | | **Handling Unit** | A physical package or container for materials (e.g., pallet, box). | | **HS Code** | Harmonized System code. An international nomenclature for classifying traded products. | | **LCC** | Logistics Cost Calculator, the primary system this API supports. | | **Lead Time** | The time taken from ordering to delivery of materials. | | **Material** | A product or component that is transported or managed in the system. | | **Node** | A geographic location in the logistics network (could be source, sink, or intermediate). | | **Packaging** | The physical container or wrapping for materials during transportation. | | **Pre-Shared Key (PSK)** | A secret key shared between parties for authentication purposes. | | **Property Type** | A definition of a characteristic that can be assigned to system entities. | | **Rate** | The cost associated with transporting goods between locations. | | **Sink** | A destination node in the logistics network (typically a manufacturing plant). | | **Source** | An origin node in the logistics network (typically a supplier). | | **System Property** | A configuration setting that affects the behavior of the LCC system. | | **Transit Node** | An intermediate point in a transportation route. | | **User Supplier** | A supplier that is specific to a particular user rather than system-wide. | | **Validity Period** | A timeframe during which rates or other data are considered active and applicable. | # Database Documentation ## Overview Database This document provides a comprehensive description of the LCC Backend Database structure. It handles property management, geographical data, user management, logistics nodes, transportation rates, packaging, materials, and calculation workflows for optimizing logistics operations. ## Table Categories The database is organized into several functional areas: 1. **Property Management** - Versioned configuration properties 2. **Geographic Data** - Countries and regions 3. **User Management** - Users, groups, and permissions 4. **Logistics Nodes** - Physical locations in the supply chain 5. **Transportation** - Distance matrices and rates 6. **Materials & Packaging** - Product and packaging information 7. **Premiss & Routes** - Supply chain scenarios and route planning 8. **Calculation** - Cost calculation jobs and results ## Detailed Table Descriptions ### Property Management #### `property_set` Manages versioned sets of properties with temporal validity. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `start_date` | TIMESTAMP | When this property set becomes valid | | `end_date` | TIMESTAMP | When this property set expires (NULL = no expiration) | | `state` | CHAR(8) | Status of property set: DRAFT, VALID, INVALID, EXPIRED | #### `system_property_type` Defines system-wide configuration property types. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `name` | VARCHAR(255) | Property type name | | `external_mapping_id` | VARCHAR(16) | External system identifier | | `data_type` | VARCHAR(16) | Data type: INT, PERCENTAGE, BOOLEAN, CURRENCY, ENUMERATION, TEXT | | `validation_rule` | VARCHAR(64) | Optional validation rules | #### `system_property` Stores system-wide configuration property values. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `property_set_id` | INT | References property_set | | `system_property_type_id` | INT | References system_property_type | | `property_value` | VARCHAR(500) | The value of the property | ### Geographic Data #### `country` Master data table for country information and regional classification. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `iso_code` | CHAR(2) | ISO 3166-1 alpha-2 country code | | `region_code` | CHAR(5) | Geographic region: EMEA/LATAM/APAC/NAM | | `name` | VARCHAR(128) | Country name | | `is_deprecated` | BOOLEAN | Whether the country record is deprecated | #### `country_property_type` Defines property types specific to countries. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `name` | VARCHAR(255) | Property type name | | `external_mapping_id` | VARCHAR(16) | External system identifier | | `data_type` | VARCHAR(16) | Data type: INT, PERCENTAGE, BOOLEAN, CURRENCY, ENUMERATION, TEXT | | `validation_rule` | VARCHAR(64) | Optional validation rules | | `is_required` | BOOLEAN | Whether the property is required | #### `country_property` Stores country-specific property values with versioning support. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `country_id` | INT | References country | | `country_property_type_id` | INT | References country_property_type | | `property_set_id` | INT | References property_set | | `property_value` | VARCHAR(500) | The value of the property | ### User Management #### `sys_user` Stores basic information about system users. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `workday_id` | CHAR(32) | External HR system identifier | | `email` | VARCHAR(254) | User email | | `firstname` | VARCHAR(100) | User first name | | `lastname` | VARCHAR(100) | User last name | | `is_active` | BOOLEAN | Whether the user is active | #### `sys_group` Defines user groups for access management. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `group_name` | VARCHAR(64) | Group name | | `group_description` | VARCHAR(128) | Group description | #### `sys_user_group_mapping` Links users with their associated groups. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `user_id` | INT | References sys_user | | `group_id` | INT | References sys_group | #### `sys_user_node` Contains user-generated logistic nodes. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `user_id` | INT | References sys_user | | `country_id` | INT | References country | | `name` | VARCHAR(254) | Node name | | `address` | VARCHAR(500) | Physical address | | `geo_lat` | DECIMAL(7,4) | Latitude (-90 to 90) | | `geo_lng` | DECIMAL(7,4) | Longitude (-180 to 180) | | `is_deprecated` | BOOLEAN | Whether the node is deprecated | ### Logistics Nodes #### `node` Represents physical locations in the supply chain network. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `country_id` | INT | References country | | `name` | VARCHAR(255) | Node name | | `address` | VARCHAR(500) | Physical address | | `external_mapping_id` | VARCHAR(32) | External system identifier | | `predecessor_required` | BOOLEAN | Whether this node requires a predecessor | | `is_sink` | BOOLEAN | Whether this node is a destination/consumption point | | `is_source` | BOOLEAN | Whether this node is a source/production point | | `is_intermediate` | BOOLEAN | Whether this node is a transfer point | | `geo_lat` | DECIMAL(7,4) | Latitude (-90 to 90) | | `geo_lng` | DECIMAL(7,4) | Longitude (-180 to 180) | | `updated_at` | TIMESTAMP | Last update timestamp | | `is_deprecated` | BOOLEAN | Whether the node is deprecated | #### `node_predecessor` Defines predecessor relationships between nodes. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `node_id` | INT | References node | | `predecessor_node_id` | INT | References node as a predecessor | | `sequence_number` | INT | Position in the sequence (>0) | #### `outbound_country_mapping` Maps nodes to countries they can serve. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `node_id` | INT | References node | | `country_id` | INT | References country | #### `distance_matrix` Stores distance information between nodes. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `from_node_id` | INT | References source node | | `to_node_id` | INT | References destination node | | `from_geo_lat` | DECIMAL(7,4) | Source latitude | | `from_geo_lng` | DECIMAL(7,4) | Source longitude | | `to_geo_lat` | DECIMAL(7,4) | Destination latitude | | `to_geo_lng` | DECIMAL(7,4) | Destination longitude | | `distance` | DECIMAL(15,2) | Travel distance in meters | | `updated_at` | TIMESTAMP | Last update timestamp | | `state` | CHAR(10) | Status: VALID, STALE | ### Transportation Rates #### `validity_period` Defines time periods for rate validity. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `start_date` | TIMESTAMP | When the period starts | | `end_date` | TIMESTAMP | When the period ends (NULL = no end) | | `state` | CHAR(8) | Status: DRAFT, VALID, INVALID, EXPIRED | #### `container_rate` Stores rates for container transportation between nodes. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `from_node_id` | INT | References source node | | `to_node_id` | INT | References destination node | | `container_rate_type` | CHAR(8) | Type: RAIL, SEA, POST-RUN, ROAD | | `rate_20` | DECIMAL(15,2) | Rate for 20ft container in EUR | | `rate_40` | DECIMAL(15,2) | Rate for 40ft container in EUR | | `rate_40_hc` | DECIMAL(15,2) | Rate for 40ft HQ container in EUR | | `lead_time` | INT UNSIGNED | Lead time in days | | `validity_period_id` | INT | References validity_period | #### `country_matrix_rate` Stores rates for full truck load based on country pairs. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `from_country_id` | INT | References source country | | `to_country_id` | INT | References destination country | | `rate` | DECIMAL(15,2) | Rate for full truck load per kilometer in EUR | | `validity_period_id` | INT | References validity_period | ### Materials & Packaging #### `material` Stores information about materials. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `part_number` | CHAR(12) | Material part number | | `normalized_part_number` | CHAR(12) | Standardized part number (unique) | | `hs_code` | CHAR(8) | Harmonized System code for customs | | `name` | VARCHAR(500) | Material name | | `is_deprecated` | BOOLEAN | Whether the material is deprecated | #### `packaging` Defines packaging specifications. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `supplier_node_id` | INT | References node (supplier) | | `material_id` | INT | References material | | `parent_id` | INT | References parent packaging (hierarchical) | | `type` | CHAR(3) | Type: SHU (small handling unit), HU (handling unit) | | `length` | INT UNSIGNED | Length in mm | | `width` | INT UNSIGNED | Width in mm | | `height` | INT UNSIGNED | Height in mm | | `displayed_dimension_unit` | CHAR(2) | Display unit: MM, CM, M | | `weight` | INT UNSIGNED | Weight in g | | `displayed_weight_unit` | CHAR(2) | Display unit: G, KG | | `content_unit_count` | INT UNSIGNED | Number of units contained | | `is_deprecated` | BOOLEAN | Whether the packaging is deprecated | #### `packaging_property_type` Defines property types for packaging. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `name` | VARCHAR(255) | Property type name | | `data_type` | VARCHAR(16) | Data type | | `validation_rule` | VARCHAR(64) | Optional validation rules | | `is_required` | BOOLEAN | Whether the property is required | #### `packaging_property` Stores packaging property values. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `packaging_property_type_id` | INT | References packaging_property_type | | `packaging_id` | INT | References packaging | | `property_value` | VARCHAR(500) | The value of the property | ### Premiss & Routes #### `premiss` Core table for logistics scenario planning. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `material_id` | INT | References material | | `supplier_node_id` | INT | References node (system supplier) | | `user_supplier_node_id` | INT | References sys_user_node (user's supplier) | | `packaging_id` | INT | References packaging | | `user_id` | INT | References sys_user (creator) | | `createdAt` | TIMESTAMP | Creation timestamp | | `updatedAt` | TIMESTAMP | Last update timestamp | | `material_cost` | DECIMAL(15,2) | Material cost in EUR (MEK_A) | | `is_fca_enabled` | BOOLEAN | Free Carrier shipping terms enabled | | `oversea_share` | DECIMAL(7,4) | Percentage of overseas transport | | `hs_code` | CHAR(8) | Harmonized System code for customs | | `custom_rate` | DECIMAL(7,4) | Custom duty rate | | `state` | CHAR(10) | Status: DRAFT, COMPLETED, ARCHIVED, DELETED | | `individual_hu_length` | INT UNSIGNED | Handling unit length in mm | | `individual_hu_height` | INT UNSIGNED | Handling unit height in mm | | `individual_hu_width` | INT UNSIGNED | Handling unit width in mm | | `individual_hu_weight` | INT UNSIGNED | Handling unit weight in g | | `hu_displayed_dimension_unit` | CHAR(2) | Display unit for dimensions | | `hu_displayed_weight_unit` | CHAR(2) | Display unit for weight | | `hu_unit_count` | INT UNSIGNED | Number of units per handling unit | | `hu_stackable` | BOOLEAN | Whether the unit is stackable | | `hu_mixable` | BOOLEAN | Whether the unit can be mixed with others | #### `premiss_sink` Links premiss to destination nodes with volume information. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `premiss_id` | INT | References premiss | | `annual_amount` | INT UNSIGNED | Annual amount in pieces | | `sink_node_id` | INT | References node (destination) | #### `premiss_route` Defines possible routes for a premiss_sink. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `premiss_sink_id` | INT | References premiss_sink | | `is_fastest` | BOOLEAN | Whether this is the fastest route | | `is_cheapest` | BOOLEAN | Whether this is the cheapest route | | `is_selected` | BOOLEAN | Whether this route is selected/preferred | #### `premiss_route_node` Defines nodes in a route. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `premiss_route_id` | INT | References premiss_route | | `node_id` | INT | References node (system node) | | `user_node_id` | INT | References sys_user_node (user's node) | | `name` | VARCHAR(255) | Node name | | `address` | VARCHAR(500) | Node address | | `is_sink` | BOOLEAN | Whether this is a destination node | | `is_intermediate` | BOOLEAN | Whether this is a transfer node | | `is_source` | BOOLEAN | Whether this is a source node | | `geo_lat` | DECIMAL(7,4) | Latitude | | `geo_lng` | DECIMAL(7,4) | Longitude | | `is_outdated` | BOOLEAN | Whether the node data is outdated | #### `premiss_route_section` Defines transportation sections between route nodes. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `premiss_route_id` | INT | References premiss_route | | `from_route_node_id` | INT | References premiss_route_node (source) | | `to_route_node_id` | INT | References premiss_route_node (destination) | | `list_position` | INT | Position in the route sequence | | `transport_type` | CHAR(16) | Type: RAIL, SEA, ROAD, POST-RUN, MATRIX, D2D | | `rate_d2d` | DECIMAL(15,2) | Door-to-door rate in EUR | | `is_pre_run` | BOOLEAN | Whether this is a pre-run section | | `is_main_run` | BOOLEAN | Whether this is a main-run section | | `is_post_run` | BOOLEAN | Whether this is a post-run section | | `is_outdated` | BOOLEAN | Whether the section data is outdated | ### Calculation System #### `calculation_job` Manages calculation processes. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `premiss_id` | INT | References premiss | | `calculation_date` | TIMESTAMP | When the calculation was performed | | `validity_period_id` | INT | References validity_period | | `property_set_id` | INT | References property_set | | `job_state` | CHAR(10) | Status: CREATED, SCHEDULED, VALID, INVALID, EXCEPTION | | `user_id` | INT | References sys_user (creator) | #### `calculation_job_sink_result` Stores calculation results per sink. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_id` | INT | References calculation_job | | `premiss_sink_id` | INT | References premiss_sink | | `safety_stock` | INT UNSIGNED | Safety stock in pieces | | `shipping_frequency` | INT UNSIGNED | Annual shipping frequency | | `total_cost` | DECIMAL(15,2) | Total cost in EUR (MEK_B) | #### `calculation_job_transportation_result` Stores transportation calculation results. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_sink_result_id` | INT | References calculation_job_sink_result | | `transportation_type` | CHAR(8) | Type: 20, 40, 40HC, TRUCK | | `hu_per_layer` | INT UNSIGNED | Handling units per layer | | `layer_structure` | JSON | Structure of a single layer | | `layer_count` | INT UNSIGNED | Number of layers per container/truck | | `transport_weight_exceeded` | BOOLEAN | Weight vs. volume limitation | | `transports_per_year` | DECIMAL(15,2) | Number of transports per year | | `annual_cost` | DECIMAL(15,2) | Annual transportation costs in EUR | #### `calculation_job_route_section_result` Detailed calculation results for route sections. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `premiss_route_section_id` | INT | References premiss_route_section | | `calculation_job_transportation_result_id` | INT | References calculation_job_transportation_result | | `used_rule` | CHAR(8) | Calculation rule: CONTAINER, MATRIX | | `is_unmixed_price` | BOOLEAN | Whether an unmixed pricing was used | | `is_cbm_price` | BOOLEAN | Whether cubic meter pricing was used | | `is_weight_price` | BOOLEAN | Whether weight-based pricing was used | | `is_stacked` | BOOLEAN | Whether stacking was considered | | `is_pre_run` | BOOLEAN | Whether this is a pre-run calculation | | `is_main_run` | BOOLEAN | Whether this is a main-run calculation | | `is_post_run` | BOOLEAN | Whether this is a post-run calculation | | `rate` | DECIMAL(15,2) | Applied rate in EUR | | `distance` | DECIMAL(15,2) | Section distance in meters | | `cbm_price` | DECIMAL(15,2) | Price per cubic meter | | `weight_price` | DECIMAL(15,2) | Price per kilogram | | `annual_cost` | DECIMAL(15,2) | Annual costs for this section | | `transit_time` | INT UNSIGNED | Transit time | #### `calculation_job_airfreight_result` Stores air freight calculation results. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_sink_result_id` | INT | References calculation_job_sink_result | | `air_freight_share_max` | DECIMAL(7,4) | Maximum air freight share | | `air_freight_share` | DECIMAL(7,4) | Actual air freight share | | `air_freight_volumetric_weight` | DECIMAL(15,2) | Volumetric weight | | `air_freight_weight` | DECIMAL(15,2) | Actual weight | | `annual_cost` | DECIMAL(15,2) | Annual air freight costs | #### `calculation_job_custom_result` Stores customs duty calculation results. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_sink_result_id` | INT | References calculation_job_sink_result | | `custom_value` | DECIMAL(15,2) | Customs value | | `custom_duties` | DECIMAL(15,2) | Customs duties | | `custom_rate` | DECIMAL(7,4) | Applied duty rate | | `annual_cost` | DECIMAL(15,2) | Annual customs costs | #### `calculation_job_inventory_result` Stores inventory calculation results. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_sink_result_id` | INT | References calculation_job_sink_result | | `operational_stock` | DECIMAL(15,2) | Operational stock in pieces | | `safety_stock` | DECIMAL(15,2) | Safety stock in pieces | | `stocked_inventory` | DECIMAL(15,2) | Total stocked inventory | | `in_transport_stock` | DECIMAL(15,2) | Stock in transport | | `stock_before_payment` | DECIMAL(15,2) | Stock before payment | | `annual_capital_cost` | DECIMAL(15,2) | Annual capital costs | | `annual_storage_cost` | DECIMAL(15,2) | Annual storage costs | #### `calculation_job_handling_result` Stores handling cost calculation results. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_sink_result_id` | INT | References calculation_job_sink_result | | `is_small_unit` | BOOLEAN | Whether this is a small unit (< 0.08 cbm) | | `annual_repacking_cost` | DECIMAL(15,2) | Annual repacking costs | | `annual_handling_cost` | DECIMAL(15,2) | Annual handling costs | | `annual_disposal_cost` | DECIMAL(15,2) | Annual disposal costs | #### `calculation_job_risk_result` Stores risk assessment calculation results. | Column | Type | Description | |--------|------|-------------| | `id` | INT | Primary key | | `calculation_job_sink_result_id` | INT | References calculation_job_sink_result | | `annual_risk_cost` | DECIMAL(15,2) | Annual risk costs (worst case) | | `annual_chance_cost` | DECIMAL(15,2) | Annual opportunity costs (best case) | ## Entity Relationship Diagram The database has several key relationship patterns: 1. The `property_set` system provides versioned configuration for both system-wide and country-specific properties 2. The `node` system forms the backbone of the logistics network 3. The `premiss` system ties together materials, packaging, suppliers, and destinations 4. The `calculation_job` system captures results of cost calculations with various components ## Common Data Types and Conventions - Monetary values are stored as DECIMAL(15,2) in EUR - Geographical coordinates are stored as DECIMAL(7,4) - Dimensions are stored in mm (millimeters) - Weights are stored in g (grams) - Most tables include an `is_deprecated` flag for soft-deletion - State/status fields use CHECK constraints to limit valid values