# Configuration Module — Business Guide (English)

This guide explains the **Configuration** module of the ERPFLOW backend in everyday business language.
It is written so that HR, Admin, and operations staff can understand it without technical knowledge.

> বাংলা ভার্সন: **CONFIGURATION_MODULE_GUIDE_BN.md**

---

## 1. What is this module?

The Configuration module is the **shared "master data" centre** of the ERP. It is the dictionary file
that many other modules (Employee, Attendance, Payroll, Onboarding, etc.) rely on.

Instead of each module keeping its own copy of information such as what the departments are, what job
titles exist, or where people work, the Configuration module stores these once and lets everyone reuse them.

It is divided into two big areas:

| Area | Purpose |
|------|---------|
| **Employee / HR masters** | Employment types, salary structures, document types, designations, grades, teams, divisions, branches, work locations, sections, cost centers, employee ID card settings |
| **System Configuration** | Companies and departments (the tenant structure the whole system sits on) |

**Key idea:** almost everything here is scoped to the **currently selected company** (tenant). A user
only sees and manages master data belonging to the company they are currently working in.

> All routes are served under the **`api/v1/configuration`** prefix and require a logged-in user.

---

## 2. Who should use it?

| Role | Typical use |
|------|-------------|
| System / Super Admin | Manage the companies (tenants) that the ERP serves |
| HR / Admin | Maintain departments, designations, job types, document types, grades, teams, divisions, branches, sections, cost centers, work locations |
| Payroll / Finance | Read the salary structures, ID card templates, work locations |
| Regular employees (read-only via pickers) | Choose a department, section, cost center, work location, document type, etc. when filling forms |

Because of the `onboarding.access` and `onboarding.document` middleware, the access also depends on the
person being logged in, having completed onboarding, and not having an expired document deadline. Because of
the `permission:*` middleware, each operation additionally requires a specific permission (see **Section 6**).

> **Access model (verified in `PermissionEngine::userCan`, `config/platform.php`, `config/actions.php`):**
> access is checked per permission key for the currently selected company. Users with user-type `developer`
> (default `bypass_user_types`) or holding the system role `administrator` inside the company get **full
> access** without role-matrix grants. Everyone else receives permissions from their roles
> (`role_permissions`) plus per-user allow/deny overrides; a **deny** override always wins.

---

## 3. Before you start (prerequisites)

To create or use the data managed by this module, the following should exist:

1. A **company** (tenant) for all company-scoped masters, in an **active** status.
2. An **active employee user** account for the person who will be department head, and correct authorization.
3. Valid authentication (JWT via `auth:api`), a **completed onboarding**, and a **non-expired document deadline**.
4. The relevant role permissions such as `configuration.view`, `configuration.create`,
   `configuration.update`, `configuration.delete`, and `configuration.system-configuration-menu-view`.

---

## 4. What problems does it solve?

| Business problem | How this module solves it |
|------------------|---------------------------|
| Duplicate or inconsistent "department" or "designation" names across the system | One company-scoped master record reused everywhere |
| No central place to configure a tenant/company structure | Company + department management under System Configuration |
| Hiring needs standard lists (job types, document types, grades, teams, branches) | Picker-style master data that Employee onboarding and HR forms reuse |
| Nobody is responsible for a department | Department management with a **department head** picker |
| Payroll depends on salary structures | Salary structures are maintained centrally and read here |
| HR cannot determine an employee's workplace / cost grouping | Work locations, sections, and cost centers as company-scoped masters |

---

## 5. Main features (described in business language)

### 5.1 System health check
- **What it is:** a lightweight "is the module alive" signal for monitoring.
- **API:** `GET /api/v1/configuration/health`
- **Permission:** `configuration.view`
- **Controller/Service:** `ConfigurationController::health` → `ConfigurationService::getHealthStatus`
- **Business impact:** used by DevOps/monitoring; logs an activity event `configuration.health_viewed`.

### 5.2 Employment types (Full-time, Contract, Intern, etc.)
- **What it is:** the types of contract/relationship an employee can have.
- **API (read):** `GET /employment-types`, `GET /employment-types/{id}`
- **API (write):** `POST /system-configuration/employment-types`, `PUT /system-configuration/employment-types/{id}`, `DELETE /system-configuration/employment-types/{id}`
- **Controllers:** `EmploymentTypeController` + `EmploymentTypeService` + `EmploymentTypeRepository`, model `EmploymentType`; requests `Store/UpdateEmploymentTypeRequest`.
- **Dependencies:** belongs to a company; consumed by the Employee module (Employment section).
- **Business impact:** determines job classification used by HR and (indirectly) leave/payroll rules.

### 5.3 Salary structures
- **What it is:** named salary frameworks an employee gets assigned to.
- **API (read-only in this module):** `GET /salary-structures`, `GET /salary-structures/{id}`; also `GET /system-configuration/salary-structures`, `GET /system-configuration/salary-structures/{id}`
- **Controller:** `SalaryStructureController` (`index`/`show` only), model `SalaryStructure`.
- **Important note (verified in the route files):** the Configuration route file comment says *"Salary
  structure writes moved to Payroll (`payroll.structure-manage`)"* — and `Modules/Payroll/routes/api.php`
  confirms it: `POST /salary-structures`, `PUT /salary-structures/{id}`, `PATCH .../activate`,
  `PATCH .../deactivate` and the `/components` endpoints all live in the Payroll module behind
  `permission:payroll.structure-manage`. The Configuration `SalaryStructureController` still contains
  `store/update/destroy` methods, but **no write route is registered for them in this module**.
- **Dependencies:** owned by a company; consumed by Employee (Salary) and Payroll (which owns the writes).
- **Business impact:** payroll and HR always see the same salary frameworks.
### 5.4 Document types
- **What it is:** the "roll types" HR allows in employee files (NID, passport, offer letter, etc.), including sensitive ("restricted") and expiry-required flags.
- **API:** `GET /document-types`, `GET /document-types/active`, `GET /document-types/{id}`; writes under `/system-configuration/document-types`.
- **Controllers:** `DocumentTypeController` + `DocumentTypeService`, model `DocumentType` (fields `is_restricted`, `requires_expiry`).
- **Dependencies (verified):** used by the Employee module — `EmployeeDocument`, `EmployeeIdentity`
  (via `EmployeeDocumentService`) — and by the Onboarding document-upload step (`DocumentUploadStepHandler`).
  The employee ID card feature does **not** reference document types.
- **Business impact:** controls what classified employees can upload; restricted documents need a special role.

### 5.5 Designations (job titles)
- **What it is:** the titles employees are hired into.
- **API:** `GET /system-configuration/designations`, `POST /system-configuration/designations`, `PUT /system-configuration/designations/{id}`, `DELETE /system-configuration/designations/{id}`
- **Controllers:** `DesignationController` (`listDesignations`, `storeDesignation`, `updateDesignation`, `destroyDesignation`), `DesignationService`, model `Designation`.
- **Dependencies:** consumed by the Employee module (Organization assignment).

### 5.6 Employee grades (grade / level)
- **What it is:** the grade/level ladder (e.g. Grade-1 … Grade-10) that ranks employees.
- **API:** `GET /grades`, `POST /grades`, `PUT /grades/{id}`, `DELETE /grades/{id}`
- **Controller:** `Grade/EmployeeGradeManagementController` + `GradeService`, model `Grade`.
- **Note:** delete soft-archives (`archived_at`) so historical assignments keep their names.
- **Dependencies:** belongs to a company (grade uniqueness is company-scoped); consumed by Employee.

### 5.7 Teams
- **What it is:** the team groupings people are organised into.
- **API:** `GET /teams`, `POST /teams`, `PUT /teams/{id}`, `DELETE /teams/{id}`
- **Controller:** `Team/TeamManagementController` + `TeamService`, model `Team`.

### 5.8 Company divisions
- **What it is:** the divisions / business units under a company.
- **API:** `GET /divisions`, `POST /divisions`, `PUT /divisions/{id}`, `DELETE /divisions/{id}`
- **Controller:** `Division/CompanyDivisionManagementController` + `DivisionService`, model `Division`.

### 5.9 Company branches
- **What it is:** the physical branches of the company.
- **API:** `GET /branches`, `POST /branches`, `PUT /branches/{id}`, `DELETE /branches/{id}`
- **Controller:** `Branch/EmployeeBranchManagementController` + `BranchService`, model `Branch`.

### 5.10 Employee ID card settings
- **What it is:** templates that control the employee ID card design (portrait/landscape, fields, validity).
- **API:** `GET /employee-id-card-settings`, `POST /employee-id-card-settings`, `PUT /employee-id-card-settings/{settingId}`, `DELETE /employee-id-card-settings/{settingId}`
- **Controller:** `EmployeeIdCard/EmployeeIdCardManagementController` + `EmployeeIdCardSettingService`, models `EmployeeIdCardSetting` (belongs to company) and `EmployeeIdCard`.

### 5.11 Sections, Cost centers, Work locations (the "flat org masters")
- **What they are:**
  - **Sections**: a unit within the organization
  - **Cost centers**: a budget / cost grouping (finance-oriented)
  - **Work locations**: where employees physically work
- **API per row (list + active + show + store + update + destroy):**
  - `GET /sections`, `GET /sections/active`, `GET /sections/{id}`, `POST /sections`, `PUT /sections/{id}`, `DELETE /sections/{id}`
  - `GET /cost-centers`, `GET /cost-centers/active`, `GET /cost-centers/{id}`, `POST /cost-centers`, `PUT /cost-centers/{id}`, `DELETE /cost-centers/{id}`
  - `GET /work-locations`, `GET /work-locations/active`, `GET /work-locations/{id}`, `POST /work-locations`, `PUT /work-locations/{id}`, `DELETE /work-locations/{id}`
- **Controllers:** `SectionController`, `CostCenterController`, `WorkLocationController` (each with a service + repository + model + request/resource).
- **Permission:** reads under `configuration.view`; writes under `configuration.create` / `.update` / `.delete`.
- **Business impact:** the **`active`** endpoints exist for the picker forms (only active values are shown when assigning an employee).
---

## 6. How access is controlled (verified from code)

The whole route group runs through three middleware layers:

1. `auth:api` — the caller must present a valid JWT for an active user.
2. `onboarding.access` + `onboarding.document` — new joiners must complete onboarding; an expired document
   deadline blocks access (verified in `EnsureOnboardingAccess` / `EnsureDocumentDeadline`).
3. `permission:*` — `App\Platform\Http\Middleware\EnsurePermission` calls `PermissionEngine::userCan()`,
   which grants a key only when the user is **active**, the request has a resolved **company**, and the key
   is either granted through roles/overrides or bypassed.

### Where permission keys come from

Permission keys are generated from the action catalog `config/actions.php`. The Configuration module does
not opt out of common verbs, so its published keys are **common actions ∪ module-specific actions**:

| Key | Kind | Referenced in this route file? |
|-----|------|-------------------------------|
| `configuration.view` | common action `view` | ✅ yes |
| `configuration.create` | common action `create` | ✅ yes |
| `configuration.update` | common action `update` | ✅ yes |
| `configuration.delete` | common action `delete` | ✅ yes |
| `configuration.system-configuration-menu-view` | module-specific action | ✅ yes |
| `configuration.system-configuration-company-view` | module-specific action | ❌ catalogued, but **no route references it** |
| `configuration.approve` / `.reject` / `.assign` / `.export` / `.import` / `.print` / `.clone` / `.archive` / `.restore` / `.download` / `.upload` / `.menu-view` | remaining common actions | ❌ not referenced by this route file |

So exactly **five keys** gate every endpoint in this file:

| Permission | What it allows (as wired in the routes) |
|------------|------------------------------------------|
| `configuration.view` | Read the core picker lists (employment types, salary structures, document types, sections, cost centers, work locations) and the health endpoint |
| `configuration.system-configuration-menu-view` | Read/List System Configuration data (companies, departments, department-head candidates, designations, employment types, salary structures, document types, grades, teams, divisions, branches, employee ID card settings) |
| `configuration.create` | Create every master record and system entity (POST routes) |
| `configuration.update` | Edit existing records (PUT routes) |
| `configuration.delete` | Delete/archive master records (DELETE routes; soft archive via `archived_at` where the model defines it) |

### How a key becomes "granted" (verified in `PermissionEngine`)

1. `developer` user-type (`bypass_user_types`, default in `config/platform.php`) or the system role slug
   `administrator` (`bypass_role_slugs`) inside the current company → **all** active permissions.
2. Otherwise, the granted set = role-linked keys (`role_permissions`, only for roles of the current company)
   ∪ per-user **allow** overrides, minus per-user **deny** overrides (deny always wins).
3. The permission record itself must have `status = active`.

### Approval wiring (verified)

`config/actions.php` marks Configuration `create`, `update`, `delete` as **requires_approval**.
`ConfigurationApprovalSeeder` seeds the **"Configuration Create Approval"** workflow (one parallel step,
resolver_type `role`, Administrator role, completion rule `any`) and a default setting with
`approvalEnabled = false` for the demo company — i.e. the approval machinery exists and `configuration.create`
is registered to it, but requests are **not blocked by default** in the demo environment.

### Who is expected to use it (verified from demo seeders)

- `administrator` role / `developer` users → full access to everything (bypass).
- Demo role **`configuration-staff`** (`ConfigurationRoleSeeder`) → seeded with only `configuration.view`
  (plus `employee.update-own-profile`), i.e. read-only picker access.
- Any other role must be given the needed `configuration.*` keys through the Platform role-matrix screen;
  the route file does not hard-code a role list.

### Company (tenant) isolation (verified)

`SetCompanyContext` resolves the company from the `X-Company-Id` header, falling back to the user's default
membership. Non-platform users are confined to companies they belong to; platform-scoped users (developer /
super-admin) may act in every **active** company. When no company resolves, tenant-scoped controllers throw
`PermissionDeniedException('company.context')` — data is never silently read across tenants.

---

## 7. Dependencies on other modules

- **Employee module** — consumes designations, departments, employment types, salary structures, document types, grades, teams, divisions, branches, sections, cost centers, work locations (via pickers).
- **Payroll module** — owns salary-structure *write* operations (`payroll.structure-manage`); this module keeps the read/reference view.
- **Onboarding module** — gates new staff; the `onboarding.access` / `onboarding.document` middleware applies.
- **Auth / Platform** — provides `auth:api`, roles, and the `permission` middleware.
- **Tenancy layer** (`App\Core\Tenancy\TenantContext`) — provides the "current company" for every endpoint.
- **Core Companies** — the company model that departments, grades, teams, etc. belong to.

---

## 8. A typical business workflow

**"Onboard a new employee in an existing company":**

1. Admin opens **System Configuration** and confirms the **company** is **active**.
2. Admin/HR make sure the required **masters** exist and are active: employment type (Full-time), designation
   (Software Engineer), grade, team, division, branch, and the relevant **department** (with its head),
   **section**, **work location**, **cost center**.
3. HR creates a **document type** if the employee document folder needs it.
4. Front-end picker forms call the **active** endpoints (e.g. `/sections/active`) so only valid options show.
5. Payroll assigns a package by selecting the salary structure from the Payroll module; Configuration stays the single reference.
6. When an employee later leaves, `DELETE` on the masters soft-archives them so history keeps the names.

---

## 9. System / business impact

- **Single source of truth** — one company-scoped master per concept reused across modules.
- **Tenant isolation** — every object is scoped to the current company, so data never leaks between tenants.
- **Safe deletion** — most org masters soft-archive, preserving historical employee assignments.
- **Clear ownership** — Payroll owns salary writes, Configuration owns the reference/read, avoiding double maintenance.

---

## 10. Common problems (and what they usually mean)

| What you see | Likely reason |
|--------------|---------------|
| 401 — not logged in | Missing / invalid `auth:api` token |
| 403 — forbidden | Onboarding not finished, document deadline expired, or the role lacks the `permission:*` key (and the user is not a `developer`/`administrator`, which bypass) |
| Department list empty | No company in context, or the company is not **active** |
| Cannot pick a value in a form | No **active** master exists; the `active` endpoints drive the pickers |
| Cannot create a salary structure here | Writes moved to Payroll (`payroll.structure-manage`) — not exposed in this route file |
| Deleting a department fails | The system blocks deleting a department that has child departments or active employees (data protection) |

---

## 11. Summary

The Configuration module is the shared **administrative reference centre** of the ERP. It defines the
companies and departments, plus all the HR / organization masters (employment types, salary structures,
document types, designations, grades, teams, divisions, branches, sections, cost centers, work locations,
and employee ID card settings) that every other module reuses. Because the data is company-scoped and
protected by layered permissions and the onboarding gate, only authorised people can change it — but once
defined, the same clean, consistent values flow through every form and every employee operation in the system.

---

*Generated from `backend/Modules/Configuration/routes/api.php`. Written as a business guide; references
controllers, services, models and middleware for accuracy.*