Employee Onboarding Portal
An internal onboarding portal that turns new-hire setup from tribal knowledge into a tracked, accountable checklist. Built on Asana as the system of record with no database, so every step is recorded under the real person who completed it.
Employee Onboarding Portal
One-Line Summary: An internal web portal that turns employee onboarding at a multi-brand debt-resolution firm from tribal knowledge into a tracked, accountable checklist, built on Asana as the system of record with no database, so every step records who completed it and when.
Problem Statement
When the firm hired someone, a set of accounts had to be created across a stack of tools: Microsoft 365, the dialer, the phone system, SMS, Salesforce, plus payroll and paperwork. That list lived only in people's heads and changed depending on who you asked. Nothing recorded who did what, so a missed step was usually discovered on the new hire's first day, when their accounts were not ready.
Leadership asked for one thing above all else: accountability. Every step should record who completed it and when. Automating the account setup was the second priority, not the first. The real problem was not speed, it was that nobody could answer "who set up their Salesforce account, and when?"
Solution
A web portal where a recruiter files a new hire, and the system creates a tracked checklist that the team ticks off as they complete each step. The twist is in the backend: there isn't one in the usual sense.
Asana is the system of record. There is no database for hires. Asana already stores the tasks, the completion state, and the audit trail, so building a separate database would have meant a schema to maintain, auth to build, and a second source of truth to reconcile. Instead the portal is a clean front end over Asana. Filing a hire creates a parent task plus one assigned subtask per step, wires the dependencies between them, and optionally sends the hire's paperwork automatically.
The result is a single place where hires are filed and steps are ticked, and everything is recorded in Asana under each person's own name.
The Constraints That Shaped the Design
Most of the interesting engineering here came from working with a tool that was never meant to be a backend, and refusing to let it cut corners on the one thing that mattered: accountability.
Attribution had to be real. In Asana, the record of who completed a task always follows the token that made the request, and it cannot be overridden. The only way a tick genuinely reads as a specific person is to send that person's own token. So each team member connects their own Asana account, separate from signing in, and the one endpoint that ticks a step refuses to fall back to a shared service token. A tick recorded as the wrong person is worse than no tick at all.
Trust nothing the external system claims to enforce. Asana will happily let you complete a task whose blocker is still open, the dependency is only a visual hint. So the rule that gates twelve steps behind two paperwork steps is enforced in the portal's own API, which rejects an out-of-order tick outright. The same applied to access: because the portal reads Asana with a shared token, Asana's own permissions could not decide who sees which hire. That scoping is enforced on every route that can reach a hire, not just the list view, because filtering only the list would be cosmetic, a hire's ID typed into the URL would still return the record and its personal data.
Two brands, one template. The firm operates as two brands out of two offices, and a hire's office decides their email domain, phone area code, paperwork, and which board they land on. The checklists genuinely differ between offices. Rather than maintain two lists that would drift apart the first time someone edited one and not the other, there is one template in code, filtered per office.
Paperwork Automation, Built Safety-First
The two document-signing steps gated everything else and were the only steps still done by hand, which made automating them the highest-value work in the project. It also meant the tool would, for the first time, take an action that reached someone outside the company, so the automation was built defensively:
- A kill switch built before the send. The ability to stop paperwork going out existed before the ability to send it, toggleable in seconds from the page you are already on, not through a deploy.
- Fails to off. Any problem reading the switch results in nothing being sent.
- An atomic claim taken before the send. The gap between "sent" and "recorded" is exactly where a duplicate document would be born, and a duplicate is not cosmetic: the hire gets two copies and cannot tell which to sign.
- A step marks "sent" only once a real confirmation comes back. A step that claims success when nothing happened is worse than an untouched one, because it silently unblocks everything downstream.
- Polling instead of webhooks. The push-based option was plan-gated and instant, polling was free and checked every ten minutes. For a step measured in hours of a working day, instant was the wrong thing to pay for.
Stack
| Layer | Choice |
|---|---|
| Front end | Vite + React 19 + TypeScript |
| API | Vercel serverless functions, no framework |
| Data | Asana (hires, checklists, audit trail) + Upstash Redis (switches, claims) |
| Auth | Email + password, scrypt-hashed; AES-256-GCM encrypted session cookie |
| Paperwork | DocuSign eSignature API, JWT Grant |
| Hosting | Vercel |
Redis holds only things that are safe to lose, a switch position or an "already sent" marker. Nothing about a hire exists only there, so if Redis vanished the worst case is a switch resetting to off.
Outcome
The portal is live and in daily use across two brands and two boards. Hires are filed in the portal and ticked there, and every completion is recorded in Asana under the real person who did it, which is exactly the accountability leadership asked for. The DocuSign paperwork automation is built and verified, waiting only on production sign-off to switch on. Account provisioning is the next phase: an onboarding and offboarding agent that creates and revokes Microsoft 365 and other tool accounts per role, rolled out one integration at a time.
The lesson worth keeping from this one is that the hard part was not code volume, it was judgment: deciding that Asana should be the source of truth, that attribution could never be faked, and that every safety mechanism for an outward-facing action had to exist before the action itself.
More from Web Apps
More in this category
Creditor Portal
A B2B SaaS dashboard enabling creditors to log in, view their debt settlement portfolio, and batch approve, reject, or counter-offer settlement cases from the client
Web AppsCustomer Portal
A comprehensive client-facing React/TypeScript portal where debt settlement customers view program status, track creditor negotiations, manage payments, upload documents, and interact with an AI assistant, all backed by Salesforce