Appearance
2. Data and security first
2.1 Identify entities
Nouns in your requirements: Employee (already in HCM), LeaveType, LeaveRequest, LeaveBalance. Approvals are a workflow, not an entity.
2.2 Create entities
For each, decide name, fields, types, required, defaults, validation. The Leave Management entities:
| Entity | Key fields |
|---|---|
lm_leave_type | type_code (unique, display), type_name, description, status (ACTIVE, INACTIVE), annual_days |
lm_leave_request | request_number (unique, display), employee_id, leave_type_id, from_date, to_date, days, reason, status (DRAFT, PENDING_APPROVAL, APPROVED, REJECTED, CANCELLED) |
lm_leave_balance | employee_id, leave_type_id, balance_year, entitled_days, used_days |
Use a short prefix (lm_) so your table names never collide with another plugin's. See Entities for every field option.
2.3 Relationships
Employee (HCM)
|
+-- LeaveRequest --- LeaveType
|
+-- LeaveBalance --- LeaveType- One to many: an employee has many requests. Store the parent's id on the child (
employee_id,leave_type_id), and mark the field as a reference so lookups show names. - One to one: a unique reference field.
- Many to many: a third entity holding both ids.
- Delete behaviour: turn on soft delete for anything auditable, so nothing disappears.
2.4 Optimize
| Do | Why |
|---|---|
index fields you filter or join by (employee_id, status, to_date) | fast lists and lookups |
unique constraints for natural keys (type_code, request_number) | no duplicates |
composite index for common filters (employee_id, balance_year) | balance lookup |
| audit fields and tenant id | already added for you |
2.5 Migration
You never write SQL. Installing the plugin creates the tables; installing a newer version alters them. The same package moves from development to test to production, so every environment gets the same structure. Add new fields rather than changing a type once data exists.
2.6 Security model (before the UI)
Roles and what they may do:
LEAVE_HR_ADMIN leave types: create, read, update requests: read balances: read approves HR stage
LEAVE_MANAGER leave types: read requests: read, approve
LEAVE_EMPLOYEE leave types: read requests: create, submit, read balances: readThen add:
- Record scope: an employee sees only rows where
employee_idis themselves; a manager sees their team. - Field permissions: hide sensitive reasons (medical) from managers if policy requires.
- API and menu permissions for each role.
- Audit: on by default; review it in the Audit log.
- Tenant isolation: automatic; every query is scoped to the tenant.
A plugin ships its roles in plugin.json, so installing gives a tenant the same roles everywhere. Details: Security Designer.
Next: Screens.
