hrms-api-recruit/CLAUDE.md
Suphonchai Phoonsawat 0f1ec072ad
All checks were successful
Build & Deploy on Dev / build (push) Successful in 52s
change logic
2026-05-13 07:00:22 +07:00

3.4 KiB

CLAUDE.md

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

Build & Run

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