HR / enterprise · 2026 · iOS + Android
HRMS Mobile
Employee self-service on Odoo: clock, leave, and pay, with DeepFace check-in so attendance is the employee, not a proxy.
Technical Product Owner + Mobile Engineer
Clock-in
Leave, pay, attendance
Employees
HR on a phone
iOS + Android
Both stores
Click any screen to zoom
01
Context
HRMS is employee self-service for organisations running HR on Odoo: a Flutter app and a Next.js dashboard over the oe_hr_ess_mobile_api REST module. Bearer sessions, portal-safe payloads, and records limited to what that employee is allowed to see. Home, Leaves, Pay, Attend, and a More hub cover the day-to-day; managers get approvals on top. Check-in is verified with DeepFace before the attendance record is trusted.
02
My role
I owned
- Module map and navigation IA (Home, Leaves, Pay, Attend, More)
- Prioritization of ESS workflows vs. manager tools
- Flutter architecture, Next.js dashboard, and Odoo API integration
- DeepFace check-in: profile photo matched to the live capture
- Screen inventory, empty states, and bilingual PDF outputs
- Product documentation for users and implementers
The team owned
- Odoo HR configuration and access rights
- oe_hr_ess_mobile_api backend module
- Payroll rules and company policy content
03
The problem
Employees were expected to live in Odoo for leave, payslips, attendance, loans, expenses, and letters. That is a desktop mental model. On a phone it becomes a maze of menus. HR still needed the system of record to stay Odoo — we could not fork the data.
04
Discovery
We inventoried every ESS action people actually do on a phone: clock in, request time off, read a payslip, raise an expense, acknowledge a warning, open a help-desk ticket. Manager work (approvals) is a different permission set, not a different app. The constraint was portal-safe APIs — never expose another employee’s records — and a More menu that could grow without exploding the tab bar.
05
Product decisions
Five tabs, everything else in More
- The decision
- Pin Home, Leaves, Pay, and Attend. Put loans, custody, requests, expenses, directory, documents, policies, training, help desk, appraisals, and disciplinary behind More.
- Why
- Daily frequency should own the bar. Satellite HR modules are real, but they are not every morning.
- The trade-off
- Some power users take an extra tap. The alternative was an unreadable eight-tab bar.
- The result
- The product can add a module without a navigation redesign. Documentation follows the same map.
Odoo remains the system of record
- The decision
- Flutter renders portal-safe REST responses. No shadow HR database on the device beyond session and cache.
- Why
- Payroll, leave balances, and disciplinary state are legally and operationally Odoo’s job.
- The trade-off
- Mobile UX is bounded by what the API will admit. We design for the contract, not a fantasy backend.
- The result
- Clock-in, leave, payslips, and tickets stay consistent with the desktop portal. Permissions are inherited, not reimplemented.
Home is status, not a menu dump
- The decision
- The dashboard is greeting, clock state, payday countdown, alerts, then insight charts — attendance hours, leave usage, salary trend.
- Why
- People open HR to answer “what do I need to do today?”, not to admire a grid of icons.
- The trade-off
- Deep modules are one hop further away. Home stays scannable.
- The result
- Attendance, leave, and pay still have dedicated tabs. Home tells you whether you are clocked in and whether something is on fire.
Check-in has to be the employee
- The decision
- DeepFace compares the profile photo with the live check-in capture, on the mobile app and on the web dashboard. A match is what gets written to Odoo.
- Why
- A clock-in without identity is how proxy attendance survives. The system of record should store a verified person, not a borrowed phone.
- The trade-off
- The capture has to work on a phone camera and in the dashboard. A failed match is an exception, not a silent success.
- The result
- Attendance that reaches Odoo is tied to the employee on file. Proxy check-ins do not become payroll truth.
06
UX / user flow
Branded sign-in, then a card-based ESS. Help desk, disciplinary, announcements, and 360 feedback use illustrated headers so dense HR modules still feel like products. Attendance combines clock-in with monthly stats. Disciplinary and warning letters expose EN/AR PDFs. 360 feedback is a completed questionnaire with matrix answers, not a dead thank-you screen.
07
Technical architecture
Flutter client and a Next.js dashboard, both on Odoo via oe_hr_ess_mobile_api and bearer session tokens. DeepFace runs the face match at check-in; the verified record is what Odoo stores. Charts hit ESS analytics endpoints. Manager features (My Approvals) require approver rights in Odoo. Sessions persist until logout or expiry. Bilingual document export for letters and payslips. Push and an in-app notification inbox sit on the same record stream as announcements.
08
What I built
- Auth, session, and server configuration
- Home dashboard, insights charts, and alerts
- Time off: balances, requests, calendar
- Payslips with PDF export
- Attendance clock with DeepFace verification against the profile photo
- Next.js HR dashboard on the same Odoo session model
- More hub: profile, loans, custody, HR requests, expenses
- Announcements, notifications, directory, documents, policies, training
- Help desk tickets, appraisals, 360 feedback, disciplinary with EN/AR PDFs
- Manager approvals
09
Trade-offs
We did not build a custom HRIS. Offline-first for every module would have fought Odoo’s permission model. The first product had to be a trustworthy phone for ESS — clock, leave, pay — with satellite modules complete enough that HR did not send people back to the browser for the long tail.
10
Launch
Shipped as HRMS Mobile against Odoo ESS. Versioned product documentation and a user manual were part of the release, not an afterthought — implementers and employees get the same module map.
11
Outcome
Employees can clock, request leave, read pay, file expenses, and follow HR processes on a phone without leaving the Odoo permission model. Exact headcount and adoption sit with each deploying company.
12
What I learned
Enterprise mobile fails when you wrap every desktop menu. It works when you pick the daily jobs, keep the system of record honest, and let the rest live one tap behind. I would pressure-test the More inventory with actual usage before treating every Odoo app as equally worthy of a custom screen.