Files
ERP-core/docs/00-CORE.md
T
HarithaRandunu 22657f0910 feat: Implement new General Ledger frontend section with comprehensive report screens and cash/bank account management
- Added a new Ledgers sidebar section for statutory-format financial reports and cash/bank-account management.
- Introduced dedicated GL client for API interactions, handling response envelopes and error management.
- Developed report screens for Trial Balance, Balance Sheet, General Ledger, Profit & Loss, Cash Flow, Budget vs Actual, and a new Tax Report.
- Implemented CSV download functionality alongside existing PDF downloads for all report screens.
- Separated Cash and Bank accounts into distinct tables/endpoints, with updated create forms and unified list view.
- Created a new Accounts section for Cheque Management, moving Cash/Bank Accounts from the Ledgers section.
- Updated RBAC navigation to include new permissions and sub-navigation items for the added features.
- Ensured compliance with GL's updated API contract, including renaming fields and adjusting response shapes.
- Addressed various bugs and presentation issues, enhancing user experience across the new module.
2026-07-31 18:02:03 +05:30

383 lines
18 KiB
Markdown

# 00 · CORE — ERP System (Phase 1: Inventory & Supply Chain)
> **This file is the hub. Start every task here.**
> It defines the repository structure, the tech stack, how to stand up a runnable backend, and — most importantly — **where to go next** for any piece of work. Do not begin backend or frontend work without first reading the relevant section below and following the routing table in §7.
---
## 1. What this project is
A modular ERP built in phases. **Phase 1** delivers the **Inventory & Supply Chain** subsystem: master data, procurement, goods receipt, and stock management (FIFO costing, multi-warehouse, single-tenant).
| Decision | Value |
|---|---|
| Costing method | **FIFO** (cost-layer tracking, per item per warehouse) |
| Warehouses | **Multi-warehouse** |
| Tenancy | **Single-tenant** |
| Approvals (PO, adjustment) | **Auto-approve**, config-gated off (RBAC deferred) |
| Access control | Authentication only; **RBAC deferred**, user identity stamped for audit |
| Vendor invoice / 3-way match | **Deferred** to Accounting phase (GRN retains hooks) |
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`.
---
## 2. Repository structure
```
erp-monorepo/
├── README.md # Root: what this is + how to run both sides
├── .gitignore # ignore appsettings.*.json secrets, .env*, bin/, obj/, node_modules/
├── Backend/ # ASP.NET Core Web API (.NET 10) — see §5 to initialize
│ ├── ERPCore.sln
│ ├── PROGRESS.md # ← backend change checklist (Claude-maintained, git-shared)
│ └── ERPCore/ # single Web API project (folders, not multi-project)
├── Frontend/ # Next.js (App Router + TypeScript) — already initialized
│ └── PROGRESS.md # ← frontend change checklist (Claude-maintained, git-shared)
└── docs/ # ALL documentation
├── 00-CORE.md # ← you are here (hub)
├── 01-DOC-GUIDE.md # documentation map + tracking conventions
├── 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)
├── 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
```
The `Backend/ERPCore/` internal layout is created in §5.3.
---
## 3. Tech stack
### Backend
| Concern | Choice |
|---|---|
| Runtime | **.NET 10** (`net10.0`) |
| Framework | ASP.NET Core Web API (controllers) |
| ORM | EF Core 10 |
| Database | **PostgreSQL** (Npgsql provider) |
| Auth | JWT bearer (simple in-app login; RBAC deferred) |
| Logging | Serilog (file sink) |
| API docs | Swashbuckle / Swagger UI |
| Health | HealthChecks + EF Core DB check → `GET /health` |
### Frontend
| Concern | Choice |
|---|---|
| Framework | **Next.js** (App Router) + TypeScript |
| State/forms | **Plain React hooks** (`useState` / custom hooks) |
| Validation | **Dependency-free** (hand-rolled) — client-side for UX only; **server is authoritative** |
| API access | Typed fetch client against the backend (`NEXT_PUBLIC_API_BASE_URL`) |
> The Frontend project is **already initialized**. Do not scaffold it here. For all frontend architecture, flows, and validation rules, go to `20-FRONTEND.md`.
### Database
PostgreSQL, running on **localhost** for development. Secrets management (User Secrets / environment variables) is deferred; see §5.4 for the current local configuration and the note on secrets.
---
## 4. Architecture (high-level, both sides)
### Backend layering — strict, one direction
```
Controller → Service → Repository → UnitOfWork/DbContext
(DTOs) (logic) (entities) (transaction boundary)
```
Rules (non-negotiable for Phase 1):
- **DTOs at the controller boundary.** Controllers accept and return DTOs only — **never** EF entities and **never** `DbContext`.
- **Services hold business logic** and return DTOs. Controllers stay thin (HTTP concerns only).
- **Repositories own EF entities** and data access. No business rules in repositories.
- **UnitOfWork is the transaction boundary.** Every stock-affecting operation (GRN confirm, transfer dispatch/receive, adjustment, return, count post) runs inside a single UoW transaction.
- **FIFO lives in a domain service** (`FifoCostingService`), invoked by stock services inside the UoW transaction — **not** in a controller or repository. Layer consumption must lock affected rows for concurrency safety.
- **Errors use RFC 7807 `ProblemDetails`** (ASP.NET Core default). Domain errors carry a stable `code`. The error catalog is in `11-BACKEND-PHASE1.md`.
- **Audit actor** is derived from the authenticated principal (token `sub`), never from the request body.
### Frontend (summary — full rules in `20-FRONTEND.md`)
- Stick to the existing initialized architecture; do not restructure.
- **Validate on the client for UX, but never trust it.** The server re-validates everything. Business rules that depend on server state (stock availability, negative-stock block, over-receipt tolerance, FIFO sufficiency) are **server-authoritative** and must not be assumed valid client-side.
---
## 5. Backend initialization (runnable)
Follow in order. Commands assume repo root `erp-monorepo/`.
### 5.1 Prerequisites
- **.NET 10 SDK** (`dotnet --version``10.0.x`)
- **PostgreSQL** running on localhost, and a login you can use
- **EF Core CLI**: `dotnet tool install --global dotnet-ef` (or `dotnet tool update --global dotnet-ef`)
- Node.js (for the Frontend, handled separately)
### 5.2 Create solution and project
```bash
mkdir -p Backend && cd Backend
dotnet new sln -n ERPCore
dotnet new webapi -n ERPCore --use-controllers -f net10.0
dotnet sln add ERPCore/ERPCore.csproj
cd ERPCore
```
### 5.3 Create the internal folder structure
```bash
# from Backend/ERPCore/
mkdir -p Controllers Services/Interfaces Services/Stock \
Repositories/Interfaces \
Domain/Entities Domain/Enums \
Dtos/Common \
Common/Models \
Infra/UoW Infra/Persistence/Configurations Infra/Persistence/Migrations Infra/Auth Infra/Logging \
System/Errors \
HealthChecks
```
Target internal layout:
```
ERPCore/
├── ERPCore.csproj
├── Program.cs
├── appsettings.json # base (no real secrets)
├── appsettings.Development.json # local dev (localhost Postgres)
├── appsettings.Production.json # env-var driven
├── Controllers/ # HTTP; DTOs in/out
├── Services/ # business logic → DTOs
│ ├── Interfaces/
│ └── Stock/ (StockService, FifoCostingService)
├── Repositories/ # EF data access (entities)
│ └── Interfaces/
├── Domain/
│ ├── Entities/ # 38 EF entities
│ └── Enums/ # ItemType, TrackingMode, HoldStatus, Direction, *Status
├── Dtos/ # request/response DTOs (+ Common: paging)
├── Common/Models/ # PagedResult<T>, PaginationMeta, Result<T>
├── Infra/
│ ├── UoW/ # IUnitOfWork, UnitOfWork
│ ├── Persistence/ # ErpDbContext, Configurations/, Migrations/
│ ├── Auth/ # JWT setup, ICurrentUser (audit source)
│ └── Logging/ # Serilog config
├── System/Errors/ # domain exceptions, error codes, ProblemDetails middleware
└── HealthChecks/ # EF Core DB health check
```
### 5.4 Add packages
Pinned versions below are current for .NET 10 at time of writing. All `Microsoft.EntityFrameworkCore.*` packages **must share the same version**.
```bash
# from Backend/ERPCore/
dotnet add package Microsoft.EntityFrameworkCore --version 10.0.9
dotnet add package Microsoft.EntityFrameworkCore.Design --version 10.0.9
dotnet add package Microsoft.EntityFrameworkCore.Tools --version 10.0.9
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL --version 10.0.2
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 10.0.9
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore --version 10.0.9
dotnet add package Serilog.AspNetCore --version 9.0.0
dotnet add package Serilog.Sinks.File --version 6.0.0
dotnet add package Swashbuckle.AspNetCore --version 10.2.3
```
Resulting `ERPCore.csproj`:
```xml
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.9" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="10.0.9" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="Common\Models\" />
<Folder Include="Infra\UoW\" />
<Folder Include="System\Errors\" />
</ItemGroup>
</Project>
```
> **Swashbuckle v10 note:** v10 upgraded to `Microsoft.OpenApi` 2.x and emits **OpenAPI 3.1**. `Program.cs` uses `using Microsoft.OpenApi;` and `AddSwaggerGen(...)` / `UseSwagger()` / `UseSwaggerUI()`.
### 5.5 App settings (three files)
`appsettings.json` (base — no real secrets; placeholder only):
```json
{
"Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } },
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=ERPCore;Username=CHANGE_ME;Password=CHANGE_ME"
},
"Jwt": {
"Issuer": "ERPCore",
"Audience": "ERPCore.Clients",
"SigningKey": "CHANGE_ME_DEV_ONLY_32+_CHARS",
"AccessTokenMinutes": 120
},
"AllowedHosts": "*"
}
```
`appsettings.Development.json` (local dev — used by `dotnet run` in Development):
```json
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=ERPCore;Username=postgres;Password=postgres"
},
"Jwt": { "SigningKey": "dev-only-signing-key-please-change-me-0123456789" }
}
```
`appsettings.Production.json` (values injected from environment variables at deploy time):
```json
{
"ConnectionStrings": { "DefaultConnection": "" },
"Jwt": { "SigningKey": "" }
}
```
> **Secrets note (current phase):** we are on **localhost dev only**, so the Development file holds local credentials for convenience. Before any shared/staging/production use, move secrets to **User Secrets** (dev) and **environment variables** (prod), keep `appsettings.Development.json` / `appsettings.Production.json` out of git (see root `.gitignore`), and rotate any credential that was ever committed.
### 5.6 Minimal `Program.cs` wiring (outline)
```csharp
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Serilog (file sink)
builder.Host.UseSerilog((ctx, cfg) => cfg
.ReadFrom.Configuration(ctx.Configuration)
.WriteTo.File("logs/erpcore-.log", rollingInterval: RollingInterval.Day));
builder.Services.AddControllers();
// EF Core + PostgreSQL
builder.Services.AddDbContext<ErpDbContext>(o =>
o.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
// ProblemDetails (RFC 7807)
builder.Services.AddProblemDetails();
// JWT bearer auth (RBAC deferred; identity used for audit stamp)
builder.Services.AddAuthentication(/* JwtBearer options from config */);
builder.Services.AddAuthorization();
// Health checks (EF Core DB)
builder.Services.AddHealthChecks().AddDbContextCheck<ErpDbContext>();
// Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(o => o.SwaggerDoc("v1", new() { Title = "ERPCore API", Version = "v1" }));
// DI: register UoW, repositories, services, ICurrentUser, FifoCostingService here
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseExceptionHandler(); // maps to ProblemDetails
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHealthChecks("/health");
app.Run();
```
### 5.7 Create the database and run
```bash
# ensure the ERPCore database exists in your local Postgres, then:
dotnet ef migrations add InitialCreate -o Infra/Persistence/Migrations
dotnet ef database update
dotnet run
```
**Verify:**
- Swagger UI at `https://localhost:<port>/swagger`
- Health at `https://localhost:<port>/health``Healthy`
Entity/DbContext modeling (the 42 entities, configurations, enums) is specified in `10-BACKEND-PHASE1.md`. Do not invent the schema here — follow that file.
---
## 6. Running the frontend
The Frontend is already initialized. Point it at the backend:
```bash
cd Frontend
cp .env.local.example .env.local # set NEXT_PUBLIC_API_BASE_URL=https://localhost:<port>
npm install
npm run dev
```
All frontend work is governed by `20-FRONTEND.md`.
---
## 7. Routing — where to go next
**Every task starts here, then jumps to the right doc.** Do not work from memory; open the target doc.
| If you are working on… | Go to |
|---|---|
| Requirements, business rules, entities, ER model, data types, architecture detail (Phase 1: Inventory & Supply Chain) | **`10-BACKEND-PHASE1.md`** |
| API endpoints, request/response shapes, error catalog, enums (Phase 1) | **`11-BACKEND-PHASE1.md`** |
| HRM requirements, business rules, entities, ER model (Phase 2) | **`12-BACKEND-HRM.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`** |
| 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`** |
| Manufacturing frontend user-flows — template canvas, run board, run execution (Phase 2) | **`21-FRONTEND-PHASE2.md`** |
| Security risks per feature, accepted-risk register, pre-ship checklist | **`02-SECURITY.md`** |
| Understanding the doc system, reading order, tracking conventions | **`01-DOC-GUIDE.md`** |
| Recording backend changes made | **`Backend/PROGRESS.md`** |
| Recording frontend changes made | **`Frontend/PROGRESS.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).
- *"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`.
---
## 8. Progress tracking (mandatory)
Two checklists track what has actually been built, and travel with code via git:
- **`Backend/PROGRESS.md`** — backend changes
- **`Frontend/PROGRESS.md`** — frontend changes
These are **Claude-maintained**: whenever a change is made on either side, the corresponding `PROGRESS.md` must be updated (tick items, add entries). The format and rules for these files are defined in **`01-DOC-GUIDE.md` §Tracking**. Both files must exist before feature work begins.
> **Security gate:** before ticking any data-mutating feature `[x]`, run its checklist in **`02-SECURITY.md`** (Part C) plus the foundational controls (Part B). Accepted Phase-1 exposures are recorded in `02-SECURITY.md` Part A — do not "fix" them ad-hoc.
---
## 9. Documentation maintenance rule
There is **one source of truth** per topic. The SRS and API content live **inside** the docs above (not in separate scattered files). When a requirement or endpoint changes, edit it **in place** in `10-`/`11-BACKEND-PHASE1.md` — do not fork copies. See `01-DOC-GUIDE.md` for the full maintenance and navigation rules.
---
*End of 00-CORE.md — the hub. Next: `01-DOC-GUIDE.md`.*