implement fe with backend

This commit is contained in:
2026-08-02 01:25:17 +05:30
parent 3c5b476635
commit 266a2a2c14
38 changed files with 5229 additions and 32 deletions
+4
View File
@@ -21,6 +21,7 @@ A modular ERP built in phases. **Phase 1** delivers the **Inventory & Supply Cha
Full requirements live in the backend spec (see §7). This file does **not** duplicate them.
**Phase 2 (HRM)** is now underway alongside Phase 1 — see §7 routing to `12-BACKEND-HRM.md` / `13-BACKEND-HRM-API.md` / `21-FRONTEND-HRM.md`.
Sales has its own API reference at `14-BACKEND-SALES-API.md`.
---
@@ -45,6 +46,7 @@ erp-monorepo/
├── 02-SECURITY.md # accepted-risks register + per-feature security checklist
├── 10-BACKEND-PHASE1.md # backend spec: SRS + ER/entities + tech + architecture
├── 11-BACKEND-PHASE1.md # backend API reference (complete req/res)
├── 14-BACKEND-SALES-API.md # sales API reference (invoices, slips, free issues, reports)
├── 12-GENERAL-LEDGER-INTEGRATION.md # ERPCore ↔ external General Ledger service (transport only)
├── 20-FRONTEND.md # frontend user-flows + architecture rules + validation posture
└── 21-GENERAL-LEDGER-FRONTEND.md # Ledgers section: reports UI + cash/bank accounts
@@ -344,6 +346,7 @@ All frontend work is governed by `20-FRONTEND.md`.
| HRM API endpoints, request/response shapes, error catalog (Phase 2) | **`13-BACKEND-HRM-API.md`** |
| Connecting to the external General Ledger service (proxy, config, API key) | **`12-GENERAL-LEDGER-INTEGRATION.md`** |
| The Ledgers frontend section (reports, cash/bank accounts) | **`21-GENERAL-LEDGER-FRONTEND.md`** |
| Sales API endpoints, request/response shapes, error catalog, enums | **`14-BACKEND-SALES-API.md`** |
| Frontend user-flows, screen flow, architecture rules, validation posture (Phase 1) | **`20-FRONTEND.md`** |
| HRM frontend user-flows (Phase 2) | **`21-FRONTEND-HRM.md`** |
| Manufacturing requirements, business rules, entities, stock/costing integration, API (Phase 2) | **`30-BACKEND-PHASE2.md`** |
@@ -356,6 +359,7 @@ All frontend work is governed by `20-FRONTEND.md`.
Quick resolver:
- *"Where is the model / an entity defined?"* → `10-BACKEND-PHASE1.md` (Phase 1) / `12-BACKEND-HRM.md` (HRM) — schema is authoritative there.
- *"What does this endpoint accept/return?"* → `11-BACKEND-PHASE1.md` (Phase 1) / `13-BACKEND-HRM-API.md` (HRM).
- *"What does the sales API accept/return?"* → `14-BACKEND-SALES-API.md`.
- *"How should the UI flow / what do I validate where?"* → `20-FRONTEND.md` (Phase 1) / `21-FRONTEND-HRM.md` (HRM).
- *"What security risks / checks apply to this feature?"* → `02-SECURITY.md`.
+2 -1
View File
@@ -39,6 +39,7 @@
| `12-BACKEND-HRM.md` | High | HRM backend spec: SRS, ER model, HRM-specific architecture notes. Schema is **authoritative** here. | Any HRM model / business-rule / requirement work (Phase 2). | Claude + humans |
| `13-BACKEND-HRM-API.md` | High | HRM **API reference**: every endpoint, error catalog additions, enums. | Any HRM API contract / controller work. | Claude + humans |
| `12-GENERAL-LEDGER-INTEGRATION.md` | High | ERPCore ↔ external **General Ledger service**: connection/proxy contract, config, progress. GL's own endpoint contract lives in the GL service's own repo, not here. | Any work touching the GL proxy or a future internal GL caller. | Claude + humans |
| `14-BACKEND-SALES-API.md` | High | Sales **API reference**: invoices, slips, free issues, reports, enums. | Any sales API contract / controller work. | Claude + humans |
| `20-FRONTEND.md` | High | Frontend **user-flows**, architecture rules to follow, **validation posture**. | Any frontend work (Phase 1). | Claude + humans |
| `21-FRONTEND-HRM.md` | High | HRM frontend **user-flows**, screens, validation specifics. | Any HRM frontend work. | Claude + humans |
| `30-BACKEND-PHASE2.md` | High | Manufacturing (Production Lines) backend: SRS, ER model, status machines, stock/costing integration, **and** the full API contract — model and API in one doc, unlike Phase 1. Schema is **authoritative** here. | Any manufacturing model / rule / API work. | Claude + humans |
@@ -197,7 +198,7 @@ Spec: docs/20-FRONTEND.md (flows + rules) · docs/11-BACKEND-PHASE1.md (API cont
## 7. Adding future docs
When later phases arrive (Sales & CRM, Manufacturing, QC/QA, Accounting), follow the same scheme HRM (Phase 2) established:
- Backend spec/API for a phase → new `1x-` files continuing the backend decade (e.g. HRM used `12-BACKEND-HRM.md` + `13-BACKEND-HRM-API.md`, mirroring the `10`/`11` SRS+ER / API-reference split), linked from the hub.
- Backend spec/API for a phase → new `1x-` files continuing the backend decade (e.g. HRM used `12-BACKEND-HRM.md` + `13-BACKEND-HRM-API.md`; sales now uses `14-BACKEND-SALES-API.md` alongside the existing phase docs), linked from the hub.
- Frontend additions → extend `20-FRONTEND.md` or add `2x-` files (e.g. HRM used `21-FRONTEND-HRM.md`).
- Always register the new doc in `00-CORE.md` routing (§7) and in this index (§2).
+224
View File
@@ -0,0 +1,224 @@
# 14 · BACKEND — Sales API Reference
> **Authoritative for:** sales API contracts for invoices, slips, free issues, and sales reports.
> **Navigation:** start from `00-CORE.md`. Sales business rules live in `docs/SALES_MODULE_PLAN.md` and the sales-related backend progress is tracked in `Backend/PROGRESS.md`.
> **Scope:** this document covers the sales endpoints currently implemented in ERPCore. Free issue is modeled as a sales-slip alias, not a separate table.
---
## 1. Conventions
- Base URL: `https://{host}/api/v1`
- Authentication: same as the rest of the v1 API
- Concurrency: `ETag` / `If-Match` on mutable resources
- Validation: `ProblemDetails` / `ValidationProblemDetails`
---
## 2. Sales Invoices
### `GET /api/v1/sales-invoices`
Query:
- `page`
- `pageSize`
- `q`
- `status`
- `customerId`
- `warehouseId`
Returns a paged list of `SalesInvoiceSummaryDto`.
The current frontend register uses this endpoint directly for the invoice hub view.
### `GET /api/v1/sales-invoices/{salesInvoiceId}`
Returns `SalesInvoiceDto`.
The detail page shows the document template and only exposes edit actions when the invoice is `Draft`.
### `POST /api/v1/sales-invoices`
Creates a draft sales invoice.
Request:
```json
{
"customerId": 2,
"warehouseId": 1,
"invoiceType": "B2C",
"lines": [
{
"itemId": 1,
"uomId": 1,
"warehouseId": 1,
"qty": 1,
"freeQty": 0,
"unitPrice": 100,
"allowManualPriceOverride": false,
"discountMode": "Percentage",
"discountPct": 0,
"discountAmount": 0,
"discountValue": 0,
"taxPct": 0,
"isFreeIssue": false,
"parentLineId": null
}
]
}
```
### `PUT /api/v1/sales-invoices/{salesInvoiceId}`
Updates a draft invoice. Requires `If-Match`.
### `POST /api/v1/sales-invoices/{salesInvoiceId}/post`
Posts stock out and marks the invoice as `Posted`.
Before posting, the UI calls `GET /api/v1/sales-invoices/{salesInvoiceId}/posting-check` to show shortages.
### `POST /api/v1/sales-invoices/{salesInvoiceId}/cancel`
Cancels a draft invoice.
---
## 3. Sales Slips
### `GET /api/v1/sales-slips`
Query:
- `page`
- `pageSize`
- `q`
- `status`
- `customerId`
- `warehouseId`
Returns a paged list of `SalesSlipSummaryDto`.
### `GET /api/v1/sales-slips/{salesSlipId}`
Returns `SalesSlipDto`.
The detail page follows the same document-style layout and draft-only edit behavior as invoices.
### `POST /api/v1/sales-slips`
Creates a draft sales slip.
Request:
```json
{
"customerId": 2,
"warehouseId": 1,
"cashierUserId": 1,
"lines": [
{
"itemId": 1,
"uomId": 1,
"warehouseId": 1,
"qty": 1,
"freeQty": 0,
"unitPrice": 50,
"allowManualPriceOverride": false,
"discountMode": "Percentage",
"discountPct": 0,
"discountAmount": 0,
"discountValue": 0,
"taxPct": 0,
"isFreeIssue": false,
"parentLineId": null
}
]
}
```
### `PUT /api/v1/sales-slips/{salesSlipId}`
Updates a draft slip. Requires `If-Match`.
### `POST /api/v1/sales-slips/{salesSlipId}/post`
Posts stock out and marks the slip as `Posted`.
Before posting, the UI calls `GET /api/v1/sales-slips/{salesSlipId}/posting-check`.
### `POST /api/v1/sales-slips/{salesSlipId}/cancel`
Cancels a draft slip.
---
## 4. Free Issues
Free issue is a business alias over sales slips.
There is no separate free-issue table in the current schema.
### `GET /api/v1/free-issues`
Same contract as `GET /api/v1/sales-slips`.
### `GET /api/v1/free-issues/{freeIssueId}`
Same contract as `GET /api/v1/sales-slips/{salesSlipId}`.
### `POST /api/v1/free-issues`
Same contract as `POST /api/v1/sales-slips`.
### `PUT /api/v1/free-issues/{freeIssueId}`
Same contract as `PUT /api/v1/sales-slips/{salesSlipId}`.
### `POST /api/v1/free-issues/{freeIssueId}/post`
Same contract as `POST /api/v1/sales-slips/{salesSlipId}/post`.
### `POST /api/v1/free-issues/{freeIssueId}/cancel`
Same contract as `POST /api/v1/sales-slips/{salesSlipId}/cancel`.
Business rule:
- free issue is represented by `IsFreeIssue=true` and/or `FreeQty>0`
- it still posts stock out through the normal slip posting flow
- the frontend free-issue screen is the main working page for create/list/edit/cancel
- cancelled free-issue records are hidden from the working list view
---
## 5. Sales Reports
### `GET /api/v1/reports/sales`
Returns the report catalog.
Response:
```json
[
{
"id": "daily-summary",
"name": "Daily Summary",
"description": "Aggregated sales by day across posted invoices and slips.",
"supportedFilters": ["from", "to"]
}
]
```
### `GET /api/v1/reports/sales/{reportId}`
Returns a single report definition by id.
### `POST /api/v1/reports/sales/query`
Returns the actual report data.
Request:
```json
{
"reportType": "item-summary",
"from": "2026-07-01",
"to": "2026-07-28",
"itemId": 1,
"customerId": null,
"warehouseId": 1
}
```
Supported report types:
- `daily-summary`
- `item-summary`
- `customer-summary`
- `warehouse-summary`
- `discount-summary`
- `free-issue-summary`
Validation rule:
- invalid filters for a given report type are rejected
- unsupported report types are rejected
- the frontend report page uses the same endpoint for all report types
- `daily-summary` auto-loads with a default date range in the UI
- the report results table is rendered from the backend response rows, not hardcoded data
---
## 6. Notes
- The sales report service reads both invoices and slips where relevant.
- Free issue reporting is derived from the same sales document lines.
- There is no separate free-issue table in the current schema.
+10 -8
View File
@@ -229,13 +229,15 @@ When an invoice or slip is posted:
- `POST /api/v1/sales-slips`
- `POST /api/v1/sales-slips/{id}/post`
- `POST /api/v1/sales-slips/{id}/cancel`
- `GET /api/v1/sales-reports/daily-summary`
- `GET /api/v1/sales-reports/item-wise`
- `GET /api/v1/sales-reports/customer-wise`
- `GET /api/v1/sales-reports/warehouse-wise`
- `GET /api/v1/sales-reports/discount-summary`
- `GET /api/v1/sales-reports/free-issue-summary`
- `GET /api/v1/sales-reports/margin-summary`
- `GET /api/v1/free-issues`
- `GET /api/v1/free-issues/{id}`
- `POST /api/v1/free-issues`
- `PUT /api/v1/free-issues/{id}`
- `POST /api/v1/free-issues/{id}/post`
- `POST /api/v1/free-issues/{id}/cancel`
- `GET /api/v1/reports/sales`
- `GET /api/v1/reports/sales/{reportId}`
- `POST /api/v1/reports/sales/query`
### Phase 1 Folder / Module Plan
- `Domain/Entities`
@@ -264,7 +266,7 @@ When an invoice or slip is posted:
4. Pricing resolver
5. Discount computation
6. Free issue handling
7. Stock posting and ledger integration
7. Stock posting
8. Basic sales reports
9. Controllers and swagger wiring