Files
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

18 KiB

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 --version10.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

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

# 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.

# 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:

<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):

{
  "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):

{
  "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):

{
  "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)

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

# 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>/healthHealthy

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:

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.