[{"data":1,"prerenderedAt":1530},["ShallowReactive",2],{"$fzrifqspztpd1":3,"mdc-qfqosf-key":15},{"release":4,"newer":10,"older":12,"page":14},{"tag":5,"name":5,"publishedAt":6,"url":7,"prerelease":8,"markdown":9},"v1.0.9","2026-04-09T19:15:10Z","https:\u002F\u002Fgithub.com\u002Fanhourtec\u002FBookYourPTO-SaaS\u002Freleases\u002Ftag\u002Fv1.0.9",false,"### Major HR Modules\r\n\r\nThis release rounds out the core employee experience with new modules for Performance, Benefits, Training, Onboarding\u002FOffboarding, Assets, Certifications, and more.\r\n\r\n### New Features — Profile & Personal Data\r\n\r\n- **Profile page redesign** — Two-column layout with sidebar vitals (phone, email, LinkedIn, location, status, department, employee #, hire date, tenure, manager, direct reports), tabbed main content, and inline section editing. Each section has its own Edit button that swaps the read view for an inline form with sticky save\u002Fcancel footer.\r\n\r\n- **Inline editing** — Replaces the old modal-based edit flow on the profile page. Per-section edits keep changes scoped (basic info, social links, address, contact, emergency contact, employment, leave allowance, holidays).\r\n\r\n- **Profile completeness indicator** — Auto-calculated progress bar in the sidebar based on 13 key fields. Color-coded (red\u002Famber\u002Fgreen) and hidden once complete. Recalculated on every read so it stays accurate.\r\n\r\n- **Employees can view their own profile** — Employees now have access to `\u002Fusers\u002F{theirOwnId}` to see and edit personal sections. View Files and Documents tabs are hidden for employees.\r\n\r\n- **My Profile navigation** — Replaced the old modal with a direct link from the user menu to the profile page.\r\n\r\n- **Education** — Add multiple education entries with institution, degree (10 types), major, GPA, and date range.\r\n\r\n- **Languages** — Track spoken languages with separate reading\u002Fwriting and speaking proficiency levels.\r\n\r\n- **Certifications** — Add certificates with name, issuing body, credential ID, issued and expiry dates. Auto-marks as expired when past the expiry date. Daily reminder cron sends 30\u002F14\u002F7\u002F0-day notifications + email to the employee and their manager.\r\n\r\n- **Visa \u002F Work Authorization** — Track visa type, country, dates, status, and notes. Auto-expires past-due visas. Daily cron sends 30\u002F14\u002F7\u002F0-day expiry reminders to employee + manager.\r\n\r\n- **Assets** — Track assigned company assets (laptop, badge, phone, etc.) with category, serial number, assigned date, return date, and condition. Searchable category dropdown with custom-category support.\r\n\r\n- **Compensation history** — Salary changes over time with effective date, type, amount, and reason.\r\n\r\n- **Bonuses** — One-off bonus records with date, amount, type, and notes.\r\n\r\n- **Job history** — Position changes (title, department, manager) tracked over time.\r\n\r\n- **Employment status history** — Status changes (Full-time, Part-time, Contract, etc.) over time.\r\n\r\n- **Notes (HR)** — Per-employee notes with three visibility levels: HR Only, Managers, Shared with Employee. Color-coded badges and full audit logging.\r\n\r\n- **Termination tracking** — Termination code, notice given date, projected termination date, ROE\u002FSAT completed date. Inline editable on the Job tab (admin-only).\r\n\r\n- **Marital status, nationality, shirt size** — New fields on the personal tab.\r\n\r\n- **Citizenship Certificate # and Benefit ID** — Encrypted-at-rest fields, masked display, admin-only.\r\n\r\n- **Home email, phone extension, home phone** — Separate from work email and landline.\r\n\r\n- **Social links** — LinkedIn, GitHub, Twitter\u002FX, Facebook with their own profile section.\r\n\r\n- **Emergency contact enhancements** — Full address, email, dropdown for relationship type.\r\n\r\n### New Features — Org Chart & People Directory\r\n\r\n- **Org Chart page** at `\u002Fusers\u002Forgchart` with three views: list (sortable table), directory (grouped by letter\u002Fdepartment\u002Flocation), and an interactive org chart tree.\r\n\r\n- **People navigation link** — Top-level nav for admin, executive, and department head roles.\r\n\r\n- **Directory search** — Search by name, title, email, or employee ID across all three views.\r\n\r\n- **Division and Work Location fields** — Added to user profile, API, and org chart.\r\n\r\n### New Features — Performance Management\r\n\r\n- **Performance Settings** at `\u002Fsettings\u002Fperformance` — Configure goal users (none \u002F all \u002F specific), cascading goals toggle, and 1:1 meeting enablement.\r\n\r\n- **Goals** — Per-employee goal cards with progress slider, status, due date, and category. Expandable cards show a comments section for collaboration.\r\n\r\n- **Goal Comments** — Threaded comments on goals with timestamps and author avatars.\r\n\r\n- **1:1 Meetings** — Recurring 1:1 series with frequency (Weekly\u002FBiweekly\u002FMonthly\u002FOne-time) and first meeting date. Inline view on the profile page with agenda items, side-by-side notes, and private note filtering. Creation\u002Fcancellation emails to participants. Daily reminder cron sends meeting reminders with current agenda.\r\n\r\n### New Features — Training\r\n\r\n- **Training Settings** at `\u002Fsettings\u002Ftraining` — Define training requirements with frequency (One-time, Annual, Every 2\u002F3\u002F5 years), categories, due-from-hire days, required-for filter (All \u002F Department \u002F Role \u002F Specific Employees), URL field, and \"allow self-complete\" toggle.\r\n\r\n- **Training auto-assign** — Required training is automatically assigned to targeted users when created or updated, with calculated due dates from their hire date.\r\n\r\n- **Profile Training tab** — Category-grouped view with inline edit, mark complete, and dismiss actions.\r\n\r\n- **Training reminders cron** — 7\u002F3\u002F1 day reminder emails before due. Notifies employee and manager.\r\n\r\n- **Training overdue cron** — Detects past-due training, updates status, and notifies the employee + manager.\r\n\r\n### New Features — Benefits Administration\r\n\r\n- **Benefits CRUD** — Track benefit plans (medical, dental, vision, life, disability, retirement, etc.) with provider, policy number, coverage, premium, and effective dates.\r\n\r\n- **Profile Benefits tab** — View enrolled benefits with dependents, premiums, and effective dates.\r\n\r\n### New Features — Onboarding & Offboarding\r\n\r\n- **Onboarding Settings** at `\u002Fsettings\u002Fonboarding-templates` — Two tabs: task lists (with icons, drag-to-reorder, per-task assignee, due date type, notification timing, target scope) and New Hire Packet Templates.\r\n\r\n- **Offboarding Settings** at `\u002Fsettings\u002Foffboarding-templates` — Parallel page for offboarding task lists. Type-aware copy throughout (\"On Last Day\" vs \"On Hire Date\", \"before\u002Fafter last day\" vs \"before\u002Fafter hire date\").\r\n\r\n- **New Hire Packet Templates** — Configure arrival time, location, contact person, instructions, \"Get to Know You\" questions, and linked task lists.\r\n\r\n- **Onboarding profile tab** — Per-employee onboarding\u002Foffboarding instances with progress bar, task list, assignee names, color-coded due dates, and category badges. Add Task and Import Task List buttons for admins.\r\n\r\n- **Auto-trigger on hire** — When a new user is created, the default onboarding template auto-creates an instance with all tasks.\r\n\r\n- **Auto-trigger on termination** — When `isActive` flips to false, the default offboarding template auto-creates an instance.\r\n\r\n- **Standalone \u002Fonboarding page** — Active\u002FCompleted\u002FTemplates tabs with progress tracking, task completion, and a stats bar.\r\n\r\n- **Template categories** — Tasks can be tagged Documents, Equipment, Access, Training, or Other with color-coded badges.\r\n\r\n- **Update existing employee tasks** — When admin adds a new task to a template, optionally apply it retroactively to all employees with active onboarding for that template.\r\n\r\n- **Document attachment to tasks** — Admins can attach a document (employee handbook, NDA, policy) to any onboarding task and require it be signed before the task can be completed.\r\n\r\n- **Per-user document copies** — When a sign-required document is attached to an onboarding task, each new hire gets their own personal copy of the document. Each employee signs their own copy independently — no shared multi-signer PDF, no privacy leak between employees. Each employee can re-view their signed copy at any time.\r\n\r\n- **Signature gating on task completion** — Tasks with attached signing-required documents cannot be marked complete until the recipient has actually signed their copy. Admins can override.\r\n\r\n- **Auto due-date calculation** — Task due dates are computed from the employee's hire date (or end date for offboarding) using the task definition's \"X days before\u002Fafter hire date\" rule. Falls back to \"today in the org's timezone\" for users without an explicit hire date so dates always match the operator's local calendar.\r\n\r\n- **Per-task notifications** — In-app and email notifications fire when:\r\n  - An onboarding instance is created (employee gets the full task list)\r\n  - A task is assigned to a specific user (assignee gets a notification)\r\n  - A task is reassigned (new assignee gets notified)\r\n  - An instance is completed (employee + admins get a completion email)\r\n\r\n- **Daily task reminder cron** — Sends 7\u002F3\u002F1\u002F0 day reminders + 1 day overdue for every pending onboarding\u002Foffboarding task. Recipient is the assignee or, if none, the employee being onboarded. Skips offboarded users.\r\n\r\n- **Task detail modal** — Click any task to open a detail modal showing description, assignee, due date, category, attached document, and Mark as Complete \u002F Mark as Incomplete buttons. The modal also surfaces signature status with a clear \"Signature required\" or \"Signed\" badge.\r\n\r\n### New Features — User Offboarding Lifecycle\r\n\r\n- **Deliberate offboarding flow** — Replaces silent `isActive` toggling with `POST \u002Fapi\u002Fusers\u002F:id\u002Foffboard`. Required: end date, termination code. Optional: notice date, ROE completed date, notes, replacement department heads. Runs a transactional cleanup across leaves, time entries, expenses, document assignments, direct reports, department heads, 1:1 series, onboarding instances, projects, tasks, benefit enrollments, and future shifts.\r\n\r\n- **Offboard preview** — `GET \u002Fapi\u002Fusers\u002F:id\u002Foffboard-preview` returns counts of everything that will change so the operator sees a \"what will happen\" summary before clicking.\r\n\r\n- **Reactivate offboarded user** — `POST \u002Fapi\u002Fusers\u002F:id\u002Freactivate` restores login access (subject to seat limits) without undoing the cleanup.\r\n\r\n- **Audit log entry** — Every offboarding writes an OFFBOARD audit entry with the full input + cleanup summary.\r\n\r\n- **Inactive user enforcement** — Approval, time-tracking, and expense endpoints now consistently reject actions from deactivated users.\r\n\r\n- **Cron filtering** — Reminder crons (training, certification, visa, document, 1:1, onboarding) skip offboarded users so they don't receive emails after leaving.\r\n\r\n- **Hard-delete disabled** — `DELETE \u002Fapi\u002Fusers\u002F:id` now returns 410 Gone with a pointer to the offboard endpoint. Hard-deletion would orphan audit logs, leaves, time entries, and reporting chains. GDPR Right-to-Erasure remains available via the privacy data-deletion endpoint.\r\n\r\n### New Features — Auth & Sign-In\r\n\r\n- **Stripe-inspired auth pages** — Redesigned login, register, forgot-password, and reset-password pages with a modern card layout, brand-aware branding, and consistent footer.\r\n\r\n- **Google sign-in \u002F sign-up** — Server endpoints, frontend callback, and route configuration for Google OAuth.\r\n\r\n- **Microsoft OAuth fixes** — Removed the consent prompt that was blocking non-admin users.\r\n\r\n- **Forced logout toast** — Users see a clear toast notification when their session expires instead of being silently kicked to the login page.\r\n\r\n### New Features — Dashboard & Calendar\r\n\r\n- **Hire date and work anniversary on dashboard and calendar** — Hire dates show on the calendar grid and in the dashboard's \"Today\" view. Work anniversaries (every year after hire) display as a separate badge with the year count.\r\n\r\n- **Daily anniversary digest** — Cron sends a daily anniversary email to admins celebrating today's work anniversaries alongside birthdays.\r\n\r\n### Improvements\r\n\r\n- **Profile tab navigation** — Tab bar is now horizontally scrollable on all screen sizes with edge fade gradients and (desktop) chevron scroll buttons. Active tab smoothly scrolls into view on click. Works on mobile without the previous \"More\" dropdown.\r\n\r\n- **Settings navigation** — Added Training, Performance, Onboarding, Offboarding, and Company Directory entries.\r\n\r\n- **Documents Completed tab** — Now shows a \"Signed By\" column instead of \"From\", so you can see who actually signed each document.\r\n\r\n- **Documents list filtering** — Per-user document copies are hidden from the admin's list view by default to avoid clutter. Each employee still sees their own copies, and admins can opt in to see all copies via a query parameter.\r\n\r\n- **Email layout** — Onboarding\u002Foffboarding emails include the full task list with assignees and due dates, plus a \"View My Tasks\" CTA button. All emails use the org's timezone for date display.\r\n\r\n- **Notification deep links** — Onboarding notifications now link to `\u002Fonboarding` (which works for everyone — admins, employees, and assignees) instead of profile-page tabs that were admin-only.\r\n\r\n- **Inline document badges on tasks** — Tasks with attached documents show a green \"Signed\" or amber \"Signature required\" badge directly in the task row, with a click-to-open link.\r\n\r\n### Billing & Usage\r\n\r\n- **Document signing requests count toward billing** — Each document file (1) plus each signing request (1 per recipient) counts toward the monthly document quota. A handbook shared with 10 new hires = 1 file + 10 signing requests = 11 toward the quota. The billing page shows the breakdown (\"X files + Y signing requests\") with a tooltip explaining the math.\r\n\r\n- **Per-user usage attribution** — The Usage Breakdown page now credits documents to the file owner and signing requests to the recipient (the employee who has to sign), not the admin who triggered the assignment. So compliance work appears against the right person's row.\r\n\r\n### Security & Compliance\r\n\r\n- **PII encryption** — New profile fields (`citizenshipCertificateNo`, `benefitIdNumber`, `phoneHome`, `homeEmail`, `offboardedReason`) are encrypted at rest using AES-256-GCM.\r\n\r\n- **Sensitive ID display** — Tax ID, citizenship certificate, and benefit ID display masked (e.g. `XXX-XXXX-1234`) and are visible only to admins.\r\n\r\n- **Rate-limited Google OAuth** — Server endpoints harden against brute-force with rate limiting and input validation.\r\n\r\n- **Permissions-Policy** — Allowed geolocation for own origin so the in-app location features work in modern browsers.\r\n\r\n- **GDPR Right-to-Erasure expansion** — Data anonymizer now clears termination, ROE, and offboarding fields when a user requests deletion.\r\n\r\n- **Department head consistency** — A user can only head one department at a time, enforced via a shared helper across all department endpoints.\r\n\r\n### Bug Fixes\r\n\r\n- **Mobile sidebar scrolling** — Fixed scrolling failure that left the bottom user menu unreachable on production and staging.\r\n\r\n- **Guided tour leakage** — Guided tour tooltips no longer appear on the wrong page after navigation.\r\n\r\n- **Setup page scrollbar** — Removed the scrollbar from the setup page on laptop screens.\r\n\r\n- **Reset-password redirect** — Visiting `\u002Freset-password` without a token now redirects to `\u002Fforgot-password` instead of showing an error.\r\n\r\n- **iCal feed URL undefined** — Fixed the iCal feed URL returning undefined after a page refresh.\r\n\r\n- **Empty-string date crashes** — All API endpoints that accept date strings now safely handle empty strings instead of crashing.\r\n\r\n- **Profile data load on tab navigation** — Profile sub-tabs (training, performance, benefits, onboarding) now correctly fetch their data on initial URL visit.\r\n\r\n- **Birthday and hire date timezone shift** — Date-only fields use UTC date components throughout, so e.g. \"Feb 25\" no longer displays as \"Feb 24\" for users west of UTC.\r\n\r\n- **Onboarding due date off-by-one** — Due dates now calculate from \"today in the organization's timezone\" with UTC date arithmetic, so \"1 day after hire date\" correctly resolves to the right calendar day for users in any timezone.\r\n\r\n- **Receipt limit reset test flakiness** — Stabilized a flaky test that occasionally failed near month boundaries.\r\n\r\n- **Sectional save isolation on the user profile** — Editing one section of the user profile (Job, Personal, Contact, etc.) now reliably leaves the other sections untouched. Comprehensive regression coverage added.\r\n\r\n- **Tenure calculation rewritten** — The \"Years of service\" line on the profile job tab is now calculated through a dedicated utility (`utils\u002Ftenure.ts`) covering future hire dates (\"Starts in N days\u002Fweeks\u002Fmonths\"), the first day (\"First day today\"), short tenures (`Nd`), and longer tenures (years\u002Fmonths). 39 unit tests cover every boundary including new-year rollovers.\r\n\r\n- **Training assignment targeting** — The \"required for\" filter on training courses (All \u002F Department \u002F Role \u002F Specific Employees) is now applied consistently on both create and update paths, so courses only assign to the intended audience. Auto-assignment logic centralized into a shared helper. 39 tests cover the targeting algorithm.\r\n\r\n- **Profile training tab now respects course targeting** — The training tab on a user's profile only displays courses that actually apply to that user.\r\n\r\n- **Profile training tab cleanup** — Removed an incomplete inline editor in favor of the canonical training editor under `\u002Fsettings\u002Ftraining`. Added a read-only details modal so users can review training info directly from their profile.\r\n\r\n- **Recording completed training is now instant** — The \"Record Completed Training\" flow no longer requires a manual page refresh to see the new entry. Optimistic UI update + single-request creation.\r\n\r\n- **Reports To picker respects role hierarchy** — The \"Reports To\" dropdown on the user edit form now only suggests users at or above the employee's level in the hierarchy, excludes inactive users, and reacts live to in-form role changes. The currently saved manager is preserved even if outside the filtered list.\r\n\r\n- **Document links from profile docs tab** — Clicking a document on a user's profile documents tab now opens the right assignment for the current viewer in all cases, while preserving the existing per-user privacy boundary (non-admins still only see their own assignment).\r\n\r\n### Performance & Loading Experience\r\n\r\nThis release dramatically reduces the \"split-second flash\" of empty\u002Ffallback content that used to appear on first navigation, and replaces every page-level loading spinner with a layout-matching skeleton.\r\n\r\n- **Single-request page bootstrap** — Authenticated pages used to need several sequential round trips to load the small set of \"always needed\" data (org settings, timezone, leave types, departments, etc). These have been folded into a single bootstrap request that uses the existing JWT middleware and is org-scoped on every database query. The response is intentionally minimal — no employee data, no leave or balance information, no per-user-per-year content. Comprehensive regression tests lock the response shape and verify no sensitive data is included.\r\n\r\n- **Session-scoped cache** — A reactive cache holds the bootstrap response for the rest of the session, shared across every page. It is dedicated to a single in-flight fetch at a time, refreshed on a short TTL, cleared on logout (so nothing persists across user sessions), and automatically invalidated whenever the user saves a setting that would affect it.\r\n\r\n- **Pre-warming on app start** — A client plugin fires the bootstrap fetch right after auth is ready, so the first page the user lands on already has its layout chrome populated.\r\n\r\n- **Auto-invalidation on settings mutation** — When an admin saves a new timezone or other org-level setting and clicks another page in the sidebar, the new value is reflected immediately — no manual page refresh required. Implemented as a network-layer hook so individual pages don't have to remember to invalidate.\r\n\r\n- **Calendar, dashboard, users, and approvals refactor** — Each of these pages used to make multiple sequential network round trips in `onMounted` before the layout could render. They now run all initial fetches in parallel. Lookups that aren't immediately needed (like the department list for the Group Booking modal) are lazy-loaded only when the user actually needs them.\r\n\r\n- **Dropped redundant auth-readiness waits** — Several composables were waiting for auth-ready state inside individual fetchers, which added per-fetch latency on the hot path. The auth middleware already guarantees ready state by the time `onMounted` fires, so these calls were dead weight and have been removed.\r\n\r\n- **Parallelized leave types load** — Calendar pages now fetch leave types in the same parallel batch as leaves, balances, holidays, and locked dates instead of waiting for the parallel block to finish first.\r\n\r\n- **Skeleton component library** — New `components\u002Fskeletons\u002F` folder with a `Skeleton` primitive (rect\u002Fcircle\u002Fpill\u002Ftext shapes) plus 11 layout-matching composites covering list pages, detail pages, form pages, card grids, the calendar header and grid, the dashboard grid, the user profile, the schedule\u002Ftimesheet board, and the org chart. All fully responsive (mobile-first Tailwind breakpoints). Reusable across the app via props.\r\n\r\n- **Loading spinners replaced across the app** — Every centered spinner that hid the page during first load is now a layout-matching skeleton that holds the layout shell. Pages updated: expenses (list + detail + reports + approvals), documents (list + detail), clients (list + detail), projects (list + detail), training, schedules, admin, onboarding, time-tracking timesheets, time-tracking approvals, users profile, users data drive, users orgchart (view-aware: orgchart\u002Flist\u002Fdirectory each get the right skeleton), settings overview, billing. Plus the approval tab components, reports tab components, and 20 settings sub-page components.\r\n\r\n- **No more \"no projects found\" flash on `\u002Fprojects`** — The empty state used to flash for one frame on every navigation because the loading flag started as false. The initial value was flipped so the skeleton renders from the very first frame.\r\n\r\n- **Org chart card and connector redesign** — Larger node cards, bigger avatars, outlined role badge, bottom-right reports\u002Fcollapse toggle, dot-grid card background, smoother bezier connector curves, search input with match dimming, expand-all\u002Fcollapse-all buttons, and per-node collapse toggles.\r\n\r\n### Browser Compatibility\r\n\r\n- **PDF rendering on older browsers** — The document signing flow could fail on browsers released before early 2025 due to a JavaScript syntax feature used by the modern PDF.js build. Switched the application to PDF.js's officially supported legacy build, which targets ES2020 and works on every browser from 2021 forward (Chrome 88+, Firefox 78+, Safari 14+). The legacy build is built from the same source as the modern build and receives the same security patches in lockstep from Mozilla.\r\n\r\n- **PDF.js version pinning** — Tightened the dependency range so future patch releases land but a minor version bump (which could re-raise the minimum browser target) requires an explicit, reviewed upgrade.\r\n\r\n",{"tag":11,"name":11},"v1.0.10",{"tag":13,"name":13},"v1.0.8",2,{"data":16,"body":17},{},{"type":18,"children":19},"root",[20,29,35,41,266,272,323,329,379,385,445,451,474,480,688,694,804,810,853,859,882,888,969,975,998,1004,1112,1118,1340,1346,1351,1501,1507],{"type":21,"tag":22,"props":23,"children":25},"element","h3",{"id":24},"major-hr-modules",[26],{"type":27,"value":28},"text","Major HR Modules",{"type":21,"tag":30,"props":31,"children":32},"p",{},[33],{"type":27,"value":34},"This release rounds out the core employee experience with new modules for Performance, Benefits, Training, Onboarding\u002FOffboarding, Assets, Certifications, and more.",{"type":21,"tag":22,"props":36,"children":38},{"id":37},"new-features-profile-personal-data",[39],{"type":27,"value":40},"New Features — Profile & Personal Data",{"type":21,"tag":42,"props":43,"children":44},"ul",{},[45,57,67,77,96,106,116,126,136,146,156,166,176,186,196,206,216,226,236,246,256],{"type":21,"tag":46,"props":47,"children":48},"li",{},[49,55],{"type":21,"tag":50,"props":51,"children":52},"strong",{},[53],{"type":27,"value":54},"Profile page redesign",{"type":27,"value":56}," — Two-column layout with sidebar vitals (phone, email, LinkedIn, location, status, department, employee #, hire date, tenure, manager, direct reports), tabbed main content, and inline section editing. Each section has its own Edit button that swaps the read view for an inline form with sticky save\u002Fcancel footer.",{"type":21,"tag":46,"props":58,"children":59},{},[60,65],{"type":21,"tag":50,"props":61,"children":62},{},[63],{"type":27,"value":64},"Inline editing",{"type":27,"value":66}," — Replaces the old modal-based edit flow on the profile page. Per-section edits keep changes scoped (basic info, social links, address, contact, emergency contact, employment, leave allowance, holidays).",{"type":21,"tag":46,"props":68,"children":69},{},[70,75],{"type":21,"tag":50,"props":71,"children":72},{},[73],{"type":27,"value":74},"Profile completeness indicator",{"type":27,"value":76}," — Auto-calculated progress bar in the sidebar based on 13 key fields. Color-coded (red\u002Famber\u002Fgreen) and hidden once complete. Recalculated on every read so it stays accurate.",{"type":21,"tag":46,"props":78,"children":79},{},[80,85,87,94],{"type":21,"tag":50,"props":81,"children":82},{},[83],{"type":27,"value":84},"Employees can view their own profile",{"type":27,"value":86}," — Employees now have access to ",{"type":21,"tag":88,"props":89,"children":91},"code",{"className":90},[],[92],{"type":27,"value":93},"\u002Fusers\u002F{theirOwnId}",{"type":27,"value":95}," to see and edit personal sections. View Files and Documents tabs are hidden for employees.",{"type":21,"tag":46,"props":97,"children":98},{},[99,104],{"type":21,"tag":50,"props":100,"children":101},{},[102],{"type":27,"value":103},"My Profile navigation",{"type":27,"value":105}," — Replaced the old modal with a direct link from the user menu to the profile page.",{"type":21,"tag":46,"props":107,"children":108},{},[109,114],{"type":21,"tag":50,"props":110,"children":111},{},[112],{"type":27,"value":113},"Education",{"type":27,"value":115}," — Add multiple education entries with institution, degree (10 types), major, GPA, and date range.",{"type":21,"tag":46,"props":117,"children":118},{},[119,124],{"type":21,"tag":50,"props":120,"children":121},{},[122],{"type":27,"value":123},"Languages",{"type":27,"value":125}," — Track spoken languages with separate reading\u002Fwriting and speaking proficiency levels.",{"type":21,"tag":46,"props":127,"children":128},{},[129,134],{"type":21,"tag":50,"props":130,"children":131},{},[132],{"type":27,"value":133},"Certifications",{"type":27,"value":135}," — Add certificates with name, issuing body, credential ID, issued and expiry dates. Auto-marks as expired when past the expiry date. Daily reminder cron sends 30\u002F14\u002F7\u002F0-day notifications + email to the employee and their manager.",{"type":21,"tag":46,"props":137,"children":138},{},[139,144],{"type":21,"tag":50,"props":140,"children":141},{},[142],{"type":27,"value":143},"Visa \u002F Work Authorization",{"type":27,"value":145}," — Track visa type, country, dates, status, and notes. Auto-expires past-due visas. Daily cron sends 30\u002F14\u002F7\u002F0-day expiry reminders to employee + manager.",{"type":21,"tag":46,"props":147,"children":148},{},[149,154],{"type":21,"tag":50,"props":150,"children":151},{},[152],{"type":27,"value":153},"Assets",{"type":27,"value":155}," — Track assigned company assets (laptop, badge, phone, etc.) with category, serial number, assigned date, return date, and condition. Searchable category dropdown with custom-category support.",{"type":21,"tag":46,"props":157,"children":158},{},[159,164],{"type":21,"tag":50,"props":160,"children":161},{},[162],{"type":27,"value":163},"Compensation history",{"type":27,"value":165}," — Salary changes over time with effective date, type, amount, and reason.",{"type":21,"tag":46,"props":167,"children":168},{},[169,174],{"type":21,"tag":50,"props":170,"children":171},{},[172],{"type":27,"value":173},"Bonuses",{"type":27,"value":175}," — One-off bonus records with date, amount, type, and notes.",{"type":21,"tag":46,"props":177,"children":178},{},[179,184],{"type":21,"tag":50,"props":180,"children":181},{},[182],{"type":27,"value":183},"Job history",{"type":27,"value":185}," — Position changes (title, department, manager) tracked over time.",{"type":21,"tag":46,"props":187,"children":188},{},[189,194],{"type":21,"tag":50,"props":190,"children":191},{},[192],{"type":27,"value":193},"Employment status history",{"type":27,"value":195}," — Status changes (Full-time, Part-time, Contract, etc.) over time.",{"type":21,"tag":46,"props":197,"children":198},{},[199,204],{"type":21,"tag":50,"props":200,"children":201},{},[202],{"type":27,"value":203},"Notes (HR)",{"type":27,"value":205}," — Per-employee notes with three visibility levels: HR Only, Managers, Shared with Employee. Color-coded badges and full audit logging.",{"type":21,"tag":46,"props":207,"children":208},{},[209,214],{"type":21,"tag":50,"props":210,"children":211},{},[212],{"type":27,"value":213},"Termination tracking",{"type":27,"value":215}," — Termination code, notice given date, projected termination date, ROE\u002FSAT completed date. Inline editable on the Job tab (admin-only).",{"type":21,"tag":46,"props":217,"children":218},{},[219,224],{"type":21,"tag":50,"props":220,"children":221},{},[222],{"type":27,"value":223},"Marital status, nationality, shirt size",{"type":27,"value":225}," — New fields on the personal tab.",{"type":21,"tag":46,"props":227,"children":228},{},[229,234],{"type":21,"tag":50,"props":230,"children":231},{},[232],{"type":27,"value":233},"Citizenship Certificate # and Benefit ID",{"type":27,"value":235}," — Encrypted-at-rest fields, masked display, admin-only.",{"type":21,"tag":46,"props":237,"children":238},{},[239,244],{"type":21,"tag":50,"props":240,"children":241},{},[242],{"type":27,"value":243},"Home email, phone extension, home phone",{"type":27,"value":245}," — Separate from work email and landline.",{"type":21,"tag":46,"props":247,"children":248},{},[249,254],{"type":21,"tag":50,"props":250,"children":251},{},[252],{"type":27,"value":253},"Social links",{"type":27,"value":255}," — LinkedIn, GitHub, Twitter\u002FX, Facebook with their own profile section.",{"type":21,"tag":46,"props":257,"children":258},{},[259,264],{"type":21,"tag":50,"props":260,"children":261},{},[262],{"type":27,"value":263},"Emergency contact enhancements",{"type":27,"value":265}," — Full address, email, dropdown for relationship type.",{"type":21,"tag":22,"props":267,"children":269},{"id":268},"new-features-org-chart-people-directory",[270],{"type":27,"value":271},"New Features — Org Chart & People Directory",{"type":21,"tag":42,"props":273,"children":274},{},[275,293,303,313],{"type":21,"tag":46,"props":276,"children":277},{},[278,283,285,291],{"type":21,"tag":50,"props":279,"children":280},{},[281],{"type":27,"value":282},"Org Chart page",{"type":27,"value":284}," at ",{"type":21,"tag":88,"props":286,"children":288},{"className":287},[],[289],{"type":27,"value":290},"\u002Fusers\u002Forgchart",{"type":27,"value":292}," with three views: list (sortable table), directory (grouped by letter\u002Fdepartment\u002Flocation), and an interactive org chart tree.",{"type":21,"tag":46,"props":294,"children":295},{},[296,301],{"type":21,"tag":50,"props":297,"children":298},{},[299],{"type":27,"value":300},"People navigation link",{"type":27,"value":302}," — Top-level nav for admin, executive, and department head roles.",{"type":21,"tag":46,"props":304,"children":305},{},[306,311],{"type":21,"tag":50,"props":307,"children":308},{},[309],{"type":27,"value":310},"Directory search",{"type":27,"value":312}," — Search by name, title, email, or employee ID across all three views.",{"type":21,"tag":46,"props":314,"children":315},{},[316,321],{"type":21,"tag":50,"props":317,"children":318},{},[319],{"type":27,"value":320},"Division and Work Location fields",{"type":27,"value":322}," — Added to user profile, API, and org chart.",{"type":21,"tag":22,"props":324,"children":326},{"id":325},"new-features-performance-management",[327],{"type":27,"value":328},"New Features — Performance Management",{"type":21,"tag":42,"props":330,"children":331},{},[332,349,359,369],{"type":21,"tag":46,"props":333,"children":334},{},[335,340,341,347],{"type":21,"tag":50,"props":336,"children":337},{},[338],{"type":27,"value":339},"Performance Settings",{"type":27,"value":284},{"type":21,"tag":88,"props":342,"children":344},{"className":343},[],[345],{"type":27,"value":346},"\u002Fsettings\u002Fperformance",{"type":27,"value":348}," — Configure goal users (none \u002F all \u002F specific), cascading goals toggle, and 1:1 meeting enablement.",{"type":21,"tag":46,"props":350,"children":351},{},[352,357],{"type":21,"tag":50,"props":353,"children":354},{},[355],{"type":27,"value":356},"Goals",{"type":27,"value":358}," — Per-employee goal cards with progress slider, status, due date, and category. Expandable cards show a comments section for collaboration.",{"type":21,"tag":46,"props":360,"children":361},{},[362,367],{"type":21,"tag":50,"props":363,"children":364},{},[365],{"type":27,"value":366},"Goal Comments",{"type":27,"value":368}," — Threaded comments on goals with timestamps and author avatars.",{"type":21,"tag":46,"props":370,"children":371},{},[372,377],{"type":21,"tag":50,"props":373,"children":374},{},[375],{"type":27,"value":376},"1:1 Meetings",{"type":27,"value":378}," — Recurring 1:1 series with frequency (Weekly\u002FBiweekly\u002FMonthly\u002FOne-time) and first meeting date. Inline view on the profile page with agenda items, side-by-side notes, and private note filtering. Creation\u002Fcancellation emails to participants. Daily reminder cron sends meeting reminders with current agenda.",{"type":21,"tag":22,"props":380,"children":382},{"id":381},"new-features-training",[383],{"type":27,"value":384},"New Features — Training",{"type":21,"tag":42,"props":386,"children":387},{},[388,405,415,425,435],{"type":21,"tag":46,"props":389,"children":390},{},[391,396,397,403],{"type":21,"tag":50,"props":392,"children":393},{},[394],{"type":27,"value":395},"Training Settings",{"type":27,"value":284},{"type":21,"tag":88,"props":398,"children":400},{"className":399},[],[401],{"type":27,"value":402},"\u002Fsettings\u002Ftraining",{"type":27,"value":404}," — Define training requirements with frequency (One-time, Annual, Every 2\u002F3\u002F5 years), categories, due-from-hire days, required-for filter (All \u002F Department \u002F Role \u002F Specific Employees), URL field, and \"allow self-complete\" toggle.",{"type":21,"tag":46,"props":406,"children":407},{},[408,413],{"type":21,"tag":50,"props":409,"children":410},{},[411],{"type":27,"value":412},"Training auto-assign",{"type":27,"value":414}," — Required training is automatically assigned to targeted users when created or updated, with calculated due dates from their hire date.",{"type":21,"tag":46,"props":416,"children":417},{},[418,423],{"type":21,"tag":50,"props":419,"children":420},{},[421],{"type":27,"value":422},"Profile Training tab",{"type":27,"value":424}," — Category-grouped view with inline edit, mark complete, and dismiss actions.",{"type":21,"tag":46,"props":426,"children":427},{},[428,433],{"type":21,"tag":50,"props":429,"children":430},{},[431],{"type":27,"value":432},"Training reminders cron",{"type":27,"value":434}," — 7\u002F3\u002F1 day reminder emails before due. Notifies employee and manager.",{"type":21,"tag":46,"props":436,"children":437},{},[438,443],{"type":21,"tag":50,"props":439,"children":440},{},[441],{"type":27,"value":442},"Training overdue cron",{"type":27,"value":444}," — Detects past-due training, updates status, and notifies the employee + manager.",{"type":21,"tag":22,"props":446,"children":448},{"id":447},"new-features-benefits-administration",[449],{"type":27,"value":450},"New Features — Benefits Administration",{"type":21,"tag":42,"props":452,"children":453},{},[454,464],{"type":21,"tag":46,"props":455,"children":456},{},[457,462],{"type":21,"tag":50,"props":458,"children":459},{},[460],{"type":27,"value":461},"Benefits CRUD",{"type":27,"value":463}," — Track benefit plans (medical, dental, vision, life, disability, retirement, etc.) with provider, policy number, coverage, premium, and effective dates.",{"type":21,"tag":46,"props":465,"children":466},{},[467,472],{"type":21,"tag":50,"props":468,"children":469},{},[470],{"type":27,"value":471},"Profile Benefits tab",{"type":27,"value":473}," — View enrolled benefits with dependents, premiums, and effective dates.",{"type":21,"tag":22,"props":475,"children":477},{"id":476},"new-features-onboarding-offboarding",[478],{"type":27,"value":479},"New Features — Onboarding & Offboarding",{"type":21,"tag":42,"props":481,"children":482},{},[483,500,517,527,537,547,565,575,585,595,605,615,625,635,668,678],{"type":21,"tag":46,"props":484,"children":485},{},[486,491,492,498],{"type":21,"tag":50,"props":487,"children":488},{},[489],{"type":27,"value":490},"Onboarding Settings",{"type":27,"value":284},{"type":21,"tag":88,"props":493,"children":495},{"className":494},[],[496],{"type":27,"value":497},"\u002Fsettings\u002Fonboarding-templates",{"type":27,"value":499}," — Two tabs: task lists (with icons, drag-to-reorder, per-task assignee, due date type, notification timing, target scope) and New Hire Packet Templates.",{"type":21,"tag":46,"props":501,"children":502},{},[503,508,509,515],{"type":21,"tag":50,"props":504,"children":505},{},[506],{"type":27,"value":507},"Offboarding Settings",{"type":27,"value":284},{"type":21,"tag":88,"props":510,"children":512},{"className":511},[],[513],{"type":27,"value":514},"\u002Fsettings\u002Foffboarding-templates",{"type":27,"value":516}," — Parallel page for offboarding task lists. Type-aware copy throughout (\"On Last Day\" vs \"On Hire Date\", \"before\u002Fafter last day\" vs \"before\u002Fafter hire date\").",{"type":21,"tag":46,"props":518,"children":519},{},[520,525],{"type":21,"tag":50,"props":521,"children":522},{},[523],{"type":27,"value":524},"New Hire Packet Templates",{"type":27,"value":526}," — Configure arrival time, location, contact person, instructions, \"Get to Know You\" questions, and linked task lists.",{"type":21,"tag":46,"props":528,"children":529},{},[530,535],{"type":21,"tag":50,"props":531,"children":532},{},[533],{"type":27,"value":534},"Onboarding profile tab",{"type":27,"value":536}," — Per-employee onboarding\u002Foffboarding instances with progress bar, task list, assignee names, color-coded due dates, and category badges. Add Task and Import Task List buttons for admins.",{"type":21,"tag":46,"props":538,"children":539},{},[540,545],{"type":21,"tag":50,"props":541,"children":542},{},[543],{"type":27,"value":544},"Auto-trigger on hire",{"type":27,"value":546}," — When a new user is created, the default onboarding template auto-creates an instance with all tasks.",{"type":21,"tag":46,"props":548,"children":549},{},[550,555,557,563],{"type":21,"tag":50,"props":551,"children":552},{},[553],{"type":27,"value":554},"Auto-trigger on termination",{"type":27,"value":556}," — When ",{"type":21,"tag":88,"props":558,"children":560},{"className":559},[],[561],{"type":27,"value":562},"isActive",{"type":27,"value":564}," flips to false, the default offboarding template auto-creates an instance.",{"type":21,"tag":46,"props":566,"children":567},{},[568,573],{"type":21,"tag":50,"props":569,"children":570},{},[571],{"type":27,"value":572},"Standalone \u002Fonboarding page",{"type":27,"value":574}," — Active\u002FCompleted\u002FTemplates tabs with progress tracking, task completion, and a stats bar.",{"type":21,"tag":46,"props":576,"children":577},{},[578,583],{"type":21,"tag":50,"props":579,"children":580},{},[581],{"type":27,"value":582},"Template categories",{"type":27,"value":584}," — Tasks can be tagged Documents, Equipment, Access, Training, or Other with color-coded badges.",{"type":21,"tag":46,"props":586,"children":587},{},[588,593],{"type":21,"tag":50,"props":589,"children":590},{},[591],{"type":27,"value":592},"Update existing employee tasks",{"type":27,"value":594}," — When admin adds a new task to a template, optionally apply it retroactively to all employees with active onboarding for that template.",{"type":21,"tag":46,"props":596,"children":597},{},[598,603],{"type":21,"tag":50,"props":599,"children":600},{},[601],{"type":27,"value":602},"Document attachment to tasks",{"type":27,"value":604}," — Admins can attach a document (employee handbook, NDA, policy) to any onboarding task and require it be signed before the task can be completed.",{"type":21,"tag":46,"props":606,"children":607},{},[608,613],{"type":21,"tag":50,"props":609,"children":610},{},[611],{"type":27,"value":612},"Per-user document copies",{"type":27,"value":614}," — When a sign-required document is attached to an onboarding task, each new hire gets their own personal copy of the document. Each employee signs their own copy independently — no shared multi-signer PDF, no privacy leak between employees. Each employee can re-view their signed copy at any time.",{"type":21,"tag":46,"props":616,"children":617},{},[618,623],{"type":21,"tag":50,"props":619,"children":620},{},[621],{"type":27,"value":622},"Signature gating on task completion",{"type":27,"value":624}," — Tasks with attached signing-required documents cannot be marked complete until the recipient has actually signed their copy. Admins can override.",{"type":21,"tag":46,"props":626,"children":627},{},[628,633],{"type":21,"tag":50,"props":629,"children":630},{},[631],{"type":27,"value":632},"Auto due-date calculation",{"type":27,"value":634}," — Task due dates are computed from the employee's hire date (or end date for offboarding) using the task definition's \"X days before\u002Fafter hire date\" rule. Falls back to \"today in the org's timezone\" for users without an explicit hire date so dates always match the operator's local calendar.",{"type":21,"tag":46,"props":636,"children":637},{},[638,643,645],{"type":21,"tag":50,"props":639,"children":640},{},[641],{"type":27,"value":642},"Per-task notifications",{"type":27,"value":644}," — In-app and email notifications fire when:",{"type":21,"tag":42,"props":646,"children":647},{},[648,653,658,663],{"type":21,"tag":46,"props":649,"children":650},{},[651],{"type":27,"value":652},"An onboarding instance is created (employee gets the full task list)",{"type":21,"tag":46,"props":654,"children":655},{},[656],{"type":27,"value":657},"A task is assigned to a specific user (assignee gets a notification)",{"type":21,"tag":46,"props":659,"children":660},{},[661],{"type":27,"value":662},"A task is reassigned (new assignee gets notified)",{"type":21,"tag":46,"props":664,"children":665},{},[666],{"type":27,"value":667},"An instance is completed (employee + admins get a completion email)",{"type":21,"tag":46,"props":669,"children":670},{},[671,676],{"type":21,"tag":50,"props":672,"children":673},{},[674],{"type":27,"value":675},"Daily task reminder cron",{"type":27,"value":677}," — Sends 7\u002F3\u002F1\u002F0 day reminders + 1 day overdue for every pending onboarding\u002Foffboarding task. Recipient is the assignee or, if none, the employee being onboarded. Skips offboarded users.",{"type":21,"tag":46,"props":679,"children":680},{},[681,686],{"type":21,"tag":50,"props":682,"children":683},{},[684],{"type":27,"value":685},"Task detail modal",{"type":27,"value":687}," — Click any task to open a detail modal showing description, assignee, due date, category, attached document, and Mark as Complete \u002F Mark as Incomplete buttons. The modal also surfaces signature status with a clear \"Signature required\" or \"Signed\" badge.",{"type":21,"tag":22,"props":689,"children":691},{"id":690},"new-features-user-offboarding-lifecycle",[692],{"type":27,"value":693},"New Features — User Offboarding Lifecycle",{"type":21,"tag":42,"props":695,"children":696},{},[697,722,740,757,767,777,787],{"type":21,"tag":46,"props":698,"children":699},{},[700,705,707,712,714,720],{"type":21,"tag":50,"props":701,"children":702},{},[703],{"type":27,"value":704},"Deliberate offboarding flow",{"type":27,"value":706}," — Replaces silent ",{"type":21,"tag":88,"props":708,"children":710},{"className":709},[],[711],{"type":27,"value":562},{"type":27,"value":713}," toggling with ",{"type":21,"tag":88,"props":715,"children":717},{"className":716},[],[718],{"type":27,"value":719},"POST \u002Fapi\u002Fusers\u002F:id\u002Foffboard",{"type":27,"value":721},". Required: end date, termination code. Optional: notice date, ROE completed date, notes, replacement department heads. Runs a transactional cleanup across leaves, time entries, expenses, document assignments, direct reports, department heads, 1:1 series, onboarding instances, projects, tasks, benefit enrollments, and future shifts.",{"type":21,"tag":46,"props":723,"children":724},{},[725,730,732,738],{"type":21,"tag":50,"props":726,"children":727},{},[728],{"type":27,"value":729},"Offboard preview",{"type":27,"value":731}," — ",{"type":21,"tag":88,"props":733,"children":735},{"className":734},[],[736],{"type":27,"value":737},"GET \u002Fapi\u002Fusers\u002F:id\u002Foffboard-preview",{"type":27,"value":739}," returns counts of everything that will change so the operator sees a \"what will happen\" summary before clicking.",{"type":21,"tag":46,"props":741,"children":742},{},[743,748,749,755],{"type":21,"tag":50,"props":744,"children":745},{},[746],{"type":27,"value":747},"Reactivate offboarded user",{"type":27,"value":731},{"type":21,"tag":88,"props":750,"children":752},{"className":751},[],[753],{"type":27,"value":754},"POST \u002Fapi\u002Fusers\u002F:id\u002Freactivate",{"type":27,"value":756}," restores login access (subject to seat limits) without undoing the cleanup.",{"type":21,"tag":46,"props":758,"children":759},{},[760,765],{"type":21,"tag":50,"props":761,"children":762},{},[763],{"type":27,"value":764},"Audit log entry",{"type":27,"value":766}," — Every offboarding writes an OFFBOARD audit entry with the full input + cleanup summary.",{"type":21,"tag":46,"props":768,"children":769},{},[770,775],{"type":21,"tag":50,"props":771,"children":772},{},[773],{"type":27,"value":774},"Inactive user enforcement",{"type":27,"value":776}," — Approval, time-tracking, and expense endpoints now consistently reject actions from deactivated users.",{"type":21,"tag":46,"props":778,"children":779},{},[780,785],{"type":21,"tag":50,"props":781,"children":782},{},[783],{"type":27,"value":784},"Cron filtering",{"type":27,"value":786}," — Reminder crons (training, certification, visa, document, 1:1, onboarding) skip offboarded users so they don't receive emails after leaving.",{"type":21,"tag":46,"props":788,"children":789},{},[790,795,796,802],{"type":21,"tag":50,"props":791,"children":792},{},[793],{"type":27,"value":794},"Hard-delete disabled",{"type":27,"value":731},{"type":21,"tag":88,"props":797,"children":799},{"className":798},[],[800],{"type":27,"value":801},"DELETE \u002Fapi\u002Fusers\u002F:id",{"type":27,"value":803}," now returns 410 Gone with a pointer to the offboard endpoint. Hard-deletion would orphan audit logs, leaves, time entries, and reporting chains. GDPR Right-to-Erasure remains available via the privacy data-deletion endpoint.",{"type":21,"tag":22,"props":805,"children":807},{"id":806},"new-features-auth-sign-in",[808],{"type":27,"value":809},"New Features — Auth & Sign-In",{"type":21,"tag":42,"props":811,"children":812},{},[813,823,833,843],{"type":21,"tag":46,"props":814,"children":815},{},[816,821],{"type":21,"tag":50,"props":817,"children":818},{},[819],{"type":27,"value":820},"Stripe-inspired auth pages",{"type":27,"value":822}," — Redesigned login, register, forgot-password, and reset-password pages with a modern card layout, brand-aware branding, and consistent footer.",{"type":21,"tag":46,"props":824,"children":825},{},[826,831],{"type":21,"tag":50,"props":827,"children":828},{},[829],{"type":27,"value":830},"Google sign-in \u002F sign-up",{"type":27,"value":832}," — Server endpoints, frontend callback, and route configuration for Google OAuth.",{"type":21,"tag":46,"props":834,"children":835},{},[836,841],{"type":21,"tag":50,"props":837,"children":838},{},[839],{"type":27,"value":840},"Microsoft OAuth fixes",{"type":27,"value":842}," — Removed the consent prompt that was blocking non-admin users.",{"type":21,"tag":46,"props":844,"children":845},{},[846,851],{"type":21,"tag":50,"props":847,"children":848},{},[849],{"type":27,"value":850},"Forced logout toast",{"type":27,"value":852}," — Users see a clear toast notification when their session expires instead of being silently kicked to the login page.",{"type":21,"tag":22,"props":854,"children":856},{"id":855},"new-features-dashboard-calendar",[857],{"type":27,"value":858},"New Features — Dashboard & Calendar",{"type":21,"tag":42,"props":860,"children":861},{},[862,872],{"type":21,"tag":46,"props":863,"children":864},{},[865,870],{"type":21,"tag":50,"props":866,"children":867},{},[868],{"type":27,"value":869},"Hire date and work anniversary on dashboard and calendar",{"type":27,"value":871}," — Hire dates show on the calendar grid and in the dashboard's \"Today\" view. Work anniversaries (every year after hire) display as a separate badge with the year count.",{"type":21,"tag":46,"props":873,"children":874},{},[875,880],{"type":21,"tag":50,"props":876,"children":877},{},[878],{"type":27,"value":879},"Daily anniversary digest",{"type":27,"value":881}," — Cron sends a daily anniversary email to admins celebrating today's work anniversaries alongside birthdays.",{"type":21,"tag":22,"props":883,"children":885},{"id":884},"improvements",[886],{"type":27,"value":887},"Improvements",{"type":21,"tag":42,"props":889,"children":890},{},[891,901,911,921,931,941,959],{"type":21,"tag":46,"props":892,"children":893},{},[894,899],{"type":21,"tag":50,"props":895,"children":896},{},[897],{"type":27,"value":898},"Profile tab navigation",{"type":27,"value":900}," — Tab bar is now horizontally scrollable on all screen sizes with edge fade gradients and (desktop) chevron scroll buttons. Active tab smoothly scrolls into view on click. Works on mobile without the previous \"More\" dropdown.",{"type":21,"tag":46,"props":902,"children":903},{},[904,909],{"type":21,"tag":50,"props":905,"children":906},{},[907],{"type":27,"value":908},"Settings navigation",{"type":27,"value":910}," — Added Training, Performance, Onboarding, Offboarding, and Company Directory entries.",{"type":21,"tag":46,"props":912,"children":913},{},[914,919],{"type":21,"tag":50,"props":915,"children":916},{},[917],{"type":27,"value":918},"Documents Completed tab",{"type":27,"value":920}," — Now shows a \"Signed By\" column instead of \"From\", so you can see who actually signed each document.",{"type":21,"tag":46,"props":922,"children":923},{},[924,929],{"type":21,"tag":50,"props":925,"children":926},{},[927],{"type":27,"value":928},"Documents list filtering",{"type":27,"value":930}," — Per-user document copies are hidden from the admin's list view by default to avoid clutter. Each employee still sees their own copies, and admins can opt in to see all copies via a query parameter.",{"type":21,"tag":46,"props":932,"children":933},{},[934,939],{"type":21,"tag":50,"props":935,"children":936},{},[937],{"type":27,"value":938},"Email layout",{"type":27,"value":940}," — Onboarding\u002Foffboarding emails include the full task list with assignees and due dates, plus a \"View My Tasks\" CTA button. All emails use the org's timezone for date display.",{"type":21,"tag":46,"props":942,"children":943},{},[944,949,951,957],{"type":21,"tag":50,"props":945,"children":946},{},[947],{"type":27,"value":948},"Notification deep links",{"type":27,"value":950}," — Onboarding notifications now link to ",{"type":21,"tag":88,"props":952,"children":954},{"className":953},[],[955],{"type":27,"value":956},"\u002Fonboarding",{"type":27,"value":958}," (which works for everyone — admins, employees, and assignees) instead of profile-page tabs that were admin-only.",{"type":21,"tag":46,"props":960,"children":961},{},[962,967],{"type":21,"tag":50,"props":963,"children":964},{},[965],{"type":27,"value":966},"Inline document badges on tasks",{"type":27,"value":968}," — Tasks with attached documents show a green \"Signed\" or amber \"Signature required\" badge directly in the task row, with a click-to-open link.",{"type":21,"tag":22,"props":970,"children":972},{"id":971},"billing-usage",[973],{"type":27,"value":974},"Billing & Usage",{"type":21,"tag":42,"props":976,"children":977},{},[978,988],{"type":21,"tag":46,"props":979,"children":980},{},[981,986],{"type":21,"tag":50,"props":982,"children":983},{},[984],{"type":27,"value":985},"Document signing requests count toward billing",{"type":27,"value":987}," — Each document file (1) plus each signing request (1 per recipient) counts toward the monthly document quota. A handbook shared with 10 new hires = 1 file + 10 signing requests = 11 toward the quota. The billing page shows the breakdown (\"X files + Y signing requests\") with a tooltip explaining the math.",{"type":21,"tag":46,"props":989,"children":990},{},[991,996],{"type":21,"tag":50,"props":992,"children":993},{},[994],{"type":27,"value":995},"Per-user usage attribution",{"type":27,"value":997}," — The Usage Breakdown page now credits documents to the file owner and signing requests to the recipient (the employee who has to sign), not the admin who triggered the assignment. So compliance work appears against the right person's row.",{"type":21,"tag":22,"props":999,"children":1001},{"id":1000},"security-compliance",[1002],{"type":27,"value":1003},"Security & Compliance",{"type":21,"tag":42,"props":1005,"children":1006},{},[1007,1054,1072,1082,1092,1102],{"type":21,"tag":46,"props":1008,"children":1009},{},[1010,1015,1017,1023,1025,1031,1032,1038,1039,1045,1046,1052],{"type":21,"tag":50,"props":1011,"children":1012},{},[1013],{"type":27,"value":1014},"PII encryption",{"type":27,"value":1016}," — New profile fields (",{"type":21,"tag":88,"props":1018,"children":1020},{"className":1019},[],[1021],{"type":27,"value":1022},"citizenshipCertificateNo",{"type":27,"value":1024},", ",{"type":21,"tag":88,"props":1026,"children":1028},{"className":1027},[],[1029],{"type":27,"value":1030},"benefitIdNumber",{"type":27,"value":1024},{"type":21,"tag":88,"props":1033,"children":1035},{"className":1034},[],[1036],{"type":27,"value":1037},"phoneHome",{"type":27,"value":1024},{"type":21,"tag":88,"props":1040,"children":1042},{"className":1041},[],[1043],{"type":27,"value":1044},"homeEmail",{"type":27,"value":1024},{"type":21,"tag":88,"props":1047,"children":1049},{"className":1048},[],[1050],{"type":27,"value":1051},"offboardedReason",{"type":27,"value":1053},") are encrypted at rest using AES-256-GCM.",{"type":21,"tag":46,"props":1055,"children":1056},{},[1057,1062,1064,1070],{"type":21,"tag":50,"props":1058,"children":1059},{},[1060],{"type":27,"value":1061},"Sensitive ID display",{"type":27,"value":1063}," — Tax ID, citizenship certificate, and benefit ID display masked (e.g. ",{"type":21,"tag":88,"props":1065,"children":1067},{"className":1066},[],[1068],{"type":27,"value":1069},"XXX-XXXX-1234",{"type":27,"value":1071},") and are visible only to admins.",{"type":21,"tag":46,"props":1073,"children":1074},{},[1075,1080],{"type":21,"tag":50,"props":1076,"children":1077},{},[1078],{"type":27,"value":1079},"Rate-limited Google OAuth",{"type":27,"value":1081}," — Server endpoints harden against brute-force with rate limiting and input validation.",{"type":21,"tag":46,"props":1083,"children":1084},{},[1085,1090],{"type":21,"tag":50,"props":1086,"children":1087},{},[1088],{"type":27,"value":1089},"Permissions-Policy",{"type":27,"value":1091}," — Allowed geolocation for own origin so the in-app location features work in modern browsers.",{"type":21,"tag":46,"props":1093,"children":1094},{},[1095,1100],{"type":21,"tag":50,"props":1096,"children":1097},{},[1098],{"type":27,"value":1099},"GDPR Right-to-Erasure expansion",{"type":27,"value":1101}," — Data anonymizer now clears termination, ROE, and offboarding fields when a user requests deletion.",{"type":21,"tag":46,"props":1103,"children":1104},{},[1105,1110],{"type":21,"tag":50,"props":1106,"children":1107},{},[1108],{"type":27,"value":1109},"Department head consistency",{"type":27,"value":1111}," — A user can only head one department at a time, enforced via a shared helper across all department endpoints.",{"type":21,"tag":22,"props":1113,"children":1115},{"id":1114},"bug-fixes",[1116],{"type":27,"value":1117},"Bug Fixes",{"type":21,"tag":42,"props":1119,"children":1120},{},[1121,1131,1141,1151,1177,1187,1197,1207,1217,1227,1237,1247,1273,1283,1293,1310,1320,1330],{"type":21,"tag":46,"props":1122,"children":1123},{},[1124,1129],{"type":21,"tag":50,"props":1125,"children":1126},{},[1127],{"type":27,"value":1128},"Mobile sidebar scrolling",{"type":27,"value":1130}," — Fixed scrolling failure that left the bottom user menu unreachable on production and staging.",{"type":21,"tag":46,"props":1132,"children":1133},{},[1134,1139],{"type":21,"tag":50,"props":1135,"children":1136},{},[1137],{"type":27,"value":1138},"Guided tour leakage",{"type":27,"value":1140}," — Guided tour tooltips no longer appear on the wrong page after navigation.",{"type":21,"tag":46,"props":1142,"children":1143},{},[1144,1149],{"type":21,"tag":50,"props":1145,"children":1146},{},[1147],{"type":27,"value":1148},"Setup page scrollbar",{"type":27,"value":1150}," — Removed the scrollbar from the setup page on laptop screens.",{"type":21,"tag":46,"props":1152,"children":1153},{},[1154,1159,1161,1167,1169,1175],{"type":21,"tag":50,"props":1155,"children":1156},{},[1157],{"type":27,"value":1158},"Reset-password redirect",{"type":27,"value":1160}," — Visiting ",{"type":21,"tag":88,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":27,"value":1166},"\u002Freset-password",{"type":27,"value":1168}," without a token now redirects to ",{"type":21,"tag":88,"props":1170,"children":1172},{"className":1171},[],[1173],{"type":27,"value":1174},"\u002Fforgot-password",{"type":27,"value":1176}," instead of showing an error.",{"type":21,"tag":46,"props":1178,"children":1179},{},[1180,1185],{"type":21,"tag":50,"props":1181,"children":1182},{},[1183],{"type":27,"value":1184},"iCal feed URL undefined",{"type":27,"value":1186}," — Fixed the iCal feed URL returning undefined after a page refresh.",{"type":21,"tag":46,"props":1188,"children":1189},{},[1190,1195],{"type":21,"tag":50,"props":1191,"children":1192},{},[1193],{"type":27,"value":1194},"Empty-string date crashes",{"type":27,"value":1196}," — All API endpoints that accept date strings now safely handle empty strings instead of crashing.",{"type":21,"tag":46,"props":1198,"children":1199},{},[1200,1205],{"type":21,"tag":50,"props":1201,"children":1202},{},[1203],{"type":27,"value":1204},"Profile data load on tab navigation",{"type":27,"value":1206}," — Profile sub-tabs (training, performance, benefits, onboarding) now correctly fetch their data on initial URL visit.",{"type":21,"tag":46,"props":1208,"children":1209},{},[1210,1215],{"type":21,"tag":50,"props":1211,"children":1212},{},[1213],{"type":27,"value":1214},"Birthday and hire date timezone shift",{"type":27,"value":1216}," — Date-only fields use UTC date components throughout, so e.g. \"Feb 25\" no longer displays as \"Feb 24\" for users west of UTC.",{"type":21,"tag":46,"props":1218,"children":1219},{},[1220,1225],{"type":21,"tag":50,"props":1221,"children":1222},{},[1223],{"type":27,"value":1224},"Onboarding due date off-by-one",{"type":27,"value":1226}," — Due dates now calculate from \"today in the organization's timezone\" with UTC date arithmetic, so \"1 day after hire date\" correctly resolves to the right calendar day for users in any timezone.",{"type":21,"tag":46,"props":1228,"children":1229},{},[1230,1235],{"type":21,"tag":50,"props":1231,"children":1232},{},[1233],{"type":27,"value":1234},"Receipt limit reset test flakiness",{"type":27,"value":1236}," — Stabilized a flaky test that occasionally failed near month boundaries.",{"type":21,"tag":46,"props":1238,"children":1239},{},[1240,1245],{"type":21,"tag":50,"props":1241,"children":1242},{},[1243],{"type":27,"value":1244},"Sectional save isolation on the user profile",{"type":27,"value":1246}," — Editing one section of the user profile (Job, Personal, Contact, etc.) now reliably leaves the other sections untouched. Comprehensive regression coverage added.",{"type":21,"tag":46,"props":1248,"children":1249},{},[1250,1255,1257,1263,1265,1271],{"type":21,"tag":50,"props":1251,"children":1252},{},[1253],{"type":27,"value":1254},"Tenure calculation rewritten",{"type":27,"value":1256}," — The \"Years of service\" line on the profile job tab is now calculated through a dedicated utility (",{"type":21,"tag":88,"props":1258,"children":1260},{"className":1259},[],[1261],{"type":27,"value":1262},"utils\u002Ftenure.ts",{"type":27,"value":1264},") covering future hire dates (\"Starts in N days\u002Fweeks\u002Fmonths\"), the first day (\"First day today\"), short tenures (",{"type":21,"tag":88,"props":1266,"children":1268},{"className":1267},[],[1269],{"type":27,"value":1270},"Nd",{"type":27,"value":1272},"), and longer tenures (years\u002Fmonths). 39 unit tests cover every boundary including new-year rollovers.",{"type":21,"tag":46,"props":1274,"children":1275},{},[1276,1281],{"type":21,"tag":50,"props":1277,"children":1278},{},[1279],{"type":27,"value":1280},"Training assignment targeting",{"type":27,"value":1282}," — The \"required for\" filter on training courses (All \u002F Department \u002F Role \u002F Specific Employees) is now applied consistently on both create and update paths, so courses only assign to the intended audience. Auto-assignment logic centralized into a shared helper. 39 tests cover the targeting algorithm.",{"type":21,"tag":46,"props":1284,"children":1285},{},[1286,1291],{"type":21,"tag":50,"props":1287,"children":1288},{},[1289],{"type":27,"value":1290},"Profile training tab now respects course targeting",{"type":27,"value":1292}," — The training tab on a user's profile only displays courses that actually apply to that user.",{"type":21,"tag":46,"props":1294,"children":1295},{},[1296,1301,1303,1308],{"type":21,"tag":50,"props":1297,"children":1298},{},[1299],{"type":27,"value":1300},"Profile training tab cleanup",{"type":27,"value":1302}," — Removed an incomplete inline editor in favor of the canonical training editor under ",{"type":21,"tag":88,"props":1304,"children":1306},{"className":1305},[],[1307],{"type":27,"value":402},{"type":27,"value":1309},". Added a read-only details modal so users can review training info directly from their profile.",{"type":21,"tag":46,"props":1311,"children":1312},{},[1313,1318],{"type":21,"tag":50,"props":1314,"children":1315},{},[1316],{"type":27,"value":1317},"Recording completed training is now instant",{"type":27,"value":1319}," — The \"Record Completed Training\" flow no longer requires a manual page refresh to see the new entry. Optimistic UI update + single-request creation.",{"type":21,"tag":46,"props":1321,"children":1322},{},[1323,1328],{"type":21,"tag":50,"props":1324,"children":1325},{},[1326],{"type":27,"value":1327},"Reports To picker respects role hierarchy",{"type":27,"value":1329}," — The \"Reports To\" dropdown on the user edit form now only suggests users at or above the employee's level in the hierarchy, excludes inactive users, and reacts live to in-form role changes. The currently saved manager is preserved even if outside the filtered list.",{"type":21,"tag":46,"props":1331,"children":1332},{},[1333,1338],{"type":21,"tag":50,"props":1334,"children":1335},{},[1336],{"type":27,"value":1337},"Document links from profile docs tab",{"type":27,"value":1339}," — Clicking a document on a user's profile documents tab now opens the right assignment for the current viewer in all cases, while preserving the existing per-user privacy boundary (non-admins still only see their own assignment).",{"type":21,"tag":22,"props":1341,"children":1343},{"id":1342},"performance-loading-experience",[1344],{"type":27,"value":1345},"Performance & Loading Experience",{"type":21,"tag":30,"props":1347,"children":1348},{},[1349],{"type":27,"value":1350},"This release dramatically reduces the \"split-second flash\" of empty\u002Ffallback content that used to appear on first navigation, and replaces every page-level loading spinner with a layout-matching skeleton.",{"type":21,"tag":42,"props":1352,"children":1353},{},[1354,1364,1374,1384,1394,1412,1429,1439,1465,1475,1491],{"type":21,"tag":46,"props":1355,"children":1356},{},[1357,1362],{"type":21,"tag":50,"props":1358,"children":1359},{},[1360],{"type":27,"value":1361},"Single-request page bootstrap",{"type":27,"value":1363}," — Authenticated pages used to need several sequential round trips to load the small set of \"always needed\" data (org settings, timezone, leave types, departments, etc). These have been folded into a single bootstrap request that uses the existing JWT middleware and is org-scoped on every database query. The response is intentionally minimal — no employee data, no leave or balance information, no per-user-per-year content. Comprehensive regression tests lock the response shape and verify no sensitive data is included.",{"type":21,"tag":46,"props":1365,"children":1366},{},[1367,1372],{"type":21,"tag":50,"props":1368,"children":1369},{},[1370],{"type":27,"value":1371},"Session-scoped cache",{"type":27,"value":1373}," — A reactive cache holds the bootstrap response for the rest of the session, shared across every page. It is dedicated to a single in-flight fetch at a time, refreshed on a short TTL, cleared on logout (so nothing persists across user sessions), and automatically invalidated whenever the user saves a setting that would affect it.",{"type":21,"tag":46,"props":1375,"children":1376},{},[1377,1382],{"type":21,"tag":50,"props":1378,"children":1379},{},[1380],{"type":27,"value":1381},"Pre-warming on app start",{"type":27,"value":1383}," — A client plugin fires the bootstrap fetch right after auth is ready, so the first page the user lands on already has its layout chrome populated.",{"type":21,"tag":46,"props":1385,"children":1386},{},[1387,1392],{"type":21,"tag":50,"props":1388,"children":1389},{},[1390],{"type":27,"value":1391},"Auto-invalidation on settings mutation",{"type":27,"value":1393}," — When an admin saves a new timezone or other org-level setting and clicks another page in the sidebar, the new value is reflected immediately — no manual page refresh required. Implemented as a network-layer hook so individual pages don't have to remember to invalidate.",{"type":21,"tag":46,"props":1395,"children":1396},{},[1397,1402,1404,1410],{"type":21,"tag":50,"props":1398,"children":1399},{},[1400],{"type":27,"value":1401},"Calendar, dashboard, users, and approvals refactor",{"type":27,"value":1403}," — Each of these pages used to make multiple sequential network round trips in ",{"type":21,"tag":88,"props":1405,"children":1407},{"className":1406},[],[1408],{"type":27,"value":1409},"onMounted",{"type":27,"value":1411}," before the layout could render. They now run all initial fetches in parallel. Lookups that aren't immediately needed (like the department list for the Group Booking modal) are lazy-loaded only when the user actually needs them.",{"type":21,"tag":46,"props":1413,"children":1414},{},[1415,1420,1422,1427],{"type":21,"tag":50,"props":1416,"children":1417},{},[1418],{"type":27,"value":1419},"Dropped redundant auth-readiness waits",{"type":27,"value":1421}," — Several composables were waiting for auth-ready state inside individual fetchers, which added per-fetch latency on the hot path. The auth middleware already guarantees ready state by the time ",{"type":21,"tag":88,"props":1423,"children":1425},{"className":1424},[],[1426],{"type":27,"value":1409},{"type":27,"value":1428}," fires, so these calls were dead weight and have been removed.",{"type":21,"tag":46,"props":1430,"children":1431},{},[1432,1437],{"type":21,"tag":50,"props":1433,"children":1434},{},[1435],{"type":27,"value":1436},"Parallelized leave types load",{"type":27,"value":1438}," — Calendar pages now fetch leave types in the same parallel batch as leaves, balances, holidays, and locked dates instead of waiting for the parallel block to finish first.",{"type":21,"tag":46,"props":1440,"children":1441},{},[1442,1447,1449,1455,1457,1463],{"type":21,"tag":50,"props":1443,"children":1444},{},[1445],{"type":27,"value":1446},"Skeleton component library",{"type":27,"value":1448}," — New ",{"type":21,"tag":88,"props":1450,"children":1452},{"className":1451},[],[1453],{"type":27,"value":1454},"components\u002Fskeletons\u002F",{"type":27,"value":1456}," folder with a ",{"type":21,"tag":88,"props":1458,"children":1460},{"className":1459},[],[1461],{"type":27,"value":1462},"Skeleton",{"type":27,"value":1464}," primitive (rect\u002Fcircle\u002Fpill\u002Ftext shapes) plus 11 layout-matching composites covering list pages, detail pages, form pages, card grids, the calendar header and grid, the dashboard grid, the user profile, the schedule\u002Ftimesheet board, and the org chart. All fully responsive (mobile-first Tailwind breakpoints). Reusable across the app via props.",{"type":21,"tag":46,"props":1466,"children":1467},{},[1468,1473],{"type":21,"tag":50,"props":1469,"children":1470},{},[1471],{"type":27,"value":1472},"Loading spinners replaced across the app",{"type":27,"value":1474}," — Every centered spinner that hid the page during first load is now a layout-matching skeleton that holds the layout shell. Pages updated: expenses (list + detail + reports + approvals), documents (list + detail), clients (list + detail), projects (list + detail), training, schedules, admin, onboarding, time-tracking timesheets, time-tracking approvals, users profile, users data drive, users orgchart (view-aware: orgchart\u002Flist\u002Fdirectory each get the right skeleton), settings overview, billing. Plus the approval tab components, reports tab components, and 20 settings sub-page components.",{"type":21,"tag":46,"props":1476,"children":1477},{},[1478,1489],{"type":21,"tag":50,"props":1479,"children":1480},{},[1481,1483],{"type":27,"value":1482},"No more \"no projects found\" flash on ",{"type":21,"tag":88,"props":1484,"children":1486},{"className":1485},[],[1487],{"type":27,"value":1488},"\u002Fprojects",{"type":27,"value":1490}," — The empty state used to flash for one frame on every navigation because the loading flag started as false. The initial value was flipped so the skeleton renders from the very first frame.",{"type":21,"tag":46,"props":1492,"children":1493},{},[1494,1499],{"type":21,"tag":50,"props":1495,"children":1496},{},[1497],{"type":27,"value":1498},"Org chart card and connector redesign",{"type":27,"value":1500}," — Larger node cards, bigger avatars, outlined role badge, bottom-right reports\u002Fcollapse toggle, dot-grid card background, smoother bezier connector curves, search input with match dimming, expand-all\u002Fcollapse-all buttons, and per-node collapse toggles.",{"type":21,"tag":22,"props":1502,"children":1504},{"id":1503},"browser-compatibility",[1505],{"type":27,"value":1506},"Browser Compatibility",{"type":21,"tag":42,"props":1508,"children":1509},{},[1510,1520],{"type":21,"tag":46,"props":1511,"children":1512},{},[1513,1518],{"type":21,"tag":50,"props":1514,"children":1515},{},[1516],{"type":27,"value":1517},"PDF rendering on older browsers",{"type":27,"value":1519}," — The document signing flow could fail on browsers released before early 2025 due to a JavaScript syntax feature used by the modern PDF.js build. Switched the application to PDF.js's officially supported legacy build, which targets ES2020 and works on every browser from 2021 forward (Chrome 88+, Firefox 78+, Safari 14+). The legacy build is built from the same source as the modern build and receives the same security patches in lockstep from Mozilla.",{"type":21,"tag":46,"props":1521,"children":1522},{},[1523,1528],{"type":21,"tag":50,"props":1524,"children":1525},{},[1526],{"type":27,"value":1527},"PDF.js version pinning",{"type":27,"value":1529}," — Tightened the dependency range so future patch releases land but a minor version bump (which could re-raise the minimum browser target) requires an explicit, reviewed upgrade.",1790889965183]