ERP MVP
Интегрированный monorepo ERP MVP v1 для демонстрации базового операционного цикла: справочники, закупки, продажи, складские движения, PDF-заглушки документов, dashboard и demo data.
Структура
erp-mvp/
backend/
frontend/
.env.example
docker-compose.yml
README.md
Запуск
Опционально можно скопировать пример переменных окружения:
cp .env.example .env
Для production обязательно замените JWT_SECRET, пароли PostgreSQL и dev credentials.
docker compose up --build
После запуска:
- Frontend: http://localhost:5173
- Backend health: http://localhost:8080/api/health
- PostgreSQL: localhost:5432
Backend
Backend использует переменные окружения для подключения к PostgreSQL:
POSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDSPRING_DATASOURCE_URLSPRING_DATASOURCE_USERNAMESPRING_DATASOURCE_PASSWORDCORS_ALLOWED_ORIGINSJWT_SECRETJWT_EXPIRATION_MINUTESADMIN_EMAILADMIN_PASSWORDDEMO_DATA_ENABLED
По умолчанию frontend разрешен с http://localhost:5173.
Backend Foundation
Backend содержит базовую инфраструктуру для дальнейшей разработки ERP-модулей:
- расширяемую package structure с
common,config,healthи заготовкамиmodules; - единый API response envelope;
- global exception handler;
- базовые custom exceptions;
- pagination DTO;
- JPA auditing foundation через
BaseEntity; - OpenAPI / Swagger UI;
- Flyway migrations для системной инициализации.
Auth + Roles
Backend содержит stateless JWT authentication foundation:
- таблица
app_users; - роли
ADMIN,MANAGER,WAREHOUSE,FINANCE; - BCrypt password hashing;
- seed admin user через Spring Boot initializer;
- JWT Bearer auth для защищенных
/api/**endpoint-ов; - Swagger Bearer JWT authorization scheme.
Dev credentials по умолчанию:
- Email:
admin@erp.local - Password:
admin12345
Значения можно переопределить через переменные окружения:
ADMIN_EMAILADMIN_PASSWORDJWT_SECRETJWT_EXPIRATION_MINUTES
API Response Format
Успешный ответ:
{
"success": true,
"data": {},
"error": null,
"timestamp": "2026-05-14T10:00:00Z"
}
Ответ с ошибкой:
{
"success": false,
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": []
},
"timestamp": "2026-05-14T10:00:00Z"
}
API URLs
- Swagger UI: http://localhost:8080/swagger-ui/index.html
- Health check: http://localhost:8080/api/health
- OpenAPI JSON: http://localhost:8080/v3/api-docs
- Frontend login: http://localhost:5173/login
Auth Endpoints
POST /api/auth/loginGET /api/auth/mePOST /api/auth/logoutGET /api/auth/protected-test
Login:
curl -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}'
Protected endpoint with JWT:
TOKEN="<paste-access-token>"
curl "http://localhost:8080/api/auth/protected-test" \
-H "Authorization: Bearer $TOKEN"
Catalog Module
Catalog module содержит базовые ERP-справочники без закупок, заказов, остатков и документов:
- Products / SKU
- Suppliers
- B2B Customers
- Warehouses
Backend endpoints:
GET /api/catalog/productsGET /api/catalog/products/{id}POST /api/catalog/productsPUT /api/catalog/products/{id}DELETE /api/catalog/products/{id}GET /api/catalog/suppliersGET /api/catalog/suppliers/{id}POST /api/catalog/suppliersPUT /api/catalog/suppliers/{id}DELETE /api/catalog/suppliers/{id}GET /api/catalog/customersGET /api/catalog/customers/{id}POST /api/catalog/customersPUT /api/catalog/customers/{id}DELETE /api/catalog/customers/{id}GET /api/catalog/warehousesGET /api/catalog/warehouses/{id}POST /api/catalog/warehousesPUT /api/catalog/warehouses/{id}DELETE /api/catalog/warehouses/{id}
List endpoints support:
?page=0&size=20&search=&active=true
Role access:
GET: any authenticated user.POST,PUT,DELETE:ADMINandMANAGER.DELETEperforms soft delete by settingactive=false.
Frontend URLs:
- Products: http://localhost:5173/catalog/products
- Suppliers: http://localhost:5173/catalog/suppliers
- Customers: http://localhost:5173/catalog/customers
- Warehouses: http://localhost:5173/catalog/warehouses
Create product example:
LOGIN_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}')
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.accessToken')
curl -X POST "http://localhost:8080/api/catalog/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"sku": "SKU-001",
"name": "Demo product",
"category": "General",
"unit": "pcs",
"barcode": "1234567890",
"description": "Demo catalog item"
}'
Procurement Module
Procurement module содержит простой процесс закупок без продаж, документов и оплат:
- purchase order header;
- supplier from Catalog;
- optional receiving warehouse from Catalog;
- product items from Catalog;
- quantity, unit price, line total;
- status flow and status history.
- stock receipt when
ORDEREDmoves toRECEIVED.
Backend endpoints:
GET /api/procurement/purchase-ordersGET /api/procurement/purchase-orders/{id}POST /api/procurement/purchase-ordersPUT /api/procurement/purchase-orders/{id}PATCH /api/procurement/purchase-orders/{id}/statusGET /api/procurement/purchase-orders/{id}/status-historyDELETE /api/procurement/purchase-orders/{id}
List endpoint supports:
?page=0&size=20&search=&status=DRAFT&supplierId=&fromDate=&toDate=
Statuses:
DRAFTAPPROVEDORDEREDRECEIVEDCANCELLED
Allowed transitions:
DRAFTtoAPPROVEDAPPROVEDtoORDEREDORDEREDtoRECEIVEDDRAFTtoCANCELLEDAPPROVEDtoCANCELLEDORDEREDtoCANCELLED
Role access:
- Read:
ADMIN,MANAGER,WAREHOUSE,FINANCE. - Create/update/cancel:
ADMIN,MANAGER. - Mark received:
ADMIN,MANAGER,WAREHOUSE. FINANCEcan only read.
Frontend URLs:
- Purchase orders: http://localhost:5173/procurement/purchase-orders
- Purchase order details: http://localhost:5173/procurement/purchase-orders/{id}
Create purchase order example:
LOGIN_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}')
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.accessToken')
# Create an active supplier, warehouse, and product first in Catalog, then use their ids below.
SUPPLIER_ID="<supplier-id>"
WAREHOUSE_ID="<warehouse-id>"
PRODUCT_ID="<product-id>"
CREATE_PO_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/procurement/purchase-orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "{
\"supplierId\": \"$SUPPLIER_ID\",
\"warehouseId\": \"$WAREHOUSE_ID\",
\"expectedDeliveryDate\": \"2026-06-01\",
\"notes\": \"Initial procurement request\",
\"items\": [
{
\"productId\": \"$PRODUCT_ID\",
\"quantity\": 10,
\"unitPrice\": 1250.00
}
]
}")
PO_ID=$(echo "$CREATE_PO_RESPONSE" | jq -r '.data.id')
curl -X PATCH "http://localhost:8080/api/procurement/purchase-orders/$PO_ID/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"status":"APPROVED","comment":"Approved for ordering"}'
Sales Module
Sales module содержит простой B2B customer order process без документов, оплат и внешних интеграций:
- customer order header;
- customer from Catalog;
- optional warehouse from Catalog;
- product items from Catalog;
- quantity, unit price, line total;
- status flow and status history.
- stock issue when
IN_PROGRESSmoves toSHIPPED.
Backend endpoints:
GET /api/sales/customer-ordersGET /api/sales/customer-orders/{id}POST /api/sales/customer-ordersPUT /api/sales/customer-orders/{id}PATCH /api/sales/customer-orders/{id}/statusGET /api/sales/customer-orders/{id}/status-historyDELETE /api/sales/customer-orders/{id}
List endpoint supports:
?page=0&size=20&search=&status=NEW&customerId=&warehouseId=&fromDate=&toDate=
Statuses:
NEWCONFIRMEDIN_PROGRESSSHIPPEDCLOSEDCANCELLED
Allowed transitions:
NEWtoCONFIRMEDCONFIRMEDtoIN_PROGRESSIN_PROGRESStoSHIPPEDSHIPPEDtoCLOSEDNEWtoCANCELLEDCONFIRMEDtoCANCELLEDIN_PROGRESStoCANCELLED
Role access:
- Read:
ADMIN,MANAGER,WAREHOUSE,FINANCE. - Create/update/cancel:
ADMIN,MANAGER. - Status changes:
ADMIN,MANAGER. - Warehouse status changes:
CONFIRMEDtoIN_PROGRESS,IN_PROGRESStoSHIPPED. FINANCEcan only read.
Frontend URLs:
- Customer orders: http://localhost:5173/sales/customer-orders
- Customer order details: http://localhost:5173/sales/customer-orders/{id}
Create customer order example:
LOGIN_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}')
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.accessToken')
# Create an active customer and product first in Catalog, then use their ids below.
# WAREHOUSE_ID is optional.
CUSTOMER_ID="<customer-id>"
PRODUCT_ID="<product-id>"
WAREHOUSE_ID="<warehouse-id>"
CREATE_ORDER_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/sales/customer-orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "{
\"customerId\": \"$CUSTOMER_ID\",
\"warehouseId\": \"$WAREHOUSE_ID\",
\"requestedDeliveryDate\": \"2026-06-10\",
\"notes\": \"Initial B2B order\",
\"items\": [
{
\"productId\": \"$PRODUCT_ID\",
\"quantity\": 5,
\"unitPrice\": 1800.00
}
]
}")
ORDER_ID=$(echo "$CREATE_ORDER_RESPONSE" | jq -r '.data.id')
curl -X PATCH "http://localhost:8080/api/sales/customer-orders/$ORDER_ID/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"status":"CONFIRMED","comment":"Confirmed with customer"}'
Warehouse Module
Warehouse module содержит складские остатки и историю движений без документов, оплат и внешних интеграций:
- stock balance by warehouse and product;
- stock movement history;
- inbound movement when purchase order becomes
RECEIVED; - outbound movement when customer order becomes
SHIPPED; - manual stock adjustments;
- insufficient stock check before shipping.
Backend endpoints:
GET /api/warehouse/stock-balancesGET /api/warehouse/stock-movementsPOST /api/warehouse/stock-adjustments
Stock balances list supports:
?page=0&size=20&warehouseId=&productId=&search=
Stock movements list supports:
?page=0&size=20&warehouseId=&productId=&movementType=INBOUND&sourceType=PURCHASE_ORDER&sourceId=&fromDate=&toDate=
Movement types:
INBOUNDOUTBOUNDADJUSTMENT_INADJUSTMENT_OUT
Source types:
PURCHASE_ORDERCUSTOMER_ORDERMANUAL_ADJUSTMENT
Business rules:
PurchaseOrdermust havewarehouseIdbefore marking it asRECEIVED.RECEIVEDcreatesINBOUNDstock movement per PO item and increases stock.CustomerOrdermust havewarehouseIdbefore marking it asSHIPPED.SHIPPEDcreatesOUTBOUNDstock movement per SO item and decreases stock.- Shipping is blocked if stock balance does not exist or quantity is insufficient.
- Manual
ADJUSTMENT_OUTis blocked if it would make stock negative.
Role access:
- Read stock balances/movements:
ADMIN,MANAGER,WAREHOUSE,FINANCE. - Manual stock adjustment:
ADMIN,WAREHOUSE. - PO receipt:
ADMIN,MANAGER,WAREHOUSE. - SO shipment:
ADMIN,MANAGER,WAREHOUSE. FINANCEis read-only.
Frontend URLs:
- Stock balances: http://localhost:5173/warehouse/stock-balances
- Stock movements: http://localhost:5173/warehouse/stock-movements
Manual adjustment example:
LOGIN_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}')
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.accessToken')
WAREHOUSE_ID="<warehouse-id>"
PRODUCT_ID="<product-id>"
curl -X POST "http://localhost:8080/api/warehouse/stock-adjustments" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "{
\"warehouseId\": \"$WAREHOUSE_ID\",
\"productId\": \"$PRODUCT_ID\",
\"type\": \"ADJUSTMENT_IN\",
\"quantity\": 25.000,
\"comment\": \"Opening stock balance\"
}"
Mark PO as received:
curl -X PATCH "http://localhost:8080/api/procurement/purchase-orders/$PO_ID/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"status":"RECEIVED","comment":"Received into warehouse"}'
Mark SO as shipped:
curl -X PATCH "http://localhost:8080/api/sales/customer-orders/$ORDER_ID/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"status":"SHIPPED","comment":"Shipped from warehouse"}'
Documents Module
Documents module генерирует простые PDF placeholders для customer orders без email, подписей, оплат и внешних сервисов.
Document types:
INVOICECONTRACTDELIVERY_NOTE
Backend endpoints:
GET /api/documentsGET /api/documents/{id}GET /api/documents/customer-orders/{customerOrderId}POST /api/documents/customer-orders/{customerOrderId}/generateGET /api/documents/{id}/download
List endpoint supports:
?page=0&size=20&documentType=INVOICE&sourceType=CUSTOMER_ORDER&sourceId=&status=GENERATED&fromDate=&toDate=
Business rules:
- Customer order must exist.
- Documents cannot be generated for
CANCELLEDcustomer orders. DELIVERY_NOTEcan be generated only forSHIPPEDorCLOSEDorders.INVOICEandCONTRACTcan be generated for any status exceptCANCELLED.- Regenerating the same document type for the same customer order updates the existing PDF and keeps the document number.
Role access:
- Read/list/download:
ADMIN,MANAGER,WAREHOUSE,FINANCE. - Generate
INVOICEandCONTRACT:ADMIN,MANAGER,FINANCE. - Generate
DELIVERY_NOTE:ADMIN,MANAGER,WAREHOUSE.
Frontend URLs:
- Documents: http://localhost:5173/documents
- Customer order details documents block: http://localhost:5173/sales/customer-orders/{id}
Generate invoice example:
LOGIN_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}')
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.accessToken')
CUSTOMER_ORDER_ID="<customer-order-id>"
GENERATE_DOCUMENT_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/documents/customer-orders/$CUSTOMER_ORDER_ID/generate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"documentType":"INVOICE"}')
DOCUMENT_ID=$(echo "$GENERATE_DOCUMENT_RESPONSE" | jq -r '.data.id')
Download PDF example:
curl -L "http://localhost:8080/api/documents/$DOCUMENT_ID/download" \
-H "Authorization: Bearer $TOKEN" \
-o invoice-placeholder.pdf
Dashboard / Analytics
Dashboard module содержит read-only ERP analytics для руководителя без Power BI, внешней BI-системы и изменения бизнес-логики.
Backend endpoints:
GET /api/dashboard/summaryGET /api/dashboard/salesGET /api/dashboard/procurementGET /api/dashboard/warehouseGET /api/dashboard/recent-activitiesGET /api/dashboard/low-stock
Metrics included:
- catalog counts: products, active products, suppliers, customers, warehouses;
- sales: customer order counts, active orders, total sales amount, status breakdown, daily sales, top customers;
- procurement: purchase order counts, active orders, total procurement amount, status breakdown, daily procurement, top suppliers;
- warehouse: stock items, quantity on hand, low stock, movements, stock by warehouse, movements by type;
- documents: total generated documents and documents by type;
- recent activities across customer orders, purchase orders, stock movements, and documents.
Query examples:
GET /api/dashboard/sales?fromDate=2026-05-01&toDate=2026-05-31
GET /api/dashboard/procurement?fromDate=2026-05-01&toDate=2026-05-31
GET /api/dashboard/recent-activities?limit=20
GET /api/dashboard/low-stock?threshold=10&page=0&size=20
Role access:
ADMINMANAGERWAREHOUSEFINANCE
Frontend URL:
- Dashboard: http://localhost:5173/dashboard
Dashboard sections:
- KPI cards
- Sales by Status
- Procurement by Status
- Warehouse Overview
- Low Stock Items
- Recent Activities
Summary curl example:
LOGIN_RESPONSE=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@erp.local","password":"admin12345"}')
TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.data.accessToken')
curl "http://localhost:8080/api/dashboard/summary" \
-H "Authorization: Bearer $TOKEN"
Low stock curl example:
curl "http://localhost:8080/api/dashboard/low-stock?threshold=10&page=0&size=20" \
-H "Authorization: Bearer $TOKEN"
Demo Data
Demo seed заполняет dev/demo окружение тестовыми данными для демонстрации ERP без ручной подготовки справочников, заказов, остатков и документов.
Seed выключен по умолчанию:
app:
demo-data:
enabled: ${DEMO_DATA_ENABLED:false}
Включить можно через env:
DEMO_DATA_ENABLED=true
В dev docker-compose.yml для backend уже задано:
DEMO_DATA_ENABLED: ${DEMO_DATA_ENABLED:-true}
Demo users:
admin@erp.local/admin12345/ADMINmanager@erp.local/manager12345/MANAGERwarehouse@erp.local/warehouse12345/WAREHOUSEfinance@erp.local/finance12345/FINANCE
Seeded data:
- catalog: 8 products, 3 suppliers, 3 customers, 2 warehouses;
- procurement: 3 purchase orders, including one
RECEIVEDorder that creates inbound stock movements; - sales: 4 customer orders, including one
SHIPPEDorder that creates outbound stock movements; - warehouse: manual low-stock adjustments for
Water 0.5LandApple Juice 1L; - documents: invoice, contract and delivery note for shipped order; invoice and contract for confirmed order.
Idempotency:
- users are matched by email;
- products by SKU;
- warehouses by code;
- suppliers/customers by BIN or company name;
- purchase/customer orders by
DEMO-SEED-*marker in notes; - manual stock movements by source, warehouse, product and comment;
- documents reuse the existing unique
(sourceType, sourceId, documentType)row.
How to verify:
- Run
docker compose up --build. - Open http://localhost:5173/login.
- Use any demo credential button.
- Check Dashboard, Catalog, Purchase Orders, Customer Orders, Stock Balances, Stock Movements, and Documents.
UI / UX
Frontend содержит единый ERP-style интерфейс без внешней UI-библиотеки:
- общий layout с grouped sidebar и top header;
- reusable UI components в
frontend/src/components/ui; - единые table/loading/error/empty/pagination states;
- единые status badges для закупок, продаж, документов и складских движений;
- форматтеры в
frontend/src/utils/formatters.tsдля сумм, количеств, дат, статусов, типов документов и движений; - role-aware UI: frontend скрывает недоступные кнопки, backend остается главным источником прав.
Available frontend routes:
/login/dashboard/catalog/products/catalog/suppliers/catalog/customers/catalog/warehouses/procurement/purchase-orders/procurement/purchase-orders/{id}/sales/customer-orders/sales/customer-orders/{id}/warehouse/stock-balances/warehouse/stock-movements/documents
Role-aware UI behavior:
FINANCE: read-only UI for catalog, purchase orders, customer orders, warehouse; can generate invoice/contract documents.WAREHOUSE: no catalog create/edit UI; can receive PO, process/ship SO, create warehouse adjustments, generate delivery notes.ADMINandMANAGER: main operational actions for catalog, procurement, sales, and documents.- Warehouse manual
ADJUSTMENT_OUT, catalog deactivate, PO cancel, and SO cancel use confirmation dialogs.
Common UI components:
Button,Input,Select,TextareaCard,Badge,PageHeaderEmptyState,LoadingState,ErrorStateConfirmDialog,FormField,Pagination
Debug Error Endpoint
Dev-only endpoint для проверки единого формата ошибок:
curl "http://localhost:8080/api/debug/error?type=validation"
curl "http://localhost:8080/api/debug/error?type=not-found"
curl "http://localhost:8080/api/debug/error?type=business"
curl "http://localhost:8080/api/debug/error?type=generic"
Endpoint должен быть удален или отключен перед production.
Useful Commands
Run:
docker compose up --build
Stop:
docker compose down
Reset database:
docker compose down -v
docker compose up --build
Backend logs:
docker compose logs -f backend
Frontend logs:
docker compose logs -f frontend
Postgres logs:
docker compose logs -f postgres
Server deployment compose:
docker compose -f docker-compose.server.yml up -d --build
docker-compose.server.yml does not publish app ports directly. It expects an external Docker network named common_network and an edge reverse proxy, for example nginx, to route HTTPS traffic to erp-frontend and /api traffic to erp-backend.
ERP MVP Demo Script
Pitch:
This MVP demonstrates the core ERP operating loop: catalog data, procurement, sales orders, warehouse stock movements, document generation and management dashboard in one integrated system.
5-7 minute flow:
- Login as Admin:
admin@erp.local/admin12345. - Open Dashboard and show KPI cards for catalog, sales, procurement, warehouse, documents and low stock.
- Open Catalog -> Products, Suppliers, Customers, Warehouses and show the seeded master data.
- Open Purchase Orders and open the received PO.
- Explain that moving PO to
RECEIVEDcreated inbound stock movements. - Open Stock Balances and show updated warehouse quantities.
- Open Customer Orders and open the shipped order.
- Explain that moving SO to
SHIPPEDcreated outbound stock movements and checked available stock. - Open Documents and show generated invoice, contract and delivery note placeholders.
- Download one PDF from Documents or Customer Order details.
- Return to Dashboard and show recent activities, low stock and updated analytics.
Manual QA Checklist
Backend:
/api/healthreturnsUP.- Swagger opens at http://localhost:8080/swagger-ui/index.html.
- Login works.
- Catalog CRUD works.
- Purchase order flow works.
- Customer order flow works.
- Stock balances update correctly.
- Documents generate and download.
- Dashboard loads.
Frontend:
- Login works.
- Sidebar navigation works.
- Dashboard loads.
- Forms save data.
- Status transitions work.
- Errors display properly.
- Download PDF works.
- Logout works.
Troubleshooting
PostgreSQL port already in use:
- Stop the local PostgreSQL process or change the
5432:5432mapping indocker-compose.yml.
Backend cannot connect to database:
- Check
docker compose logs -f backendand confirmSPRING_DATASOURCE_URL,POSTGRES_DB,POSTGRES_USERandPOSTGRES_PASSWORDmatch.
Flyway migration failed:
- For dev data loss is acceptable, reset with
docker compose down -vand thendocker compose up --build.
Frontend cannot call backend due to CORS:
- Confirm
CORS_ALLOWED_ORIGINSincludeshttp://localhost:5173.
JWT expired or unauthorized:
- Logout, login again, and check that requests include
Authorization: Bearer <token>.
Demo data not visible:
- Ensure
DEMO_DATA_ENABLED=true, then reset the dev database if it was initialized before enabling demo data.
PDF download blocked by browser:
- Try downloading from the Documents page again and make sure pop-up/download blocking is not preventing the file save.
Database credentials changed but old volume remains:
- Run
docker compose down -vso PostgreSQL can initialize with the new.envvalues.
MVP Scope
Included:
- Auth and roles.
- Catalog.
- Procurement.
- Sales.
- Warehouse stock.
- Documents.
- Dashboard.
- Demo data.
Not included in MVP v1:
- Real 1C integration.
- Real WMS/TMS integration.
- Payment module.
- Email/WhatsApp sending.
- Electronic signature.
- Advanced approval workflow.
- Advanced BI/Power BI.
- Multi-company accounting.