EchoTex_Payroll/CLAUDE.md

4.2 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

EchoTex HR & Payroll: an ASP.NET Core (.NET 8) Web API that hosts an Angular 13 SPA, backed by SQL Server through a hand-written ADO.NET data layer (no EF). Solution file: EchoTex.sln. Main branch for PRs is devqc; developers work on dev_<name> branches.

Commands

Backend (from repo root):

  • Build everything: dotnet build EchoTex.sln. DatabaseComparison is a legacy .NET Framework 4.6.1 WinForms project, so it may need Visual Studio/MSBuild. Build HRM.UI/HRM.UI.csproj directly to skip it.
  • Run API + SPA: dotnet run --project HRM.UI. In Development, Startup calls spa.UseAngularCliServer(npmScript: "start"), which runs ng serve from HRM.UI/ClientApp automatically.

Frontend (from HRM.UI/ClientApp):

  • npm install (Kendo UI license file: kendo-ui-license.txt)
  • npm start (ng serve), npm run build, npm run lint (tslint), npm test (Karma)

The solution has no .NET test projects.

Architecture

Layered projects, with dependencies flowing downward:

  • Ease.Core: framework code. DataAccess/ (TransactionContext, DataReader, SQLParser.MakeSQL, DbConfig/ConnectionFactory for SQL/Oracle) and Model/ (ServiceTemplate, ObjectTemplate).
  • HRM.BO: business objects grouped by domain folder (Leave, Salary, Tax, PF, Attendance…). Each domain file holds the entity classes (usually derived from AuditTrailBase / BasicBaseObject) and its service interface, e.g. ILeaveEntryService is defined at the bottom of HRM.BO/Leave/LeaveEntry.cs.
  • HRM.DA: two halves.
    • DA/<Domain>/*DA.cs: static internal classes that build raw SQL strings with SQLParser.MakeSQL(...) and run them against a TransactionContext.
    • Service/<Domain>/*Service.cs: implement the BO interfaces and inherit ServiceTemplate. Each public method follows the same pattern: tc = TransactionContext.Begin(...), call the DA, map rows with DataReader in a private MapObject, tc.End(), and tc.HandleError() in the catch block. Overloads that take an existing TransactionContext tc let one transaction span several services.
  • HRM.Report: RDLC report generation (RDLC/, typed DataSets, ReportProcessor.cs).
  • HRM.UI: the API host.
    • Controllers/<Area>/: [ApiController] with [Route("api/<Area>")]. Each action wraps its body in try/catch and returns StatusCode(500, e.Message) on failure. Get the logged-in user from the JWT with CurrentUser.GetCurrentUser(HttpContext.User).
    • Configurations/DI/ServiceCollectionExtensions.cs: every service interface→implementation pair must be registered here (AddTransient). A new service will not resolve until it is added.
    • Configurations/AutoMapper: mappings, registered by services.ConfigureMappings().
    • appsettings.json → AppSettings: DefaultDB names the connection entry in DbConfig, whose key is encrypted. The same file also holds JWT, email, and OpenAI settings.
  • HRM.AttendanceAutoProcess (console) and HRM.MailNotificationProcess (WinForms, net8.0-windows): standalone background jobs that reuse BO/DA.
  • Erecruitment.UI: a separate web app for e-recruitment.

Adding a feature end-to-end

  1. Add the entity and interface in HRM.BO/<Domain>.
  2. Add the SQL in HRM.DA/DA/<Domain>/XxxDA.cs.
  3. Add the service in HRM.DA/Service/<Domain>.
  4. Register it in ServiceCollectionExtensions.
  5. Add the controller action.
  6. Add the Angular service method and component.

Angular client (HRM.UI/ClientApp/src/app)

  • Feature modules are lazy-loaded from app.routes.ts (e.g. leave/leave.module).
  • HTTP calls go through per-domain services in _services/<domain>/. These wrap ApiService (app.api.service.ts) and call relative paths such as this.apiService.httpGet('/Leave/getWeeklyHoliday').
  • ApiService holds base_url, versionNumber, and the current payroll type/user type. The commented-out base_url values are per-client deployment paths.
  • UI components come from Kendo UI for Angular and PrimeNG-style layout components (app.main, app.menu, app.topbar). Models live in _models/.
  • Auth uses JWT (@auth0/angular-jwt), with optional Azure AD via MSAL. Route guards are in _guards/.