Civil Service HR Core API
On this page
- At a glance
- What it does
- A. Keeps the complete employee record
- B. Treats a family as a graph
- C. Takes employees' own changes through review
- D. Prepares salary-step, promotion and retirement decisions
- E. Applies rules taken from regulations
- F. Keeps a versioned organisation chart
- G. Scopes every piece of access
- H. Reports, reminds and invites
- I. Brings in data from the older system
- J. Has documents signed on a signing platform
- K. Protects accounts and identities
- Interface
- Standards
- Inside
- Design decisions
- Related
- Terms
Civil Service HR Core API is the core of a personnel system for civil servants: the Laravel application that owns every employee record and every rule applied to it. It holds personal data, placements, families and more than twenty kinds of career history, takes employees' own proposed changes through review, prepares salary-step, promotion and retirement decisions, applies pay and retirement rules taken from government regulations, keeps a versioned organisation chart, and decides who may see and change what, down to a single unit.
It is built for an organisation whose structure and rules are set by regulation and change over time. Every rule it applies can be traced to the regulation it implements, every derived figure is calculated from its source rather than typed in, and every piece of access is a recorded, time-limited grant.
At a glance
| Language & framework | PHP, with Laravel, on PostgreSQL and Redis |
|---|---|
| Architecture | Stateless Laravel Core |
| Version | 2.1.0 |
| Status | In development |
| Form | An HTTP API with background workers; the user interface is a separate web application |
| Source code | Private |
What it does
A. Keeps the complete employee record
Each person has personal data, contacts, addresses and titles; each employee has a placement and a unit. Around them sit more than twenty kinds of career history — education, rank, position, salary steps, performance, leave, training, awards, transfers, discipline and others — each with its own rules and the supporting documents that kind of record requires. A person's legal status changes automatically when an event that the regulations define, such as unpaid leave or study leave, begins and ends.
B. Treats a family as a graph
Spouses, parents and children are relationships between people, not fields on an employee, so a family member is recorded once and linked to everyone they belong to. Marital status is derived from those relationships, and the module suggests who qualifies for a family allowance, with its reasons, for an administrator to decide.
C. Takes employees' own changes through review
Employees propose changes to their own records — a new qualification, a marriage, a corrected date — with attachments. A reviewer approves, returns or rejects each proposal, and on approval the change and its attachments move into the record itself.
D. Prepares salary-step, promotion and retirement decisions
The module lists who is due for a periodic salary step, a promotion or retirement, notifies the people responsible, and takes each case through its decision. For a salary step it also drafts the decree as a PDF whose every figure comes from the records and whose preamble cites the regulations it rests on.
E. Applies rules taken from regulations
Salary tables are stored per regulation with the date each takes effect, so pay is correct for any date, past or present. Retirement age comes from the position held, promotion dates apply their conditions in order, and performance scores are judged by the method of their own era.
F. Keeps a versioned organisation chart
Each agency's structure belongs to the regulation that set it and takes effect on its own date. The whole government can be read as it stood on any day, positions form their own hierarchy on top of the units, and the number of people in each position is calculated from appointments.
G. Scopes every piece of access
Access is granted as a role at a scope — the whole system, the central personnel office, one agency, or one unit with the units below it. Grants are requested and approved by different people, expire on their own, and follow their holder when they move.
H. Reports, reminds and invites
Reports cover the employee list, the seniority list, recapitulations by any dimension, staffing per agency, terminations, training and awards, all filtered by the reader's scope. Reminders of upcoming due dates go out by e-mail, and invitations to create an account are sent in daily batches.
I. Brings in data from the older system
Records from the system it replaces are imported phase by phase, from a read-only source, repeatably, with a report of every problem found and no personal data in that report.
J. Has documents signed on a signing platform
Documents that need a signature are signed on an external signing platform, with this module as its client. A user links their account once by consent; each signing stage is registered with the platform, the signer signs there with their own certificate, and the result comes back so the signed PDF is copied into the module's own storage. If a notification is missed, the status can be pulled again.
K. Protects accounts and identities
People sign in with the module's own tokens or through an external single sign-on, with two-factor authentication. A person's identity is verified at two levels: a document level, checked by an officer from scanned documents for people without an account, such as family members, and an actual level, reached only through an identity card and a live face challenge by the account holder. Personal data is encrypted in the database, and identity photos shown to reviewers carry a watermark naming the viewer.
Interface
| Area | What it exposes |
|---|---|
| Authentication | login, rotating refresh tokens, two-factor, external sign-on, the public keys of its tokens |
| People and identity | personal data, identity levels, identity verification and its review queue |
| Employees and families | employee records, placements, family relationships, allowance suggestions |
| Career history | every kind of history record with its documents |
| Proposals | employees' proposed changes and their review |
| Services | salary-step, promotion and retirement cases, decisions and decree drafts |
| Organisation | regulations, agencies, versioned structures, the position map, its change log |
| Access | role requests, approvals, revocations, the catalogue of roles |
| Reports | lists, recapitulations, staffing, dashboard |
| Reference data | a catalogue of every reference table, from which the interface builds its forms |
| Files and signing | uploads through short-lived links, signing stages and their status |
| Readiness | one check of the database, the cache, storage and every service the core depends on |
Standards
| Standard | What it guarantees here |
|---|---|
| JSON Web Tokens with RS256, and a published JWKS | one token format for every login, verifiable by any service without calling the core |
| OAuth 2.0 and OpenID Connect, with PKCE | sign-in through an external identity provider, exchanged for the core's own token |
| TOTP (RFC 6238) | two-factor authentication with any authenticator app |
| Presigned URLs, AWS Signature Version 4 | files moved between browsers and storage without passing through the core |
| W3C Trace Context and OpenTelemetry | one trace from the user's request through every background job and service call |
| UUIDv7 | public identifiers that sort by time and reveal no internal sequence |
| ISO 8583 and ISO 4217 | every amount stored as an integer in the currency's minor unit |
| National civil-service circular on access management | access requested and approved, the verifier is not the approver, grants last at most two years |
| Civil-service regulations on pay, rank, retirement and allowances | each rule applied is the one in force on the date in question, and cites its legal basis |
Inside
The core follows Stateless Laravel Core: nodes hold nothing, slow work runs as queued jobs, files never touch the server, every login ends in the core's own token, and every request, job and outgoing call is traced. Each external service is reached through one class of its own, with its own configuration, timeout and family of errors, and each business domain — people, families, histories, proposals, services, organisation, access — has its own services that both the administrators' routes and the employees' proposals go through.
Design decisions
A proposal goes through the same rules as an administrator's edit. A change an employee proposes is validated by the same domain service an administrator would use, so there is no looser side door into the records. The proposal is stored encrypted together with a snapshot of the record it was based on, and approval is refused if the record has changed since — a reviewer can never approve a proposal that would silently overwrite someone else's later correction. A reviewer cannot decide a proposal about themselves or their close family.
Rules come from regulations, as dated data and cited code. What a regulation changes — a salary table, an assessment method — is stored as data with the date it takes effect, so a new regulation is added rather than coded over the old one, and past dates keep their own rules. What stays the same — counting service, rounding a date to the next promotion period — is code that names the regulation it implements.
A hierarchy stays relational, and versioned. The organisation chart is master data for employees, positions and access, so it lives in the same relational database, with foreign keys protecting every record that points into it. Each structure is a version with its own dates, and units are linked to their predecessors rather than matched by name.
Scope is data, and code asks about permissions. A grant is a row of user, role and scope. One function decides whether a grant covers a piece of data, lists are filtered by the union of a user's scopes, and code never checks a role's name, so a new kind of reviewer is one catalogue entry.
Money is an integer. Every amount is stored, calculated and sent as a whole number of hundredths of a rupiah, named with a suffix that states the scale, so no layer can lose or invent a fraction of a rupiah.
Derive, do not store. The number of people in a position, an employee's current unit, the scope a record belongs to and a person's marital status are all calculated from their sources. A derived figure cannot drift from what it was derived from, and it can be asked for any date.
The system suggests; a person decides. Where the rules depend on facts the system cannot fully trust — who still qualifies for a family allowance, which era an ambiguous score belongs to — the module answers yes, no or needs review, with its reasons, and an administrator makes the decision.
Identity has two levels. A family member who will never have an account can still be recorded with a checked identity at document level, while the actual level is reserved for an account holder who passes the identity-card and face challenge. Neither level pretends to be the other.
Old data comes in phase by phase. The older system's database is read without ever being written to, each phase can be run again safely, and every problem found is reported without personal data, so the move to this module is a sequence of checked steps rather than a single risky cut-over.
Related
The storage service through which every document and attachment travels.
The address service that supplies regions for people's addresses.
The face challenge that proves an account holder was present during identity verification.
The renderer that gives every uploaded document its first-page preview.
The signing platform on which documents are signed, with this module as one of its external clients.
Where the trace of a request through all these services ends up.
How the older system's records are brought in, phase by phase.
How pay, promotion and retirement rules stay in step with the regulations.
Why every amount is an integer in the currency's minor unit.
How the versioned organisation chart is stored and read.
How each administrator gets access to exactly their part of the organisation.
Terms
- Career history
- The dated records of an employee's working life — rank, position, salary steps, education, leave and the like — each with its supporting documents.
- Proposal
- A change an employee requests to their own record, applied only after a reviewer approves it.
- Scope
- The part of the organisation a grant of access applies to: everything, one agency, or one unit with the units below it.
- Decree
- The official document that records a decision about an employee, such as a new salary step.
- Agency
- A department of the government whose structure is set by its own regulation.
Technologies covered
- PHP
- Laravel
- PostgreSQL
- Redis
- FrankenPHP
- OpenTelemetry
- ISO 8583
- JWT
- OAuth 2.0
- OpenID Connect