7.7 KiB
General Ledger Service — Project Specification
This is an early-stage ASP.NET Core Web API (.NET 10) microservice, scaffolded as part of a larger multi-service ERP system (JWT issuer is ERPCore, audience ERPCore.Clients, suggesting this service authenticates against a shared identity provider). Only the foundational skeleton exists — domain models, repositories, and business logic are not yet implemented (several folders are empty placeholders).
1. Project root
| File | Purpose |
|---|---|
General-Ledgar-Service.csproj |
SDK-style project file targeting net10.0, Nullable/ImplicitUsings enabled, root namespace General_Ledger_Service. Declares empty placeholder folders (Interfaces/Repositories, Interfaces/Services, Models, Repositories, Services) that are referenced but not yet populated. |
Program.cs |
Application entry point and DI/middleware composition root (detailed below). |
General-Ledgar-Service.slnx |
Visual Studio solution file (new XML-based .slnx format). |
appsettings.json / appsettings.Development.json / appsettings.Production.json |
Environment-layered configuration. appsettings.json holds only settings common to every environment (logging, Kestrel URL, allowed hosts, JWT issuer/audience/token lifetime). appsettings.Development.json holds development-only values (local MySQL connection string, JWT signing key, API key, demo company details); appsettings.Production.json holds production-only values, currently blank/placeholder secrets meant to be filled via environment variables/secret store at deploy time. |
General_Ledger_Service.http |
VS/Rider .http scratch file for manual endpoint testing (still has the default weatherforecast template call — not yet updated for this service's real routes). |
.gitignore |
Standard .NET ignore rules. |
2. Program.cs — composition root
Configures, in order:
- MVC controllers (
AddControllers) - Swagger/OpenAPI (dev-only UI)
- EF Core + MySQL via
Pomelo.EntityFrameworkCore.MySql, readingConnectionStrings:DefaultConnection - Unit of Work —
IUnitOfWork→EFUnitOfWorkregistered as scoped - Health checks —
/healthendpoint backed by a DbContext check - JWT Bearer authentication — conditionally wired up only if a
Jwt:SigningKeyis configured; validates issuer, audience, lifetime, and signing key - Authorization, HTTPS redirection, and controller routing
This is a fairly standard, clean ASP.NET Core startup — no custom middleware or exception-handling pipeline registered yet (the custom exception types in Exceptions/ aren't currently caught by any global handler).
3. Controllers/
Purpose: HTTP API surface (thin layer, delegates to services once they exist).
GeneralLedgerController.cs— currently only exposesGET /api/GeneralLedger/status, a liveness/status probe returning service name, status, and UTC timestamp. This is a placeholder; no ledger domain endpoints (accounts, journal entries, postings, trial balance, etc.) exist yet.
4. AppDBContext.cs (root-level, namespace General_Ledger_Service.Infra)
Purpose: EF Core DbContext. Currently has no DbSet<T> properties or entity configuration — a bare shell awaiting the domain model (accounts, journal entries, ledger lines, periods, etc.).
5. Infra/UoW/ — Unit of Work pattern
Purpose: Wraps EF Core's SaveChanges/transaction lifecycle behind an abstraction so services aren't coupled directly to DbContext.
IUnitOfWork.cs— contract:BeginAsync,CommitAsync,RollbackAsync,SaveChangesAsync.EFUnitOfWork.cs— EF Core implementation; manages anIDbContextTransaction, commits both the transaction and pending changes together, supports rollback/dispose cleanup.
6. DTOs/Common/
Purpose: Shared response envelope used by every endpoint in this service.
ApiResponse.cs— generic envelope (StatusCode,Success,Message,Data). Renamed fromAuthResponse/DTOs/Auth/(2026-07-19) since this service does not perform authentication/authorization itself — the name no longer implied that.
7. Exceptions/
Purpose: Domain-level custom exceptions for consistent HTTP-status-mapped error handling.
CustomExceptions.cs—NotFoundException,BadRequestException,UnauthorizedException,ForbiddenException. Not yet wired to a global exception-handling middleware/filter, so today they'd surface as unhandled 500s unless caught locally.
8. Helpers/
Purpose: Cross-cutting utility code.
DataExtractor.cs— a large, defensive helper for pulling typed values (string,int,float,decimal,bool,Guid,DateTime,DateOnly) out of aDictionary<string, JsonElement>payload, with required/optional/multi-key variants that throwBadRequestExceptionon invalid input. Also hasGetUserIdFromContext(reads aUserIdclaim/HttpContext item, throws if missing/unauthenticated) andGetRequiredApiResponse(builds anApiResponsefrom raw payload data). This is the backbone for manually parsing loosely-typed JSON request bodies rather than relying purely on strongly-typed model binding.DeserializePayload.cs— round-trips an arbitrary object throughJsonSerializerinto aDictionary<string, JsonElement>(for use withDataExtractor), plus a safe genericDeserializeJson<T>that swallows exceptions and returnsnullon failure.EncryptionHelper.cs— AES encrypt/decrypt using a hardcoded 256-bit key embedded in source, IV prepended to ciphertext and base64-encoded. ⚠️ Worth flagging: a hardcoded symmetric key in source control is a real security concern for anything beyond a placeholder/dev stub — it should move to configuration/secrets before this handles real data.
9. Empty placeholder folders (declared in .csproj, not yet populated)
Interfaces/Repositories/,Interfaces/Services/,Models/,Repositories/,Services/— the intended layering (Controller → Service → Repository → DbContext, with a Unit of Work spanning repositories) is scaffolded structurally but has no files yet.
10. Build output (bin/, obj/, .vs/)
Standard generated/IDE artifacts — not source, ignored by git, no need to document further.
Package references (.csproj)
| Package | Version | Purpose |
|---|---|---|
ClosedXML |
0.105.0 | Reading/writing .xlsx files (likely for ledger import/export to Excel) |
Microsoft.EntityFrameworkCore |
10.0.9 | Core ORM |
Microsoft.EntityFrameworkCore.Design |
10.0.9 | Design-time tooling (migrations scaffolding) |
Microsoft.EntityFrameworkCore.Tools |
10.0.9 | Package Manager Console / CLI tooling for migrations |
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore |
10.0.9 | Backs the /health DbContext check |
Pomelo.EntityFrameworkCore.MySql |
9.0.0 | MySQL provider for EF Core (EF Core packages are pinned to 9.0.9 to match) |
QuestPDF |
2026.7.1 | PDF generation (likely ledger/financial statement output) |
Serilog.AspNetCore |
10.0.0 | Structured logging integration |
Serilog.Sinks.File |
7.0.0 | File sink for Serilog |
Swashbuckle.AspNetCore |
10.2.3 | Swagger/OpenAPI generation |
Overall assessment
This is a bootstrap/scaffold commit (git log shows only "Initial project setup") for a General Ledger microservice within a larger ERP suite. The architecture direction is clear — layered (Controllers → Services → Repositories), Unit-of-Work-mediated persistence, JWT auth against a shared ERPCore identity issuer, PostgreSQL storage, PDF generation capability reserved — but no actual ledger domain logic (chart of accounts, journal entries, double-entry postings, trial balance, period close, etc.) has been built yet.