# 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_` 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//*DA.cs`: static internal classes that build raw SQL strings with `SQLParser.MakeSQL(...)` and run them against a `TransactionContext`. - `Service//*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//`: `[ApiController]` with `[Route("api/")]`. 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/`. 2. Add the SQL in `HRM.DA/DA//XxxDA.cs`. 3. Add the service in `HRM.DA/Service/`. 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//`. 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/`.