76 lines
3.4 KiB
Markdown
76 lines
3.4 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Build & Run
|
|
|
|
```bash
|
|
dotnet build BMA.EHR.Recruit.Service.sln
|
|
dotnet build BMA.EHR.Recruit.Service.sln -c Release
|
|
dotnet publish -c Release -o /app/publish /p:UseAppHost=false
|
|
```
|
|
|
|
No test projects exist in this solution.
|
|
|
|
## Architecture
|
|
|
|
**Stack:** ASP.NET Core 7.0 Web API / EF Core 7.0 / MySQL (Pomelo) / MinIO (S3) / Keycloak (JWT)
|
|
|
|
**Pattern:** Controllers → Services → EF Core DbContext (no repository layer for main data)
|
|
|
|
### Multiple DbContexts
|
|
Three separate MySQL databases, each with its own `DbContext`:
|
|
- `ApplicationDbContext` — Recruitment data (Recruits, Scores, Imports)
|
|
- `OrgDbContext` — Organization data
|
|
- `MetadataDbContext` — Metadata
|
|
|
|
All registered as `Transient` lifetime. Auto-migration runs on startup.
|
|
|
|
### Controllers
|
|
- `BaseController` provides standardized `Success()` / `Error()` response methods returning `ResponseObject` (Status, Message, Result)
|
|
- `RecruitController` is the sole business controller (route: `api/v{version}/recruit`)
|
|
- API versioning enabled via `Microsoft.AspNetCore.Mvc.Versioning`
|
|
|
|
### Background Import System
|
|
Excel file imports run asynchronously through a Channel-based queue:
|
|
- `ImportBackgroundService` (BackgroundService) — dequeues and processes jobs
|
|
- `ImportJobQueue` — bounded Channel (capacity 100)
|
|
- `ImportJobTracker` — in-memory ConcurrentDictionary tracking
|
|
|
|
Four import types: `CandidateFile`, `CandidateFileById`, `ScoreFile`, `ResultFile`
|
|
|
|
All imports use `EFCore.BulkExtensions.MySql` (v6.7.16) for bulk operations to handle 50,000+ rows without memory issues. Pattern:
|
|
1. Insert parent/history entities via `SaveChangesAsync` (small operations)
|
|
2. `ChangeTracker.Clear()` to release references
|
|
3. Collect entities into separate `List<T>` per table
|
|
4. `BulkInsertAsync` with `SetOutputIdentity = true` for parent entities
|
|
5. Assign generated Ids to child entities
|
|
6. `BulkInsertAsync` for each child entity table separately
|
|
7. Batch size: 500
|
|
|
|
### Entity Models
|
|
All entities inherit from `EntityBase` (Guid `Id` PK, audit fields: `CreatedAt`, `CreatedUserId`, `LastUpdatedAt`, etc.). Models are in `Models/` with subdirectories: `Recruits/`, `Documents/`, `HR/`, `MetaData/`, `Placement/`.
|
|
|
|
Key relationships use navigation properties without explicit FK properties (EF shadow properties). Configured via fluent API in `OnModelCreating`.
|
|
|
|
### External Services
|
|
- **Authentication:** Keycloak JWT Bearer (`hrmsbkk-id.case-collection.com/realms/hrms`)
|
|
- **File Storage:** MinIO via `MinIOService` (AWS S3 SDK)
|
|
- **Search/Logging:** Elasticsearch (NEST client)
|
|
- **Excel:** EPPlus for reading import files
|
|
|
|
## Key Files
|
|
|
|
- `Program.cs` — Service registration, middleware pipeline, auto-migration
|
|
- `Data/ApplicationDbContext.cs` — EF Core fluent API relationship configuration
|
|
- `Services/ImportBackgroundService.cs` — All bulk import logic (4 import methods)
|
|
- `Services/RecruitService.cs` — Core business logic
|
|
- `Controllers/BaseController.cs` — Standard response helpers
|
|
- `Responses/ResponseObject.cs` — Standard API response envelope
|
|
|
|
## Conventions
|
|
|
|
- Language: C# with nullable reference types enabled
|
|
- Naming: PascalCase properties, `_camelCase` parameters in service methods
|
|
- API responses: Always wrapped in `ResponseObject`
|
|
- Authorization: `[Authorize]` on controllers, user context from JWT claims
|