Download OpenAPI specification:
Enterprise REST API for Smart Supply Pro inventory and supplier management system.
All endpoints (except health checks) require OAuth2 authentication via Google. The API uses JWT tokens managed through secure HTTP-only cookies.
Returns the current authenticated user's profile information including email, full name, role, and profile picture URL from OAuth2 provider.
User data is loaded from the database based on OAuth2 email claim.
{- "email": "admin@example.com",
- "fullName": "Admin User",
- "role": "ADMIN",
}Returns the list of granted authorities (roles and permissions) for the authenticated user. Used for frontend authorization checks.
Authorities are returned as sorted strings (e.g., ROLE_USER, ROLE_ADMIN).
[- "ROLE_USER",
- "ROLE_ADMIN"
]Programmatic logout endpoint for API clients (SPAs, mobile apps).
What it does:
Cookie settings:
Note: Browser clients should prefer the standard POST /logout endpoint.
{- "message": "No authentication provided",
- "status": 401,
- "timestamp": "2025-11-18T10:30:00Z",
- "path": "/api/me"
}Retrieves all inventory items in the system (non-paginated). Includes supplier names and calculated total values.
Security: Requires authentication OR demo mode enabled. If APP_DEMO_READONLY=true, unauthenticated access is allowed.
Note: For large datasets, consider using the search endpoint with pagination.
[- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}
]Creates a new inventory item. Requires ADMIN role.
Authorization:
Validation:
Response:
| name required | string non-empty Display name of the inventory item |
| quantity required | integer <int32> >= 0 Initial stock quantity |
| price required | number <double> >= 0.01 Price per unit |
| supplierId required | string Associated supplier identifier |
| minimumQuantity | integer <int32> >= 0 Minimum stock threshold for low-stock alerts |
{- "name": "Premium Widget",
- "quantity": 100,
- "price": 29.99,
- "supplierId": "supplier-123",
- "minimumQuantity": 50
}{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Retrieves a single inventory item by its unique identifier. Includes supplier name and calculated total value.
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Unique inventory item identifier |
{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Updates an existing inventory item completely (full replacement).
Authorization:
ID Handling:
Validation:
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Inventory item identifier |
| name required | string non-empty Display name of the inventory item |
| quantity required | integer <int32> >= 0 Current stock quantity |
| price required | number <double> >= 0.01 Price per unit |
| supplierId required | string Associated supplier identifier |
| minimumQuantity | integer <int32> >= 0 Minimum stock threshold |
{- "name": "Premium Widget (Updated)",
- "quantity": 120,
- "price": 34.99,
- "supplierId": "supplier-123",
- "minimumQuantity": 60
}{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Deletes an inventory item permanently. Requires ADMIN role.
Authorization:
Business Rules:
Validation Flow:
Error Response Examples:
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Inventory item identifier |
| reason required | string Enum: "SCRAPPED" "DESTROYED" "DAMAGED" "EXPIRED" "LOST" "RETURNED_TO_SUPPLIER" Example: reason=SCRAPPED Business reason for deletion (audit trail). Must be one of deletion-valid reasons. |
{- "error": "Invalid reason for deletion",
- "status": 400,
- "timestamp": "2025-11-20T20:00:00Z"
}Searches for inventory items by name with pagination and sorting support. Name search is case-insensitive and matches substrings.
Security: Requires authentication OR demo mode enabled. If APP_DEMO_READONLY=true, unauthenticated access is allowed.
| name required | string Example: name=widget Case-insensitive name substring to search for |
| page | integer <int32> >= 0 Default: 0 Page number (0-indexed) |
| size | integer <int32> [ 1 .. 100 ] Default: 20 Example: size=20 Number of items per page |
| sort | string Example: sort=price,desc Sort criteria in format: Examples:
|
{- "content": [
- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}
], - "page": {
- "number": 0,
- "size": 20,
- "totalElements": 1,
- "totalPages": 1
}
}Adjusts the quantity of an inventory item by a delta amount.
Authorization:
Delta Logic:
Audit Trail:
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Inventory item identifier |
| delta required | integer <int32> Example: delta=-25 Quantity change (positive to add, negative to remove) |
| reason required | string Enum: "SALE" "RETURN" "DAMAGED" "EXPIRED" "RESTOCK" "MANUAL_ADJUSTMENT" "INVENTORY_COUNT" "INITIAL_STOCK" Example: reason=SALE Business reason for quantity adjustment |
{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Updates the unit price of an inventory item. Total value is automatically recalculated (quantity × new price).
Authorization:
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Inventory item identifier |
| price required | number <double> >= 0.01 Example: price=34.99 New unit price (must be positive) |
{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Premium Widget",
- "quantity": 150,
- "price": 29.99,
- "totalValue": 4498.5,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "minimumQuantity": 50,
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Retrieves a list of all suppliers in the system. Supports demo readonly access.
[- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Acme Corp",
- "contactName": "John Smith",
- "phone": "+1-555-0100",
- "email": "contact@acmecorp.com",
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}
]Creates a new supplier. Requires ADMIN role.
Validation:
Response:
| name required | string non-empty Supplier display name |
| contactName | string or null Optional contact person name |
| phone | string or null Optional phone number |
string or null <email> Optional email address | |
| createdBy required | string User creating this supplier (for audit trail) |
{- "name": "New Supplier Corp",
- "contactName": "Alice Johnson",
- "phone": "+1-555-0200",
- "email": "contact@newsupplier.com",
- "createdBy": "admin@example.com"
}{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Acme Corp",
- "contactName": "John Smith",
- "phone": "+1-555-0100",
- "email": "contact@acmecorp.com",
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Retrieves a single supplier by its unique identifier.
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Unique supplier identifier |
{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Acme Corp",
- "contactName": "John Smith",
- "phone": "+1-555-0100",
- "email": "contact@acmecorp.com",
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Updates an existing supplier completely (full replacement). Requires ADMIN role.
ID Handling:
Validation:
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Supplier identifier |
| name required | string non-empty Supplier display name |
| contactName | string or null Optional contact person name |
| phone | string or null Optional phone number |
string or null <email> Optional email address |
{- "name": "Updated Supplier Corp",
- "contactName": "Bob Wilson",
- "phone": "+1-555-0201",
- "email": "newemail@supplier.com"
}{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Acme Corp",
- "contactName": "John Smith",
- "phone": "+1-555-0100",
- "email": "contact@acmecorp.com",
- "createdBy": "admin@example.com",
- "createdAt": "2025-11-01T10:00:00Z"
}Deletes a supplier permanently. Requires ADMIN role.
Referential Integrity:
| id required | string Example: 550e8400-e29b-41d4-a716-446655440000 Supplier identifier |
{- "message": "No authentication provided",
- "status": 401,
- "timestamp": "2025-11-18T10:30:00Z",
- "path": "/api/me"
}Searches for suppliers by partial or full name match. Case-insensitive substring search.
| name required | string Example: name=Acme Case-insensitive supplier name substring |
[- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "name": "Acme Corp",
- "contactName": "John Smith",
- "phone": "+1-555-0100",
- "email": "contact@acmecorp.com",
- "createdBy": "admin@example.com",
- "createdAt": "2025-01-15T10:00:00Z"
}, - {
- "id": "660e8400-e29b-41d4-a716-446655440001",
- "name": "Acme International",
- "contactName": "Jane Doe",
- "phone": "+1-555-0101",
- "email": "contact@acme-intl.com",
- "createdBy": "admin@example.com",
- "createdAt": "2025-02-01T14:30:00Z"
}
]Retrieves all stock history entries without pagination. Use for comprehensive audit trail export or analysis.
[- {
- "id": "hist-001",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "change": -25,
- "reason": "SALE",
- "createdBy": "user@example.com",
- "timestamp": "2025-11-10T14:30:00Z",
- "priceAtChange": 29.99
}
]Retrieves all stock movement history for a specific inventory item. Shows the complete change timeline for an item with reasons and actors.
| itemId required | string Example: 550e8400-e29b-41d4-a716-446655440000 Inventory item identifier |
[- {
- "id": "hist-001",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "change": 100,
- "reason": "INITIAL_STOCK",
- "createdBy": "admin@example.com",
- "timestamp": "2025-01-15T10:00:00Z",
- "priceAtChange": 29.99
}, - {
- "id": "hist-002",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "change": -25,
- "reason": "SALE",
- "createdBy": "user@example.com",
- "timestamp": "2025-11-10T14:30:00Z",
- "priceAtChange": 29.99
}
]Filters stock history entries by the reason for change. Useful for tracking all sales, returns, damages, etc.
| reason required | string Enum: "SALE" "RETURN" "DAMAGED" "EXPIRED" "RESTOCK" "MANUAL_ADJUSTMENT" "INVENTORY_COUNT" "INITIAL_STOCK" Example: SALE Stock change reason |
[- {
- "id": "hist-002",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "change": -25,
- "reason": "SALE",
- "createdBy": "user@example.com",
- "timestamp": "2025-11-10T14:30:00Z",
- "priceAtChange": 29.99
}, - {
- "id": "hist-003",
- "itemId": "660e8400-e29b-41d4-a716-446655440001",
- "change": -10,
- "reason": "SALE",
- "createdBy": "user@example.com",
- "timestamp": "2025-11-12T16:45:00Z",
- "priceAtChange": 49.99
}
]Advanced paginated search with multiple filter criteria and date range bounds.
Filters (all optional):
Validation:
Default sorting: timestamp DESC (newest first)
| startDate | string <date-time> Example: startDate=2025-11-01T00:00:00Z Inclusive start timestamp (ISO-8601) |
| endDate | string <date-time> Example: endDate=2025-11-30T23:59:59Z Inclusive end timestamp (ISO-8601) |
| itemName | string Example: itemName=Widget Partial inventory item name to filter by |
| supplierId | string Example: supplierId=supplier-123 Supplier identifier to filter by |
| page | integer <int32> >= 0 Default: 0 Page number (0-indexed) |
| size | integer <int32> [ 1 .. 200 ] Default: 50 Example: size=50 Number of items per page (max 200, default 50) |
| sort | string Example: sort=timestamp,desc Sort criteria in format: Examples:
|
{- "content": [
- {
- "id": "hist-001",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "change": -25,
- "reason": "SALE",
- "createdBy": "user@example.com",
- "timestamp": "2025-11-15T14:30:00Z",
- "priceAtChange": 29.99
}, - {
- "id": "hist-002",
- "itemId": "660e8400-e29b-41d4-a716-446655440001",
- "change": -10,
- "reason": "SALE",
- "createdBy": "user@example.com",
- "timestamp": "2025-11-12T16:45:00Z",
- "priceAtChange": 49.99
}
], - "page": {
- "number": 0,
- "size": 50,
- "totalElements": 243,
- "totalPages": 5
}
}Gets time series of total stock value between dates. Shows inventory value trends with optional supplier filtering.
| start required | string <date> Example: start=2025-11-01 Inclusive start date (ISO yyyy-MM-dd) |
| end required | string <date> Example: end=2025-11-30 Inclusive end date (ISO yyyy-MM-dd) |
| supplierId | string Example: supplierId=supplier-123 Optional supplier filter |
[- {
- "date": "2025-11-15",
- "totalValue": 45000
}
]Gets current total stock quantity per supplier for charts and distribution analysis.
[- {
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "totalQuantity": 1500,
- "totalValue": 45000
}, - {
- "supplierId": "supplier-456",
- "supplierName": "Global Imports",
- "totalQuantity": 2300,
- "totalValue": 69000
}
]Gets item update frequency for a specific supplier. Shows which items are updated most frequently, indicating high activity.
| supplierId required | string Example: supplierId=supplier-123 Supplier identifier |
[- {
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "itemName": "Premium Widget",
- "updateCount": 45
}
]Gets items below minimum stock threshold for a supplier. Lists items requiring reorder with current and recommended levels.
| supplierId required | string Example: supplierId=supplier-123 Supplier identifier |
[- {
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "itemName": "Premium Widget",
- "currentQuantity": 15,
- "minimumQuantity": 50,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp"
}
]Gets monthly stock movement (inbound/outbound) within a date range. Shows inventory flow trends with optional supplier filtering.
| start required | string <date> Example: start=2025-09-01 Inclusive start date (ISO yyyy-MM-dd) |
| end required | string <date> Example: end=2025-11-30 Inclusive end date (ISO yyyy-MM-dd) |
| supplierId | string Example: supplierId=supplier-123 Optional supplier filter |
[- {
- "year": 2025,
- "month": 11,
- "inboundQuantity": 500,
- "outboundQuantity": 250,
- "netChange": 250
}
]Gets filtered stock updates via query parameters. Defaults to last 30 days if dates not specified.
Filters (all optional):
| startDate | string <date-time> Example: startDate=2025-10-20T00:00:00Z Start timestamp (ISO-8601, defaults to 30 days ago) |
| endDate | string <date-time> Example: endDate=2025-11-20T23:59:59Z End timestamp (ISO-8601, defaults to now) |
| itemName | string Example: itemName=Widget Partial item name filter |
| supplierId | string Example: supplierId=supplier-123 Supplier identifier filter |
| createdBy | string Example: createdBy=user@example.com User who made the change |
| minChange | integer <int32> Example: minChange=-100 Minimum quantity change (inclusive) |
| maxChange | integer <int32> Example: maxChange=100 Maximum quantity change (inclusive) |
[- {
- "id": "update-001",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "itemName": "Premium Widget",
- "change": -25,
- "reason": "SALE",
- "timestamp": "2025-11-15T14:30:00Z",
- "createdBy": "user@example.com",
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp"
}
]Gets filtered stock updates via JSON request body. Allows complex filtering criteria in structured format.
| startDate | string or null <date-time> Start timestamp (defaults to 30 days ago) |
| endDate | string or null <date-time> End timestamp (defaults to now) |
| itemName | string or null Partial item name filter |
| supplierId | string or null Supplier identifier filter |
| createdBy | string or null User who made the change |
| minChange | integer or null <int32> Minimum quantity change |
| maxChange | integer or null <int32> Maximum quantity change |
{- "startDate": "2025-10-20T00:00:00Z",
- "endDate": "2025-11-20T23:59:59Z",
- "itemName": "Widget",
- "supplierId": "supplier-123",
- "createdBy": "user@example.com",
- "minChange": -100,
- "maxChange": 100
}[- {
- "id": "update-001",
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "itemName": "Premium Widget",
- "change": -25,
- "reason": "SALE",
- "timestamp": "2025-11-15T14:30:00Z",
- "createdBy": "user@example.com",
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp"
}
]Gets comprehensive dashboard summary with multiple analytics aggregated. Includes supplier distribution, low stock items, trends, and activity.
Defaults: If dates not provided, uses last 30 days.
| supplierId | string Example: supplierId=supplier-123 Optional supplier filter |
| startDate | string <date-time> Example: startDate=2025-10-20T00:00:00Z Start timestamp (defaults to 30 days ago) |
| endDate | string <date-time> Example: endDate=2025-11-20T23:59:59Z End timestamp (defaults to now) |
{- "stockPerSupplier": [
- {
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp",
- "totalQuantity": 1500,
- "totalValue": 45000
}
], - "lowStockItems": [
- {
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "itemName": "Premium Widget",
- "currentQuantity": 15,
- "minimumQuantity": 50,
- "supplierId": "supplier-123",
- "supplierName": "Acme Corp"
}
], - "monthlyStockMovement": [
- {
- "year": 2025,
- "month": 11,
- "inboundQuantity": 500,
- "outboundQuantity": 250,
- "netChange": 250
}
], - "topUpdatedItems": [
- {
- "itemId": "550e8400-e29b-41d4-a716-446655440000",
- "itemName": "Premium Widget",
- "updateCount": 45
}
]
}Gets historical price changes for a specific inventory item. Shows price evolution over a date range with optional supplier filtering.
| itemId required | string Example: itemId=550e8400-e29b-41d4-a716-446655440000 Inventory item identifier |
| supplierId | string Example: supplierId=supplier-123 Optional supplier filter |
| start required | string <date> Example: start=2025-09-01 Inclusive start date (ISO yyyy-MM-dd) |
| end required | string <date> Example: end=2025-11-30 Inclusive end date (ISO yyyy-MM-dd) |
[- {
- "date": "2025-11-15",
- "price": 29.99,
- "quantity": 150
}
]Gets financial summary with Weighted Average Cost (WAC) calculations. Shows inventory costs, valuations, and financial metrics.
| from required | string <date> Example: from=2025-09-01 Start date (ISO yyyy-MM-dd) |
| to required | string <date> Example: to=2025-11-30 End date (ISO yyyy-MM-dd) |
| supplierId | string Example: supplierId=supplier-123 Optional supplier filter |
{- "totalInventoryValue": 157500,
- "totalQuantity": 5243,
- "weightedAverageCost": 30.04,
- "totalCost": 157500,
- "period": {
- "from": "2025-09-01",
- "to": "2025-11-30"
}
}Performs a lightweight health check to verify the application is running.
This endpoint provides a quick way to monitor application availability without checking external dependencies like databases. Useful for load balancers, orchestration platforms, and basic uptime monitoring.
Security: This endpoint is publicly accessible (no authentication required). Used by Fly.io HTTP health checks and container orchestration systems.
Performs a comprehensive health check including database connectivity verification.
Uses Oracle-specific SYS_CONTEXT query to:
Useful for monitoring critical dependencies and detecting infrastructure issues. Returns 503 Service Unavailable if database is unreachable or misconfigured.
Security: This endpoint is publicly accessible (no authentication required). Used by monitoring systems to verify database health.
{- "status": "UP",
- "oracleSeesIp": "192.168.1.100"
}