The problem
The company staffs events rather than permanent posts, so its workforce is a few thousand people who are hired for a weekend and then hired again months later. Every large event opened with registration, and registration meant ten queue lines of staff waiting to be checked in. An administrator took each person's identity document and permits, scanned them by hand, and filled in the paperwork.
That is what triggered the project. Onboarding was the bottleneck on the morning of every event, and it repeated in full each time, because most of the people standing in those lines had worked an event before and nothing about them had been kept. Before any of it could be made faster there had to be somewhere to hold the answer to a simple question: who has worked for us, on which events, and what are they qualified to do.
Personnel administration ran on spreadsheets and a shared drive. Guards hold credentials that expire and grades that govern what they can be assigned to, and nobody could say who was currently qualified for a given post without cross-referencing by hand. Staff data was duplicated across office locations, so the same person could exist three times with three different phone numbers.
The piece the client was most interested in never got built. The plan was an ID scanner: an administrator points a phone camera at an identity document and the fields fill themselves in, which is what would have shortened the queues instead of just recording who was standing in them. The client did not take that idea forward, so it stayed an idea.
What I built
An administrative platform on Laravel, built on Craftable PRO, that became the single source of truth for personnel data.
- Profiles with photographs, employee identifiers, contact details, and an employee or contractor distinction
- Guard credentials tracked as first-class records rather than as a field on a person
- Levels and level categories encoding the grade system that governs what someone can be assigned to
- Offices giving the location hierarchy staff are attached to
- Statuses so a profile has a defined lifecycle rather than an implicit one
- An availability calendar on every profile, holding typed date ranges so a month of cover reads at a glance
- A media library with tagging, because personnel files are mostly documents and photographs
- Role-based access so office administrators see their own staff and nothing else
- Bulk import for the initial migration off spreadsheets, and for ongoing batch updates
- Full localisation, since the interface is used in both English and Spanish
Decisions and tradeoffs
Building on a well established framework paired with a CRUD platform was my proposal, and the argument for it was cost. Laravel and Craftable PRO together meant reusing infrastructure that already existed instead of writing it a second time. This is a CRUD-heavy internal tool with roughly thirty screens and no unusual interaction requirements, so hand-rolling the admin would have taken weeks and the result would have been worse. What I gave up is a framework opinion I then have to live inside, and it cost me time later on the permission model.
I also modelled credentials as their own records instead of fields on the profile. A guard licence has an issue date, an expiry date and a history, and one person can hold several of them, so a column would not have held up.
The calendar was the client's idea, but not in the shape it shipped. They asked for a table of an employee's past events, which is fine for auditing and useless for planning. A row of dates does not tell you whether someone is free the week after next. What shipped holds availability rather than history: every entry has a type, a start date and an end date, so a week of cover reads as one bar across the month. Their table survived underneath the grid, the same records as rows with their length in days. All of it sits on the profile itself, next to the fields it depends on. We built it on FullCalendar, which I still recommend.
What was hard
The bill for building on a CRUD platform came due in its components. The generic screens cost me almost nothing, but anything that had to meet a specific requirement had to be tweaked, extended or rewritten. The uploader is the clearest case. Craftable PRO ships one, it works, and it neither did what the client needed nor looked like the rest of the interface, so I replaced it.
That is the honest trade in this kind of tool. A CRUD platform gives you the screens that are the same in every admin and charges you back on the ones that are specific to the client, and the specific ones are the part nobody estimates properly.
Where it stands
The platform is in production and is the system of record for personnel data across the company. I maintain it on my own.
I offer maintenance on everything I ship, so I would have heard about it. The client has not come back to me with a problem since it went in.