Movements Reference Public

Research Evidence

Evidence gathered from the live Movements module source before writing this guide — the exact configuration, controller, model, migration, cron job, and seeder files read, and what each one proves about the module's behavior.

Guide version: r1 Module version: 1.1.0 Updated: 2026-07-22 Estimated time: 4 min 2 views
Reference

Research Evidence

This guide is written from the live module source, not from assumptions. Every claim in the other pages traces back to a file listed below, with a note on what that file proves.

????
Method. Before writing, each configuration, controller, model interface, migration, cron job and seeder under modules/Movements/ was read directly. The planning docs under modules/Movements/specs/ were not used as a source — only the shipped code is authoritative. Where a behavior depends on another module (Announcements, Timeline, Compliance, mPDF), the module's own guarded call sites were the evidence.

Manifest & configuration

FileWhat it proves
module.jsonSlug movements, category Human Resource, version 1.0.0, the 10 permission keys, 6 tables, and the 12 settings keys. Also the "known risks" (immutable rows, first-run baselining, transactional selection, salary gating, session-only self-service).
config/module_config.phpmodule_key = movements, icon fa-exchange, category Human Resource — the Manage Modules registration.
config/menu.phpThe four HR Operations sidebar items, their URLs and per-item permissions, and that the Internal Job Portal has no permission.
config/default_menu.phpThe default-menu slice (position 21, after core Human Resource) mirroring the same four items.
config/permissions.phpThe exact permission keys, labels, and the "Human Resource: Mobility" category; that movements is the module-level key.
config/routes.phpThe canonical hyphenated URLs and their underscore aliases mapping to each controller.
config/settings.phpThe Mobility Settings component tab injected into core Settings.
config/profile_tabs.phpThe three profile tabs, their gates, and that the two "My…" tabs are self_only and resolve the employee from the session.
config/system_logs.phpEvery audit-log event key, its category, and its severity.
language/english/movements_lang.phpEvery UI label and message quoted in this guide, plus the movement types, stages, statuses, and the nav-description tooltips.

Controllers

FileWhat it proves
controllers/Movements.phpMovements are record/view/reverse/delete only (no edit); the "from" values are re-resolved server-side; the reversal swaps from/to and links reversed_movement_id; the my_* endpoints derive the user from the session and honor the self-tab + salary-visibility settings.
controllers/Internal_hiring.phpServer-validated status transitions; publish gating; the publication side effects (announcement/timeline); the ordered pipeline; and the one-transaction selection — application → selected, employee master update, department membership move (FIND_IN_SET), movement record, slot fill — with rollback on any failure and a policy re-check.
controllers/Internal_jobs.phpThe self-service portal takes identity from $this->login_user->id only; the server re-runs the policy on submit; withdrawal honors the grace window; and override requests require a genuine policy block. IDOR guards on every mutation.
controllers/Movements_settings.phpThe twelve setting keys and their sanitizers (int / bool / enum), and that saving writes the update:movements_settings audit event.

Policy engine, helper & jobs

FileWhat it proves
libraries/Mobility_policy.phpThe pure, unit-testable rule set: two structural rules (opening open, one active application) and three policy rules (usage limit, tenure, disciplinary); the rolling window computed local→UTC; tenure fails open on unknown hire dates; and that an approved override bypasses only the policy rules.
helpers/movements_helper.phpThe movement type / source / stage options, the opening transition map, the salary formatter (honoring the view-salary decision), and the idempotency key builder.
jobs/CaptureEmployeeMovementsJob.phpDaily 02:20 (20 2 * * *); self-gates on module_movements + movements_auto_capture; hashes department/position/salary; first run baselines only; classifies transfer / role change / salary adjustment; idempotent recording.
jobs/CloseExpiredOpeningsJob.phpDaily 01:10 (10 1 * * *); closes published openings past their closing date; self-gates and skips when tables aren't migrated.

Schema & seed data

FileWhat it proves
migrations/20260716115339_create_movements_module_tables.phpAll six tables and their columns (every field cited on the Reference page), the indexes and unique idempotency indexes, the standard audit block on every table, the reversible down(), and the insert-only seeding of the 12 settings defaults (3, 6, on, 0, 0, on, on, on, off, on, on, hr_only).
seeders/MovementsDemoSeeder.phpThe exact demo slice (2 openings, 1 application + 2 stages, 2 movements, 1 override); idempotency by stable markers; schema-drift filtering; dry-run support; and the soft-delete unseed() (children before parents).
????
Also present but out of scope for this guide: the models under models/ (one per table), the views under views/movements/, and the planning documents under modules/Movements/specs/. The models were consulted only for their public method names; the specs directory is design material and was intentionally not used as a factual source.

Next steps

Was this guide helpful?

Report a content problem