Re-platforming Dashworks Self-Service, slot booking logic and write-back data collection
Context
Juriba has Dashworks — an enterprise platform used by large organizations and financial institutions to migrate and modernize their IT estates: devices, software, users.
Each client runs an isolated instance holding their estate data, refreshed by a nightly sync rather than live feeds. Decisions about thousands of devices are made on this data, so data integrity is the point of the product, not a nice-to-have.
I joined as a Feature Product Owner (in May 2020) while Juriba was re-platforming its legacy enterprise product (Dashworks) to a new architecture and UI. Within six months I was promoted to Area Product Owner, responsible for two development teams.
During the transition the legacy interface and the new front end ran over the same operational database, so both sides had to stay consistent. One of the components my team owned was Self-Service — admin-configured pages sent to end users as personal links, where their answers wrote straight back into the operational database. Clients were large organizations and banks; decisions about thousands of devices were made on this data. I had no direct access to end users — client feedback came through in-house consultants.
The problem
Self-Service is the platform’s data-collection surface: admin-configured pages built from components and sent to end users as personal links.
Users confirm or update information about themselves and their devices — and their answers write straight back into the operational database.
The task sounded simple: “port Self-Service to the new platform.” It wasn’t – for three reasons:
- Feature parity is not a requirement. The legacy component’s behavior was under-documented. Some of the odd behaviour was bugs; other parts were things enterprise clients had built their processes around.
‼️Every “port it as is” had to be turned into an explicit keep / change / drop decision.
- No direct access to end users. Client feedback arrived through in-house consultants working with the enterprise accounts. Requirements had to be gathered, tested, and verified through proxies — and a proxy’s summary is not the same as a user’s answer.
- The stakes were data integrity. A weak validation rule would write bad data into a client’s migration database (i.e large enterprise), a database the legacy UI was still reading on the other side.
The hardest piece: slot booking
The most demanding part was self-scheduling — letting an employee book a slot for a device replacement or migration from a capacity-managed calendar, per location and time window. Booking logic is deceptively simple: the number of non-trivial ways a slot can turn out taken is always larger than anyone expects.
The core design decision was reserve-at-submit. Nothing was held when a user picked a slot; the reservation happened only when the whole form was submitted. This kept the system free of expiring holds and cleanup logic — which mattered, because the slot picker was just one of several components an admin could place on a page.
The price was that all conflict handling moved to submit time, and it had to be handled well. If a slot filled between page render and submit, the user was not passed to the Thank-you page: an in-page notification explained the slot was taken, and they re-picked without losing the rest of their answers. First valid submit wins. Abandoned sessions leave no orphaned reservations — by design, not by cleanup job.
Capacity was the other half: admin-defined booking windows, per-location slot limits, and calendar states a user could read at a glance — available, limited capacity remaining, full or outside the booking window. And because reality changes after go-live, capacity edits made when bookings already existed were handled too: admins were warned, and affected bookings were flagged as conflicts in the admin views — where the reporting side of my area picked the story up.
The team — developers, testers, and me — hunted edge cases on our own initiative long before release, because we wanted this to be solid. It shipped, it worked, and slot-based self-scheduling remains one of the publicly promoted capabilities of the product today.
The tensions
Around the booking logic sat the less visible requirements work:
- validation rules for write-back fields;
- the interplay between nightly-refreshed estate data and fresh user submissions;
- bulk onboarding of objects into a project running asynchronously — another place where “a simple form” met operational scale
- configurability everywhere: every client instance is different, so pages had to be built, not hardcoded.
The admin page builder (live preview in the center, a panel of page blocks and components on the right) originally produced single-page services when I started; configurable multi-page support was added later during my tenure.
All of it was delivered against the enterprise baseline — security, data protection, and accessibility standards (GDPR, ISO 27001, WCAG).
What clients did with the tool showed its range
One legacy example I was shown surveyed bank employees about COVID-19 vaccination status and let staff pick a convenient date, time and vaccination point from the form.
Same engine: structured questions, estate data feeding the dropdowns, answers written back to drive decisions.
What I produced
User stories with full acceptance criteria; flow definitions and rule sets like the ones recreated below; joint design reviews with the designer and product manager; and release demos to stakeholders on realistic test data.
Note: Artifacts below are recreated and generalized from memory for portfolio purposes — no client data, client names, or product screenshots are used.
Self-Service and slot-based self-scheduling are publicly documented capabilities of the product (juriba.com/self-service).
Slot Booking: States & Rules
| # | Rule / behavior | Detail |
|---|---|---|
| 1 | Calendar states (user-facing) | Green = available · Yellow = limited capacity remaining · Black = full or outside booking window |
| 2 | Booking window | Slots bookable only within an admin-defined date/time window; dates outside it shown as unavailable |
| 3 | Reservation moment | No hold at selection — the slot is reserved only on form submit. Trade-off: no expiring holds or cleanup logic; submit-time conflicts must be handled instead |
| 4 | Submit-time conflict | If the slot filled between page render and submit: user is not passed to the Thank-you page; an in-page notification explains the slot is taken; user stays on the form and re-picks |
| 5 | Success path | Valid submit → values written to the operational database → Thank-you page with admin-configured custom text |
| 6 | Reschedule model | No dedicated cancel/reschedule flow — the user re-enters the form and submits new values |
| 7 | Capacity change after bookings | Admins warned when existing bookings are affected; conflicts flagged and surfaced in admin views (marked rows) |
| 8 | Page composition | Admin page builder: central live preview, right-hand panel of page blocks and components. Single-page originally; configurable multi-page added later — the slot picker is one of several components, so availability validation runs at page submit, not per component |
| 9 | Race between concurrent users | Two users, one remaining slot: first valid submit wins; the second receives the conflict path (rule 4) |
| 10 | Abandoned session | User leaves without submitting → no orphaned reservation, by design (consequence of rule 3) |
Booking Flow Definition (recreated, generalized)
Admin lane
- Configure page: components, slot capacity per location, booking window, Thank-you text
- Later, when reality changes: edit capacity after bookings exist → system warns → conflicts flagged in admin views
User lane
- Open personal self-service link
- Fill page components; pick a slot from the calendar (green / yellow / black states)
- Submit the form
System lane
- On submit: re-validate slot availability
- Conflict: in-page notification, user stays on the form, re-picks (answers preserved)
- Success: write values back to the operational database → Thank-you page
Result
The feature shipped and worked reliably.
Booking logic is deceptively simple — the number of non-trivial ways a slot can turn out taken is always larger than anyone expects — and we caught those cases in specification and testing, not in production incidents. Slot-based self-scheduling remains one of the publicly promoted capabilities of the product today.
I was later promoted to Area Product Owner, owning this stream and the reporting/data views stream across teams.
What I learned
Feature parity is not a requirement — someone has to turn “make it like the old one” into explicit decisions, and that someone is the PO.
When user answers write into an operational database, validation and conflict rules are data-integrity work, not form design.
And requirements gathered through proxies need extra verification discipline: a consultant’s summary is not the same as a user’s answer.
Where this work lives

This case exists as the artifact in Upwork – Enterprise Self-Service Re-Platform | Booking Logic | B2B SaaS PO
What this shows
Re-platform work punishes vague requirements twice: once in the new build, and once in the legacy system still running beside it. My job was to catch the expensive cases — parity ambiguities, booking races, capacity conflicts — while they were still lines in a specification, not incidents in a client’s migration.



