Aller au contenu

Core HR (HRCORE) — PRD+FSD Hybrid

Module Code: HRCORE Product: [BOTH] (Papillon HR Suite + ALTARYS ENTERPRISE HR Suite) Country Scope: CI (Côte d'Ivoire) — MVP Version: 1.0 Date: 01/03/2026 Author: ANALYST (Claude Code) Input documents: - docs/prd/platform-vision-prd.md (Platform Vision PRD) - docs/specs/platform-vision.md (Tier 1 human-written spec) - docs/research/3_validated/core-hr-legal-validated.md (legal research — validated) - docs/research/2_audit/core-hr-legal-audit.md (legal audit — gaps)


PART A — Product Requirements (PRD)


A.1 Executive Summary

The Problem

Businesses in Côte d'Ivoire must maintain a dossier du personnel (employee file) for every employee, per the Code du Travail 2015 (Loi n°2015-532) and the employer register obligations. Most SMEs manage this with paper folders, Excel spreadsheets, or WhatsApp photos of documents. This creates:

  • Compliance risk: Missing mandatory documents (medical certificates, CNPS attestations, identity copies) discovered only during labor inspections.
  • Data fragility: Employee files scattered across physical folders, USB drives, and multiple Excel files — no single source of truth.
  • Operational inefficiency: HR managers spend hours searching for employee information, manually generating registers, and responding to employee requests for certificates or profile information.
  • Privacy risk: Sensitive personal data (national ID numbers, bank information, medical records) stored in unprotected files without audit trails or access controls.

The Solution

Core HR (HRCORE) is the enriched employee data layer that transforms the Control Plane's baseline employee record into a complete, compliant, and searchable dossier du personnel. It is:

  • A data enrichment module: Layer 2 on top of the Control Plane's baseline employee entity (Layer 1). It adds personal data, bank information, emergency contacts, photos, documents, and dependents management.
  • NOT a process module: Contract lifecycle management, onboarding/offboarding workflows, administrative events, declarations, trial period tracking, and termination procedures belong to Employee Management (EMPMGT). Core HR is the data, EMPMGT is the process.
  • An optional sellable module: Tenants without Core HR use the Control Plane baseline, which is sufficient for Absence, Attendance, and Payroll. Core HR enriches the employee record for compliance, reporting, and a richer user experience.

Module Position in the Platform

Control Plane (Layer 1 — always present)
  └── Baseline employee: last_name, first_name, email, phone,
      employee_number, contract_type, org_unit, position,
      category, hire_date, status, preferred_contact
      ↓ Sufficient for Absence, Attendance, Payroll

Core HR (Layer 2 — optional, sellable)
  └── Enriched employee: date_of_birth, nationality, national_id,
      cnps_number, marital_status, dependents[], bank_info,
      emergency_contacts[], photo, documents[], address,
      gender, blood_type, place_of_birth, parents, qualifications,
      previous_employer, change_history_view
      ↓ Complete "dossier du personnel"

Employee Management (Layer 3 — optional, sellable)
  └── Process layer: onboarding, offboarding, contract lifecycle,
      trial period tracking, administrative events, declarations
      ↓ "Actes administratifs"

Key Correction from Platform Vision

⚠️ CORRECTION: The Platform Vision PRD Layer 1 defines full_name as a single field. This PRD corrects this to last_name + first_name as separate fields at the Control Plane level. full_name becomes a computed display value. This is a fundamental data modeling correction — West African naming conventions require separate name fields for: - Legal documents (registre du personnel, CNPS declarations) - Formal display conventions (NOM Prénoms format: KOUASSI Jean-Pierre) - Search (search by last name or first name independently)

This correction must be propagated to the Control Plane PRD.


A.2 User Personas

P2: Responsable RH / HR Manager — [BOTH]

  • Primary user of Core HR
  • Uses: Creates and enriches employee profiles, manages documents, generates registre du personnel, manages bank info, responds to employee data requests
  • Key concern: "Complete employee files, find information quickly, be ready for inspections."
  • Papillon context: Often a single person (DG's spouse, trusted assistant) managing 5-50 employee files. Transitioning from paper/Excel. Needs simplicity and guidance — e.g., visual indicators of which employee files are incomplete.
  • Enterprise context: Professional HR officer managing hundreds of profiles. Needs bulk operations and efficient data entry. (Note: Core HR is [BOTH] with no brand differentiation for V1.)

P1: Directeur Général (DG) / CEO — [BOTH]

  • Secondary user
  • Uses: Views employee profiles, approves nothing in Core HR (approval workflows are in EMPMGT), accesses dashboards and statistics
  • Papillon context: In very small businesses (S1-S2), the DG IS the HR Manager — same person wearing both hats.

P4: Employé / Employee — [BOTH]

  • Self-service user
  • Uses: Views own profile (enriched when HR Core is active), updates personal contact info (phone, email, address), manages emergency contacts, uploads/updates photo
  • Key concern: "See my information, update my phone number, check that my CNPS number is correct."
  • Papillon context: Low digital literacy, Android phone, intermittent connectivity. Needs absolute simplicity.

P3: Comptable / Accountant — [BOTH]

  • Read-only financial user
  • Uses: Reads employee financial data (bank info, employee category) for payroll/accounting reconciliation
  • Key concern: "Verify bank details match payroll records."
  • Does NOT: Edit employee profiles, access personal data (national ID, medical docs)

P-MGR: Manager (N+1) — [BOTH]

  • Read-only team user
  • Uses: Views profiles of direct reports (employees in their org unit). Read-only access.
  • Key concern: "Know my team members' key information without going through HR."

A.3 User Stories

US-HRCORE-001: Enriched Employee Profile [BOTH]

As an HR Manager, I want to enrich an employee's profile with personal data, emergency contacts, bank information, photo, and documents, So that I maintain a complete and compliant dossier du personnel.

Acceptance Criteria: - Given I have HRCORE module active and HR Manager role, When I open an employee's profile, Then I see all Layer 2 fields available for editing. - Given I fill in all mandatory HR Core fields, When I save the profile, Then the system logs the changes in the audit trail and publishes an EmployeeUpdated event. - Given I leave the CNPS number field empty, When I save, Then the system saves successfully but creates a persistent alert reminding me to register the employee with CNPS.

US-HRCORE-002: Employee Self-Service Profile View [BOTH]

As an employee, I want to view my complete profile (personal data, bank info summary, emergency contacts, documents), So that I can verify my information is correct and up to date.

Acceptance Criteria: - Given I am an employee with an active account and HR Core is active for my tenant, When I navigate to "Mon Profil", Then I see my enriched profile with all Layer 2 data. - Given I view my bank info, Then I see only the last 4 digits of my account number (masked display). - Given I am offline, When I view my profile, Then I see the cached version from my last online access.

US-HRCORE-003: Employee Self-Service Edit [BOTH]

As an employee, I want to update my phone number, personal email, address, emergency contacts, and photo, So that my information stays current without waiting for HR.

Acceptance Criteria: - Given I am an employee, When I edit my phone number and save, Then the change takes effect immediately (no approval needed) and an EmployeeUpdated event is published. - Given I am offline, When I edit my address and save, Then the change is queued in IndexedDB and synced when connectivity returns within 30s. - Given I try to edit my national ID number, Then the field is read-only and I see a message: "Contactez les RH pour modifier cette information."

US-HRCORE-004: Bank Info Management [BOTH]

As an HR Manager, I want to manage employee bank account information (bank name, account number, IBAN/RIB), So that Payroll can process salary payments correctly (post-MVP).

Acceptance Criteria: - Given I have HR Manager or DG role, When I update an employee's bank info, Then the change is logged in audit trail and an EmployeeBankInfoChanged event is published. - Given I am an employee, When I try to edit my bank info, Then the field is read-only. - Given I am a Comptable, When I view an employee's bank info, Then I see the full bank details (read-only).

US-HRCORE-005: Document Attachment with Taxonomy [BOTH]

As an HR Manager, I want to attach documents to an employee's profile with structured categories (contract, medical certificate, identity, CNPS attestation, etc.), So that I can organize and find documents easily and track file completeness.

Acceptance Criteria: - Given I upload a document, When I select a category from the dropdown, Then the document is stored in MinIO with the category metadata. - Given the system has seeded categories, When I need a category not in the list, Then I can contact the DG/admin to add a custom category (V1: admin-managed; V2: inline creation). - Given I view an employee's documents tab, When I filter by category, Then I see only documents of that category.

US-HRCORE-006: Fulltext Employee Search [BOTH]

As an HR Manager, I want a single search field that searches across employee names and configurable fields using PostgreSQL fulltext search, So that I can find any employee quickly without navigating complex filter forms.

Acceptance Criteria: - Given I type "Kouassi" in the search field, When I press Enter, Then I see all employees whose last_name or first_name match "Kouassi". - Given I type "Comptabilité" in the search field, When I press Enter, Then I see all employees in the Comptabilité department (department is a default search field). - Given I am a DG/RH Manager, When I go to search configuration, Then I can add or remove fields from the fulltext search index (e.g., add cnps_number or national_id_number).

US-HRCORE-007: Bulk Employee Import [BOTH]

As an HR Manager or DG, I want to bulk-import employees via Excel with HR Core enrichment fields included, So that I can migrate our existing employee data quickly instead of entering profiles one by one.

Acceptance Criteria: - Given HR Core is active, When I download the import template, Then it includes all Layer 1 (CP) fields + Layer 2 (HR Core) enrichment fields. - Given I upload a filled Excel file, When the system parses it, Then I see an editable confirmation table with validation errors highlighted (e.g., duplicate employee numbers, invalid CNPS format). - Given some HR Core fields are left blank in the import, When I submit, Then the employees are created with whatever data is provided — no validation failure on empty optional HR Core fields.

US-HRCORE-008: Registre du Personnel Export (Fascicule 1) [BOTH]

As an HR Manager, I want to export the registre du personnel (Fascicule 1 — personnel data) as a compliant PDF or Excel document, So that I am ready for labor inspections and CNPS audits.

Acceptance Criteria: - Given I click "Exporter Registre du Personnel", When the export is generated, Then it contains all active and terminated employees with the legally required fields (sequential registration number, full name, date of birth, nationality, position, category, hire date, CNPS number, etc.). - Given an employee's CNPS number is missing, When the export is generated, Then the field shows "Non renseigné" and the export includes a warning summary of incomplete records.

US-HRCORE-009: Employee Photo Management [BOTH]

As an HR Manager or Employee (self-service), I want to upload and crop an employee photo for their profile, So that the employee is visually identifiable in the platform and for ID badges.

Acceptance Criteria: - Given I upload a photo, When I reach the crop step, Then I see a crop tool enforcing 3:4 portrait aspect ratio. - Given I confirm the crop, Then the system generates a thumbnail (48px for list views) and a medium version (150px for profile card), stored in MinIO. - Given the photo exceeds 2 MB, When I upload, Then I see an error: "La photo ne doit pas dépasser 2 Mo."

US-HRCORE-010: Dependents Management [BOTH]

As an HR Manager, I want to manage a detailed list of employee dependents (spouse, children, other persons à charge) with their personal information, So that Payroll can correctly calculate tax deductions (ITS) and social contributions (allocations familiales CNPS).

Acceptance Criteria: - Given I add a dependent, When I fill in name, date_of_birth, relationship (conjoint(e), enfant, autre personne à charge), gender, Then the dependent is saved and dependents_count and number_of_children are automatically recomputed. - Given I mark a child dependent as "scolarisé" and attach a school attestation, Then the school_attestation_attached flag is set to true. - Given I delete a dependent, Then the counts are recomputed and the change is logged in the audit trail.

US-HRCORE-011: Change History View [BOTH]

As an HR Manager, I want to see a human-readable timeline of changes made to an employee's profile, So that I can trace who changed what and when for audit and compliance purposes.

Acceptance Criteria: - Given I open an employee's "Historique des modifications" tab, When I view it, Then I see a chronological list of changes with: date, user who made the change, field name (in French), old value, new value. - Given the change history is sourced from the platform audit trail (AuditEntry), When I view it, Then the raw audit data is translated into a user-friendly French format.

US-HRCORE-012: Missing Data Alerts [BOTH]

As an HR Manager, I want the system to alert me when employee profiles are missing critical information (CNPS number, medical certificate, identity document), So that I can proactively complete files before inspections or audits.

Acceptance Criteria: - Given an employee's CNPS number is empty, When I view the HR dashboard or the employee list, Then I see a persistent alert badge. - Given the alert has been active for 30+ days, When I view the dashboard, Then the alert is escalated (highlighted in red). - Given I fill in the missing CNPS number, Then the alert is automatically dismissed.


A.4 Non-Functional Requirements

Requirement Target Notes
Profile load time < 1.5 seconds on 3G connection Employee profile page (all tabs)
Search response time < 500ms for fulltext search with up to 350 employees PostgreSQL FTS must be indexed
Bulk import Process 500 employees in < 30 seconds Background job with progress indicator
Photo upload < 3 seconds (upload + crop + thumbnail generation) Client-side crop, server-side thumbnail
Registre export < 10 seconds for 350 employees Background generation with download link
Offline profile view Available within 200ms from IndexedDB Cached on first online view
Concurrent profile edits Online-only for HR Manager edits → no conflict risk Self-service edits offline → single-editor (the employee), no conflict
Document storage Per-tenant MinIO bucket, subject to segment storage quotas (S1-S6) Follows Platform Vision §A.8 storage quotas
Audit trail Every create/update/delete on employee data produces immutable AuditEntry Platform-wide requirement (FR-PV-090-091)

A.5 MVP Scope (Core HR V1)

In V1 (First Release of Core HR)

  • Enriched employee profile (all Layer 2 fields per §B.1)
  • Detailed dependents list (name, DOB, relationship, gender, school attestation)
  • Emergency contacts (1-2 per employee)
  • Employee photo (upload + client-side crop + thumbnail generation)
  • Bank info management (HR-only write, masked employee view, full Comptable read)
  • Document attachment with structured taxonomy (system-seeded + admin-custom categories)
  • Employee self-service profile view (enriched when HR Core active)
  • Employee self-service minimal edit (phone, personal email, address, emergency contacts, photo)
  • Single fulltext search field (PostgreSQL FTS, configurable search fields)
  • Bulk employee import (dynamic template including HR Core fields)
  • Registre du personnel Fascicule 1 export (PDF/Excel)
  • Formatted change history (UI view on platform audit trail)
  • Employee number auto-generation ({PREFIX}-{YEAR}-{MM}-{SEQ})
  • Missing data alerts (CNPS number, mandatory documents)
  • Permission matrix: DG/RH full, Manager read team, Comptable financial read, Employé self-service

Out of V1 — Core HR V2 (Future Enhancements)

  • Custom employee fields (tenant-defined additional fields beyond standard schema)
  • Employee data export to Excel/CSV with column selection
  • Advanced photo management (bulk photo upload, photo directory generation)
  • Employee self-service: request profile changes with approval workflow (submit bank info change → HR approves)
  • Mobile payment methods (Orange Money, MTN MoMo, Wave) as first-class payment options alongside bank accounts
  • Employee organigramme (visual org chart)
  • Employee directory (company-wide searchable employee directory)
  • Integration with government portals (CNPS online, e-impôts CI)
  • Multi-country expansion (BJ, CM country-specific fields and registers)
  • Custom retention policies per document category (requires ADVDOC)

A.6 Open Questions

# Question Priority Status
OQ-HRCORE-01 CI data privacy (Loi n°2013-450): Core HR stores the most sensitive employee data (national ID, bank info, medical certificates, marital status). What are the specific obligations for collecting, storing, and processing this data? What consent is required from employees? Does the employer need to register data processing with ARTCI? 🔴 CRITICAL Unresolved — deferred from Platform Vision OQ-01. Requires targeted legal research on Loi 2013-450 as it applies to employer HR data processing.
OQ-HRCORE-02 CCI 1977 current status: Employee categories (Cadre, Agent de maîtrise, Employé, Ouvrier) are sourced from the CCI 1977. Has this convention been revised or superseded? If so, category names and definitions may have changed. 🟡 HIGH Unresolved. Using CCI 1977 categories as default. See TV-HRCORE-01.
OQ-HRCORE-03 Délégué du personnel threshold (CI): At what headcount are CI employers required to have délégués du personnel? Affects SME workflows (Papillon target: 2-350 employees). Many tenants will be below or near this threshold. 🟡 HIGH Unresolved. Flagged in legal audit CHECK 4 + CHECK 5 gap #3. Relevant for EMPMGT more than Core HR, but the threshold affects the employee count dashboard Core HR might display.
OQ-HRCORE-04 Record retention: statutory basis: 10-year retention adopted (aligned with OHADA AUDCIF for simplicity). But no explicit CI statutory basis found for employee personal data retention specifically. The 5-year inference (statute of limitations + CNPS audits) is from the legal research. Needs confirmation. 🟢 MEDIUM Temporarily validated at 10 years. See TV-HRCORE-02.
OQ-HRCORE-05 CNPS number format validation: What is the exact format of a CI CNPS registration number? How many digits/characters? Is there a check digit? The system should validate format on input. 🟢 MEDIUM Unresolved. Implement as free-text with optional regex validation when format is confirmed.
OQ-HRCORE-06 Medical fitness certificate requirements: When must a certificate be obtained (pre-employment? periodic?)? By whom? At what frequency? Cost borne by employer? Affects document completeness checks. 🟢 MEDIUM Unresolved. Flagged in legal audit CHECK 5 gap #13. Core HR should track the document, but frequency/renewal logic may belong to HSE module.
OQ-HRCORE-07 Registre d'employeur: mandatory for all sizes?: Is the 3-fascicule employer register mandatory for all employers regardless of size, including a sole employee? Affects the registre export feature's applicability. 🟢 MEDIUM Unresolved. Flagged in legal audit CHECK 4. Assumed mandatory for all for Core HR V1.

A.7 Temporarily Validated

# Item Current Value Risk Action Required
TV-HRCORE-01 Employee categories (CCI 1977) System seeds: Cadre, Cadre supérieur, Agent de maîtrise, Employé/Technicien, Ouvrier. Sourced from CCI 1977. CCI may have been revised. Categories and their definitions may have changed. Verify CCI 1977 current status. If updated, adjust seeded categories.
TV-HRCORE-02 Employee data retention period 10 years after termination (aligned with OHADA AUDCIF payroll/accounting retention). No explicit CI statutory basis for employee personal data specifically. May be over-retaining personal data, which could conflict with data minimization principles in Loi 2013-450. Confirm with legal counsel whether 10-year retention of personal data (national ID, bank info) is proportionate or if a shorter period with anonymization is required.
TV-HRCORE-03 CI Art. 14.x decimal sub-numbering Legal research citations use decimal sub-numbering (Art. 14.1, 14.2, 14.4, etc.) for the Code du Travail 2015. This numbering format has not been verified against a physical/digital copy of the law. Could be a Perplexity artifact. One-time verification: check the actual CI Code du Travail 2015 to confirm article numbering format. If confirmed, all citations are trustworthy.

PART B — Functional Specifications (FSD)


B.1 Data Model — Employee Enrichment (Layer 2)

Employee Enrichment Fields (Core HR adds to CP baseline)

Field Type Mandatory? Editable by Employee? Notes
last_name VARCHAR(100) YES NO CP correction: replaces full_name.
first_name VARCHAR(150) YES NO May contain multiple first names (common in CI: "Jean-Pierre Koffi")
date_of_birth DATE YES NO Format DD/MM/YYYY
place_of_birth VARCHAR(200) NO NO Lieu de naissance — common on CI administrative forms
gender ENUM(MALE, FEMALE) YES NO
nationality VARCHAR(100) YES NO Default: Ivoirienne
national_id_number VARCHAR(50) NO NO CNI or Passeport number
national_id_type ENUM(CNI, PASSPORT, TITRE_SEJOUR, OTHER) NO NO Type of identity document
cnps_registration_number VARCHAR(30) NO (with alert) NO Optional at creation, persistent alert if missing. See FR-HRCORE-020.
tax_id VARCHAR(50) NO NO Personal tax identifier (if applicable)
marital_status ENUM(CELIBATAIRE, MARIE, DIVORCE, VEUF, UNION_LIBRE) NO NO Affects tax deductions
blood_type ENUM(A_POS, A_NEG, B_POS, B_NEG, AB_POS, AB_NEG, O_POS, O_NEG, UNKNOWN) NO NO Emergency medical information
father_name VARCHAR(200) NO NO Common on CI administrative documents
mother_name VARCHAR(200) NO NO Common on CI administrative documents
professional_qualifications TEXT NO NO Diplomas, certifications (free text for V1)
previous_employer VARCHAR(200) NO NO For transfer/seniority calculations
previous_employer_exit_date DATE NO NO For seniority continuity calculations

Address Fields (Semi-Structured)

Field Type Mandatory? Editable by Employee? Notes
address_city VARCHAR(100) NO YES Dropdown with major CI cities + free text option
address_commune VARCHAR(150) NO YES Commune / Quartier (free text)
address_details VARCHAR(500) NO YES Street, landmark, building (free text)

Bank Info Fields

Field Type Mandatory? Editable by Employee? Notes
bank_name VARCHAR(100) NO NO HR-only management
bank_account_number VARCHAR(50) NO NO Masked display for employee (last 4 digits)
bank_iban VARCHAR(50) NO NO International Bank Account Number (if applicable)
bank_rib_key VARCHAR(10) NO NO RIB key (specific to UEMOA banking)
bank_branch_code VARCHAR(20) NO NO Code agence

Contact Fields (Employee Self-Editable)

Field Type Mandatory? Editable by Employee? Notes
personal_email VARCHAR(255) NO YES Distinct from work email (in CP)
personal_phone VARCHAR(20) NO YES Distinct from work phone (in CP)

Photo

Field Type Notes
photo_original_key VARCHAR(500) MinIO object key for original photo
photo_medium_key VARCHAR(500) 150px version
photo_thumbnail_key VARCHAR(500) 48px version

B.2 Sub-Entities

Emergency Contact

Field Type Mandatory? Notes
id UUID
employee_id FK YES
tenant_id FK YES Multi-tenant scoping
full_name VARCHAR(200) YES
relationship ENUM(CONJOINT, PERE, MERE, FRERE_SOEUR, ENFANT, AUTRE) YES Dropdown
phone_number VARCHAR(20) YES Primary phone
phone_number_2 VARCHAR(20) NO Secondary phone
priority_order SMALLINT YES 1 or 2

Constraint: Minimum 0, maximum 2 emergency contacts per employee.

Dependent

Field Type Mandatory? Notes
id UUID
employee_id FK YES
tenant_id FK YES Multi-tenant scoping
full_name VARCHAR(200) YES
date_of_birth DATE YES Used for age-based benefit calculations
relationship ENUM(CONJOINT, ENFANT, AUTRE_PERSONNE_A_CHARGE) YES
gender ENUM(MALE, FEMALE) NO
is_school_enrolled BOOLEAN NO Default: false. For children — affects allocations familiales
school_attestation_attached BOOLEAN NO Default: false. Document tracked via document attachment

Computed fields (from dependents list): - dependents_count = COUNT(dependents) - number_of_children = COUNT(dependents WHERE relationship = ENFANT)

Document Attachment

Field Type Mandatory? Notes
id UUID
employee_id FK YES
tenant_id FK YES Multi-tenant scoping
category_code VARCHAR(50) YES FK to document category reference table
file_name VARCHAR(255) YES Original file name
minio_object_key VARCHAR(500) YES MinIO storage key
file_size_bytes BIGINT YES For storage quota tracking
mime_type VARCHAR(100) YES
uploaded_by FK (User) YES
uploaded_at TIMESTAMP YES
description VARCHAR(500) NO Optional note about the document

Document Category (Reference Table)

Field Type Notes
code VARCHAR(50) PK e.g., CONTRAT, MEDICAL_CERT, IDENTITY, CNPS_ATTESTATION
tenant_id FK (nullable) NULL = system-seeded (shared). Non-null = tenant-custom.
display_name_fr VARCHAR(100) French label
sort_order SMALLINT Display ordering
is_system BOOLEAN true = cannot be deleted/modified by tenant

System-seeded categories (CI):

Code Display Name (FR) Notes
CONTRAT_TRAVAIL Contrat de travail
AVENANT Avenant au contrat
CERTIFICAT_MEDICAL Certificat médical d'aptitude
PIECE_IDENTITE Pièce d'identité (CNI/Passeport)
ATTESTATION_CNPS Attestation CNPS
CERTIFICAT_TRAVAIL Certificat de travail Issued at departure
DIPLOMES Diplômes et qualifications
RIB Relevé d'Identité Bancaire
BULLETIN_PAIE Bulletin de paie Payroll will auto-attach if HRCORE active
ATTESTATION_SCOLAIRE Attestation de scolarité (enfant) For dependent school enrollment
PHOTO_IDENTITE Photo d'identité
AUTRE Autre document Catch-all

Search Configuration

Field Type Notes
id UUID
tenant_id FK One configuration per tenant
search_fields VARCHAR[] (array) List of column names included in fulltext index. Default: ['last_name', 'first_name', 'department_name']
updated_by FK (User)
updated_at TIMESTAMP

Employee Number Configuration

Field Type Notes
tenant_id FK PK One configuration per tenant
prefix VARCHAR(10) Auto-generated from company name (trigram/4-6 letters). Editable by admin.
next_sequence INTEGER Auto-incremented per employee creation. Never decremented.

Format: {prefix}-{YEAR}-{MM}-{SEQ} → Example: ALT-2026-03-001


B.3 Functional Rules

Employee Profile Management

Rule Description
FR-HRCORE-001 IF HR Core module is ACTIVE for a tenant THEN employees in that tenant have access to Layer 2 enrichment fields in addition to the Layer 1 (CP) baseline fields.
FR-HRCORE-002 IF HR Core module is INACTIVE for a tenant THEN only Layer 1 (CP) baseline fields are visible and editable. Layer 2 data, if previously entered, is hidden in the UI (module deactivation sets status to INACTIVE immediately; enriched fields are hidden). MVP behavior — no grace period, no read-only state (those are V2 per FR-PV-040 through FR-PV-044).
FR-HRCORE-003 The employee last_name and first_name fields are separate. The display value full_name is computed as UPPER(last_name) || ' ' || first_name for formal display (e.g., "KOUASSI Jean-Pierre"). This convention follows CI administrative naming standards.
FR-HRCORE-004 All Layer 2 fields are optional at employee creation EXCEPT: date_of_birth, gender, nationality. These are mandatory when HR Core is active because they are required by the registre du personnel.
FR-HRCORE-005 IF an employee record is saved with optional fields left empty THEN the system tracks completeness as a percentage (number of filled fields / total fields). This percentage is displayed on the employee profile and used for missing data alerts (FR-HRCORE-020).

Employee Self-Service

Rule Description
FR-HRCORE-010 Employees can EDIT the following fields on their own profile (self-service): personal_phone, personal_email, address_city, address_commune, address_details, emergency contacts, and photo.
FR-HRCORE-011 Employees CANNOT edit: last_name, first_name, date_of_birth, national_id_number, cnps_registration_number, marital_status, dependents, bank_* fields, gender, nationality, blood_type, father_name, mother_name, professional_qualifications, previous_employer. These require HR Manager or DG action.
FR-HRCORE-012 Employee self-service edits (FR-HRCORE-010 fields) take effect immediately — no approval workflow for V1.
FR-HRCORE-013 Employee self-service edits are available OFFLINE. Changes are queued in IndexedDB and synced within 30s of reconnection. Since each employee can only edit their own profile, there is no conflict risk.
FR-HRCORE-014 HR Manager edits to any employee field require ONLINE connectivity. Offline HR Manager edits are not supported in V1 to prevent concurrent edit conflicts.

Bank Info Security

Rule Description
FR-HRCORE-015 Bank info fields (bank_name, bank_account_number, bank_iban, bank_rib_key, bank_branch_code) can only be CREATED or UPDATED by users with role DG or RH Manager.
FR-HRCORE-016 When an employee views their own bank info, bank_account_number and bank_iban are MASKED: only the last 4 characters are displayed (e.g., "●●●●●●●●4523"). bank_name is displayed in full.
FR-HRCORE-017 Users with role Comptable can view full (unmasked) bank info in READ-ONLY mode. This is necessary for payroll/accounting reconciliation.
FR-HRCORE-018 Every bank info change triggers an EmployeeBankInfoChanged event. This event carries a security_flag: true attribute to enable downstream security monitoring (e.g., detect if someone changes multiple employees' bank info rapidly — potential fraud pattern).
FR-HRCORE-019 Bank info change history is preserved: the system stores previous bank info values in the audit trail. The current bank info is the latest. There is no separate bank info history table — the platform audit trail (AuditEntry with before/after JSON) serves this purpose.

CNPS Number and Alerts

Rule Description
FR-HRCORE-020 IF an employee's cnps_registration_number is NULL or empty THEN the system creates a persistent alert visible to DG and RH Manager users. The alert message: "Numéro CNPS manquant pour {last_name} {first_name} — veuillez procéder à l'immatriculation CNPS et mettre à jour le dossier."
FR-HRCORE-021 The CNPS alert reappears on the HR dashboard MONTHLY until the field is filled. After 30 days without resolution, the alert is escalated (displayed in red/urgent style).
FR-HRCORE-022 IF the cnps_registration_number field is populated THEN the alert is automatically dismissed.
FR-HRCORE-023 The CNPS number alert applies only to employees with status ACTIVE. Terminated employees with missing CNPS numbers do not generate alerts.

Dependents Management

Rule Description
FR-HRCORE-025 Each employee can have 0 or more dependents. There is no upper limit on the number of dependents.
FR-HRCORE-026 When a dependent is added, updated, or removed, the system automatically recomputes: dependents_count = total count of dependents, number_of_children = count of dependents where relationship = ENFANT.
FR-HRCORE-027 IF dependents_count or number_of_children changes THEN the system publishes an EmployeeUpdated event with changedFields: ['dependents_count', 'number_of_children']. Payroll consumes this to recalculate tax deductions.
FR-HRCORE-028 The date_of_birth of a child dependent is used to determine age-based eligibility for allocations familiales. Age calculation rules belong to the Payroll module — Core HR only stores the data.
FR-HRCORE-029 Dependents are managed exclusively by DG or RH Manager. Employees cannot add/edit/remove their own dependents (these have payroll implications).

Document Attachment

Rule Description
FR-HRCORE-030 Every document attached to an employee must have a category_code from the document category reference table. The system provides seeded categories (see §B.2) and tenants can add custom categories via admin configuration.
FR-HRCORE-031 File upload constraints: maximum file size 10 MB, accepted MIME types: application/pdf, image/jpeg, image/png, image/webp, application/vnd.openxmlformats-officedocument.wordprocessingml.document (DOCX).
FR-HRCORE-032 Each uploaded document counts against the tenant's storage quota (per Platform Vision §A.8). IF uploading a document would exceed the tenant's storage quota THEN the upload is blocked with message: "Quota de stockage atteint. Veuillez supprimer des documents ou acheter de l'espace supplémentaire."
FR-HRCORE-033 Documents can be uploaded by DG, RH Manager, or the employee themselves (self-service — e.g., uploading a new identity document copy).
FR-HRCORE-034 Documents can only be DELETED by DG or RH Manager. Employees cannot delete their own documents. Deletion is a soft-delete (marked as deleted, not physically removed from MinIO — retained per OHADA 10-year rule for relevant document types).
FR-HRCORE-035 IF ADVDOC (Advanced Document Management) module is ACTIVE THEN document uploads automatically gain versioning, retention policies, and lifecycle management per FR-PV-036. Core HR's document attachment UI seamlessly delegates to ADVDOC when active.

Employee Photo

Rule Description
FR-HRCORE-040 Photo upload accepted formats: JPEG, PNG, WebP. Maximum file size: 2 MB.
FR-HRCORE-041 After upload, the system presents a client-side crop tool enforcing a 3:4 portrait aspect ratio. The user must confirm the crop before the photo is saved.
FR-HRCORE-042 On crop confirmation, the system generates 3 versions stored in MinIO: original (as cropped), medium (150px width, proportional height), thumbnail (48px width, proportional height).
FR-HRCORE-043 Photos can be uploaded by: the employee themselves (self-service) OR the HR Manager/DG.
FR-HRCORE-044 Uploading a new photo replaces the previous one. The previous photo is NOT retained (no versioning in V1 — ADVDOC would add this).

Employee Number Generation

Rule Description
FR-HRCORE-050 Employee numbers are auto-generated using the format: {PREFIX}-{YEAR}-{MM}-{SEQ}. Example: ALT-2026-03-001.
FR-HRCORE-051 {PREFIX} is auto-derived from the tenant's company name at tenant creation: the system extracts a 3-6 letter trigram/abbreviation. Example: "ALTARYS ENTERPRISE" → "ALT", "Boulangerie Mama Kadi" → "BMK".
FR-HRCORE-052 The PREFIX is stored in the employee number configuration (per tenant) and is editable by tenant admin (DG or RH Manager). The system displays a notification during onboarding: "Le préfixe de numérotation de vos employés est {PREFIX}. Vous pouvez le modifier dans les paramètres."
FR-HRCORE-053 {YEAR} is the 4-digit year of employee creation. {MM} is the 2-digit month. {SEQ} is a 3-digit zero-padded sequential number that auto-increments per tenant. Example: the 15th employee created in March 2026 → ALT-2026-03-015.
FR-HRCORE-054 Employee numbers are NEVER reused. IF an employee is terminated, their number is NOT recycled. The sequence only increments.
FR-HRCORE-055 During bulk import, IF the imported Excel contains employee numbers THEN the system uses those (for migration). IF the employee number column is empty THEN the system auto-generates per the above rules. Imported numbers are validated for uniqueness within the tenant.
Rule Description
FR-HRCORE-060 Core HR provides a single search field using PostgreSQL fulltext search (tsvector/tsquery). The search input accepts free text and searches across configured fields.
FR-HRCORE-061 Default search fields: last_name, first_name, department_name (denormalized or joined from org unit). These defaults apply to all new tenants.
FR-HRCORE-062 DG or RH Manager can CONFIGURE which fields are included in the fulltext search index via a settings screen. Available fields for inclusion: last_name, first_name, department_name, position_title, employee_number, cnps_registration_number, national_id_number, personal_phone, email, address_city, address_commune.
FR-HRCORE-063 When the search configuration changes, the system rebuilds the fulltext search index for that tenant. For tenants with up to 350 employees, this should complete in < 5 seconds.
FR-HRCORE-064 Search results are scoped by the user's access level: DG/RH Manager see all employees; Manager sees only employees in their org unit; Comptable sees all employees (financial data); Employé sees only their own record.
FR-HRCORE-065 Search supports partial matches and accent-insensitive search (important for French: "Koné" matches "kone"). PostgreSQL unaccent extension must be used.

Bulk Import

Rule Description
FR-HRCORE-070 IF HR Core is ACTIVE for the tenant THEN the employee import Excel template includes both Layer 1 (CP) and Layer 2 (HR Core) columns. IF HR Core is INACTIVE THEN only Layer 1 columns are included. (Layer 1 import is a Control Plane feature; HR Core extends the template.)
FR-HRCORE-071 All Layer 2 (HR Core) fields in the import template are OPTIONAL. The import succeeds even if all HR Core columns are empty — employees are created with Layer 1 data, and HR Core enrichment can be done later.
FR-HRCORE-072 After Excel upload, the system displays an editable confirmation table (per FR-PV-051). Validation errors are highlighted per row per field: duplicate employee numbers, invalid date formats, invalid enum values (gender, marital status, etc.).
FR-HRCORE-073 The import is processed as a background job with a progress indicator. For 500 employees, the import should complete in < 30 seconds.
FR-HRCORE-074 Each successfully imported employee triggers an EmployeeCreated event (from CP) and, if HR Core fields are populated, an EmployeeUpdated event (from HR Core).
FR-HRCORE-075 The import must validate uniqueness of employee_number within the tenant. IF a duplicate is found THEN the row is rejected with error: "Numéro matricule en doublon: {number}."

Registre du Personnel (Fascicule 1)

Rule Description
FR-HRCORE-080 Core HR generates the Fascicule 1 (Registre du Personnel) containing employee data. Fascicule 2 (Salaires) belongs to Payroll. Fascicule 3 (Visas d'inspection) belongs to Employee Management or HSE.
FR-HRCORE-081 The Fascicule 1 export includes the following columns per employee: numéro d'ordre (sequential), last_name, first_name, date_of_birth, place_of_birth, gender, nationality, national_id_number, cnps_registration_number, position_title, employee_category, hire_date, contract_type, address, termination_date (if applicable), termination_reason (if applicable).
FR-HRCORE-082 The export includes ALL employees: ACTIVE, ON_LEAVE, SUSPENDED, and TERMINATED. Terminated employees are listed with their termination date and reason.
FR-HRCORE-083 The export is available in two formats: PDF (formatted for printing, landscape A4) and Excel (for digital archival and inspection submission).
FR-HRCORE-084 IF any employee in the export has missing mandatory fields (e.g., CNPS number) THEN the export includes a warning summary at the end listing employees with incomplete records. The export is NOT blocked — it generates with "Non renseigné" in the missing fields.
FR-HRCORE-085 The export is generated as a background job. A download link is provided when complete. For 350 employees, generation should take < 10 seconds.

Change History View

Rule Description
FR-HRCORE-090 Core HR provides a "Historique des modifications" tab on each employee's profile. This tab displays a human-readable, chronological timeline of changes sourced from the platform audit trail (AuditEntry).
FR-HRCORE-091 The change history view translates raw AuditEntry data into French labels. Example: { field: "address_city", old: "Cocody", new: "Plateau" } → "Ville de résidence : Cocody → Plateau".
FR-HRCORE-092 The change history shows: date of change, user who made the change (display name + role), field name (French label), old value, new value.
FR-HRCORE-093 The change history is visible to DG and RH Manager. Employees see a simplified version on their own profile showing only: date of change and which field was changed (not the old/new values — to prevent information leakage about who made the change).
FR-HRCORE-094 No separate storage is maintained. The formatted view is a UI presentation layer querying the AuditEntry table filtered by entity_type = 'Employee' and entity_id = {employeeId}.

B.4 State Machines

Core HR does not introduce new lifecycle states. The employee lifecycle (ACTIVE → ON_LEAVE → SUSPENDED → TERMINATED) is managed by the Control Plane / Employee Management, not Core HR.

However, Core HR introduces a profile completeness state concept:

stateDiagram-v2
    [*] --> INCOMPLETE : Employee created (HR Core fields mostly empty)

    INCOMPLETE --> PARTIAL : Some HR Core fields filled
    INCOMPLETE --> COMPLETE : All mandatory + key optional fields filled

    PARTIAL --> COMPLETE : Remaining fields filled
    PARTIAL --> INCOMPLETE : Fields cleared/removed

    COMPLETE --> PARTIAL : Mandatory field cleared (e.g., data correction)

    note right of INCOMPLETE : Triggers missing data alerts (FR-HRCORE-020)
    note right of COMPLETE : No alerts. Registre export clean.

Profile completeness levels: - INCOMPLETE (0-40%): Missing mandatory fields (date_of_birth, gender, nationality) or critical data (CNPS number). Red indicator. - PARTIAL (41-80%): Mandatory fields filled but optional fields (bank info, emergency contacts, documents) missing. Yellow indicator. - COMPLETE (81-100%): All mandatory fields + key optional fields (CNPS, at least 1 emergency contact, photo, 1 identity document) filled. Green indicator.

These are COMPUTED states (not stored) — derived from field population at display time.


B.5 Decision Tables

Permission Matrix

Action DG RH Manager Manager Comptable Employé
View any employee profile (Layer 2) ⚠️ Team only ⚠️ Financial fields only ❌ (own only)
Edit any employee profile (Layer 2)
Edit own profile (self-service fields)
View bank info (full) ✅ (read-only) ❌ (masked)
Edit bank info
Manage dependents
Upload documents ✅ (own docs)
Delete documents
Configure search fields
Configure employee number prefix
Manage document categories
Export registre du personnel
Bulk import employees
View change history (full)
View change history (simplified, own)

Offline Capability Matrix

Operation Offline? User Sync Behavior
View employee profile ✅ Yes All roles Read from IndexedDB cache
Edit self-service fields ✅ Yes Employé Queue in IndexedDB, sync on reconnect
Upload photo (self-service) ✅ Yes Employé Queue locally, upload on reconnect
Edit employee profile (HR) ❌ No DG/RH Requires connectivity
Edit bank info ❌ No DG/RH Requires connectivity
Manage dependents ❌ No DG/RH Requires connectivity
Upload documents ❌ No DG/RH/Employé Requires connectivity (MinIO upload)
Search employees ⚠️ Partial All roles Searches cached data (may be stale)
Export registre ❌ No DG/RH Requires connectivity (server-side generation)
Bulk import ❌ No DG/RH Requires connectivity

Document Category Visibility

Category Code Auto-attached by Visible to Employee? Deletable?
CONTRAT_TRAVAIL Employee Mgmt (V2) ❌ (legal retention)
BULLETIN_PAIE Payroll (auto-attach) ❌ (legal retention)
CERTIFICAT_MEDICAL HR Manager ❌ (medical privacy) ❌ (legal retention)
PIECE_IDENTITE HR Manager / Employee Soft-delete only
ATTESTATION_CNPS HR Manager Soft-delete only
DIPLOMES HR Manager / Employee Soft-delete only
RIB HR Manager ❌ (financial privacy) Soft-delete only
AUTRE HR Manager / Employee Soft-delete only

B.6 Cross-Module Dependencies

Events Published by Core HR

Event Trigger Payload Consumed By
EmployeeUpdated Any Layer 2 field change (low-risk: address, phone, photo, emergency contacts, qualifications) { employeeId, tenantId, changedFields[], timestamp, changedBy } Modules caching employee data
EmployeeBankInfoChanged Any bank_* field change { employeeId, tenantId, bankName, maskedAccountNumber, changedBy, timestamp, security_flag: true } Payroll (recache payment info), Audit/Security monitoring
EmployeeCategoryChanged Employee category change (via CP, but HR Core may display/trigger) { employeeId, tenantId, oldCategoryId, newCategoryId, effectiveDate } Payroll (contribution rate recalculation)
EmployeeProfileCompleted Profile completeness reaches COMPLETE state { employeeId, tenantId, completenessPercent, timestamp } Employee Mgmt (onboarding checklist), Dashboard
EmployeeDocumentAttached Document uploaded to employee { employeeId, tenantId, documentId, categoryCode, fileName } ADVDOC (if active — for versioning/retention), Dashboard

Events Consumed by Core HR

Event Published By Core HR Reaction
EmployeeCreated Control Plane Creates empty Layer 2 record for the new employee. Triggers CNPS alert if CNPS number not provided.
EmployeeTerminated Employee Mgmt / CP Dismisses active CNPS alerts for terminated employee (FR-HRCORE-023). Marks profile as historical.
EmployeeReassigned Employee Mgmt Updates cached department name for fulltext search index (if department is a search field).
PayslipGenerated Payroll IF HRCORE active THEN auto-attaches payslip as document (category: BULLETIN_PAIE) to employee.

API Dependencies (Synchronous)

Caller Calls Endpoint Purpose
Core HR Control Plane GET /api/v1/cp/employees/{id} Read Layer 1 baseline data (live read for contract snapshot display)
Core HR Control Plane GET /api/v1/cp/org-units/{id} Read org unit details (department name for search, manager for display)
Core HR Control Plane GET /api/v1/cp/positions/{id} Read position title for display
Core HR MinIO (Storage) PUT /upload, GET /download, DELETE Document and photo storage
Payroll Core HR GET /api/v1/hrcore/employees/{id}/bank-info Read bank info for payment processing (post-MVP)
Payroll Core HR GET /api/v1/hrcore/employees/{id}/dependents/summary Read dependents_count + number_of_children for tax calculations
Employee Mgmt Core HR GET /api/v1/hrcore/employees/{id}/profile Read enriched profile for administrative event creation
Any module Core HR GET /api/v1/hrcore/employees/{id}/photo/thumbnail Read employee thumbnail for display in lists

API Exposed by Core HR

Endpoint Method Purpose Consumers
/api/v1/hrcore/employees/{id} GET Full enriched employee profile (Layer 1 + 2) Frontend, Employee Mgmt
/api/v1/hrcore/employees/{id} PATCH Update Layer 2 fields Frontend (HR Manager)
/api/v1/hrcore/employees/{id}/self-service PATCH Update self-service fields (FR-HRCORE-010) Frontend (Employee)
/api/v1/hrcore/employees/{id}/bank-info GET Bank info (masked or full based on role) Frontend, Payroll
/api/v1/hrcore/employees/{id}/bank-info PUT Update bank info (DG/RH only) Frontend
/api/v1/hrcore/employees/{id}/dependents GET/POST/PUT/DELETE CRUD dependents Frontend
/api/v1/hrcore/employees/{id}/dependents/summary GET Computed counts (dependents_count, number_of_children) Payroll
/api/v1/hrcore/employees/{id}/emergency-contacts GET/POST/PUT/DELETE CRUD emergency contacts (max 2) Frontend
/api/v1/hrcore/employees/{id}/documents GET/POST/DELETE Document CRUD with category Frontend, ADVDOC
/api/v1/hrcore/employees/{id}/photo GET/POST Photo upload/retrieve (3 sizes) Frontend, any module
/api/v1/hrcore/employees/{id}/change-history GET Formatted change history (from AuditEntry) Frontend
/api/v1/hrcore/employees/search GET Fulltext search (query param: q) Frontend
/api/v1/hrcore/employees/import POST Bulk import (multipart Excel upload) Frontend
/api/v1/hrcore/registre/fascicule-1 POST Generate registre export (returns job ID) Frontend
/api/v1/hrcore/registre/fascicule-1/{jobId} GET Download generated registre Frontend
/api/v1/hrcore/config/search-fields GET/PUT Search configuration Frontend (Admin)
/api/v1/hrcore/config/employee-number GET/PUT Employee number prefix configuration Frontend (Admin)
/api/v1/hrcore/config/document-categories GET/POST/PUT/DELETE Document category management Frontend (Admin)
/api/v1/hrcore/dashboard/alerts GET Missing data alerts (CNPS, incomplete profiles) Frontend (Dashboard)

B.7 Multi-Tenant Implications

Concern Shared DB Schema-per-Tenant DB-per-Tenant BYO-DB
Employee enrichment data tenant_id column on employee_enrichment table. Every query includes WHERE tenant_id = ?. Per-schema table. No tenant_id filter needed. Per-DB table. Per-DB table.
Document storage Tenant-scoped MinIO bucket: tenant-{tenantId}/employees/{employeeId}/docs/ Same MinIO path structure. Same. Tenant provides storage or uses platform MinIO.
Photo storage tenant-{tenantId}/employees/{employeeId}/photos/ Same. Same. Same.
Fulltext search index Per-tenant tsvector column, filtered by tenant_id. Search config stored per tenant. Per-schema index. More efficient (no tenant filtering). Per-DB index. Per-DB index.
Document categories System-seeded categories (tenant_id = NULL) + tenant-custom (tenant_id = X). System categories in shared schema. Tenant customs in tenant schema. Per-DB. Per-DB.
Employee number sequence Sequence per tenant (stored in config table, not a DB sequence — for portability). Same — application-level sequence. Same. Same.
Storage quotas Tracked in platform DB (Control Plane). Checked before every upload. Same. Same. Same.

Design principle: All multi-tenant patterns follow the Platform Vision (§B.5). Design for BYO-DB first. Employee number sequences are application-level (not PostgreSQL SEQUENCE objects) to ensure portability across all 4 DB profiles.


PART C — Constraints & Boundaries


C.1 Regulatory Compliance — CI (Côte d'Ivoire)

CI Registre d'Employeur (Code du Travail 2015)

The CI Code du Travail (Loi n°2015-532) requires every employer to maintain a registre d'employeur in 3 fascicules:

  1. Fascicule 1 — Personnel: Sequential employee listing with personal and professional data. Core HR generates this.
  2. Fascicule 2 — Salaires: Salary register. Payroll module scope.
  3. Fascicule 3 — Visas d'inspection: Inspection visits register. Employee Mgmt / HSE scope.

The register must be: - Kept at the workplace - Available for inspection by the Labor Inspector (Inspecteur du Travail) at any time - Maintained in French

Core HR's registre export (FR-HRCORE-080-085) generates Fascicule 1 in compliant format.

CI Employee File Requirements (Loi 2013-546, Décret 2016-851)

CI law permits electronic employee records (Loi n°2013-546 on electronic transactions + Décret n°2016-851 on electronic signatures and archives). Core HR's digital dossier du personnel is legally valid provided: - Documents are stored with integrity guarantees (MinIO checksums) - Audit trail tracks all modifications (platform AuditEntry) - Electronic copies of signed documents are acceptable

CI CNPS Registration

Every employee must be registered with CNPS (Caisse Nationale de Prévoyance Sociale) on the first day of employment (Part 3.1 of legal research). Core HR: - Stores the CNPS registration number (FR-HRCORE-020) - Generates alerts when the number is missing - Does NOT handle the actual CNPS declaration (that's Employee Management's scope)

Compliance Gap: Tenants Without HR Core

Acknowledged gap: Tenants who do not purchase the HR Core module cannot maintain a compliant registre du personnel within the platform. They must manage the registre externally (paper or Excel). This is acceptable because: 1. The Control Plane baseline provides sufficient data for operational modules (Absence, Attendance, Payroll). 2. HR Core is marketed as a compliance and organizational module — tenants who care about compliance will purchase it. 3. The module upsell prompt in the Papillon UI can highlight the registre compliance benefit.


C.2 Localization Requirements — CI

Aspect Requirement
Language French (all UI labels, validation messages, export headers, document category names)
Name display Formal: UPPER(last_name) first_name (e.g., "KOUASSI Jean-Pierre"). Informal: first_name last_name.
Currency N/A — Core HR does not handle currency fields directly. Bank info is identifier-based (account numbers), not amounts.
Date format DD/MM/YYYY for all date fields
Phone format CI mobile: +225 XX XX XX XX XX (10 digits after country code). Input validation with this format.
Address Semi-structured: city (dropdown with CI cities), commune/quartier (free text), details (free text). No postal codes.
Public holidays N/A — Core HR does not manage holidays (Absence module).
Cities dropdown Seeded with major CI cities: Abidjan, Bouaké, Daloa, Yamoussoukro, San-Pédro, Korhogo, Man, Divo, Gagnoa, Abengourou + "Autre" for free text

C.3 Security Requirements

Requirement Implementation
Sensitive data classification Bank info and national ID number are classified as SENSITIVE. Medical documents (category: CERTIFICAT_MEDICAL) are classified as MEDICAL_SENSITIVE.
Bank info masking Employee self-service displays only last 4 characters. API endpoint returns masked data unless caller has COMPTABLE or RH_MANAGER/DG role.
Medical document access Documents with category CERTIFICAT_MEDICAL are visible only to DG and RH Manager. Employees can see that a medical certificate exists but cannot view its content (document metadata visible, download blocked).
Financial document access Documents with category RIB are visible only to DG, RH Manager, and Comptable.
Audit trail Every mutation on employee enrichment data, dependents, emergency contacts, bank info, documents, and photos produces an immutable AuditEntry. Bank info changes are flagged as security-sensitive (FR-HRCORE-018).
Photo storage Photos stored in tenant-scoped MinIO bucket. Access controlled via signed URLs with expiration (no public URLs).
Document storage Documents stored in tenant-scoped MinIO bucket with signed URLs. Download requires valid JWT with appropriate role.
Bulk import security Import Excel file is scanned for macro content (reject .xlsm). File is deleted from server after processing. Import audit log records: who imported, when, how many records, any validation errors.
CNPS number sensitivity CNPS registration number is a national identifier — treated as sensitive. Not displayed in search results or employee lists. Visible only on the full employee profile view (DG, RH Manager, the employee themselves).

C.4 Out of Scope

Item Reason Owner
Contract lifecycle management (creation, renewal, amendments, CDD tracking) Process layer — belongs to Employee Management (EMPMGT) EMPMGT PRD
Onboarding/offboarding workflows Process layer — belongs to Employee Management EMPMGT PRD
Trial period tracking and alerts Process layer — belongs to Employee Management EMPMGT PRD
Termination procedures and severance calculations Process layer — belongs to Employee Management + Payroll EMPMGT + PAYROL PRDs
CNPS declarations (hiring, departure, DISA) Declaration management — belongs to Employee Management EMPMGT PRD
Working hours rules, overtime, night work Time management — belongs to Time & Activities (TIMACT) TIMACT PRD
Salary information (current salary, salary history, grade) Financial data — owned by Payroll. Core HR displays contract snapshot via live read from CP/EMPMGT. PAYROL + EMPMGT PRDs
Registre du Personnel Fascicule 2 (Salaires) Salary data — belongs to Payroll PAYROL PRD
Registre du Personnel Fascicule 3 (Visas d'inspection) Inspection data — belongs to Employee Management or HSE EMPMGT/HSE PRD
Custom employee fields (tenant-defined) V2 enhancement Core HR V2
Employee organigramme (visual org chart) V2 enhancement Core HR V2
Employee directory (company-wide) V2 enhancement Core HR V2
Document versioning, retention policies, lifecycle management Requires Advanced Document Management (ADVDOC) module ADVDOC PRD
Document generation (contracts, certificates, attestations from templates) Requires ADVDOC V2 ADVDOC V2 PRD
Multi-country support (BJ, CM fields and registers) Country expansion planned for Month 9 Core HR country expansion PRD
SSO/SAML authentication for employee self-service Enterprise V2 feature Platform V2
Employee self-service: request changes with approval workflow V2 — requires approval engine Core HR V2
Medical fitness certificate tracking (renewal dates, periodic exams) HSE module scope HSE PRD
Conventions collectives sector-specific rules V2 — platform supports only CCI interprofessionnelle for MVP Platform V2

Glossary (Module-Specific Terms)

Term (FR) Term (EN) Definition
Dossier du personnel Employee file Complete record of an employee's personal, professional, and administrative data. Core HR is the data layer for this.
Registre d'employeur Employer register Legal document required by CI Code du Travail. 3 fascicules: personnel, salaries, inspection visas. Core HR generates Fascicule 1.
Immatriculation CNPS CNPS registration Registration of an employee with the Caisse Nationale de Prévoyance Sociale (CI social security). The registration number is stored in Core HR.
Certificat médical d'aptitude Medical fitness certificate Doctor's certificate confirming an employee is fit for work. Required in the employee file. Stored as a document attachment.
Certificat de travail Employment certificate Document issued by the employer at departure, confirming employment dates and position. Mandatory (Art. 16.14 CT 2015).
RIB Bank details Relevé d'Identité Bancaire — CI banking document identifying an account. Stored as document attachment + structured bank info fields.
Avenant Contract amendment Modification to an existing employment contract. Stored as a document attachment. Contract lifecycle management belongs to EMPMGT.
Personne à charge Dependent Person financially dependent on the employee (spouse, children, other). Affects tax (ITS) and social contributions (allocations familiales).
Numéro matricule Employee number Unique sequential identifier for an employee within a tenant. Format: {PREFIX}-{YEAR}-{MM}-{SEQ}.
Fascicule Section/volume One of the 3 volumes of the registre d'employeur. Fascicule 1 = personnel, 2 = salaries, 3 = inspection visas.

This PRD+FSD was produced by the ANALYST personality based on exhaustive interview with the Business Analyst/Product Owner. It serves as the authoritative reference for Core HR module architecture, design, and implementation.

Cross-references: Platform Vision PRD (docs/prd/platform-vision-prd.md) for shared infrastructure, events, data model, and tenant segmentation. Legal research (docs/research/3_validated/core-hr-legal-validated.md) for CI regulatory details.