HomeCase studiesAn On-Demand Staffing Marketplace with Supervised Time...

Case study · Zurich, Switzerland

An On-Demand Staffing Marketplace with Supervised Time Verification and Escrow Payments

Workforce and staffing technology — supervised hourly and shift-based work

Hourly, shift-based work has a problem that project-based freelancing does not: the business is paying for hours it never saw. Our team built a staffing marketplace that answers this with a third participant — a named supervisor assigned to each shift, whose approval gates payment — supported by tracked work sessions that produce verification artefacts rather than a self-reported number. Funds are held in an internal wallet and released against approved hours, with identity-verified payouts to the worker's own account. Delivered as a REST API and administrative back office, a single-page web application, and native Android and iOS applications, each carrying a distinct experience for all of the platform's roles.

Industry
Workforce and staffing technology — supervised hourly and shift-based work
Solution
A multi-sided marketplace and workflow platform: a token-authenticated REST API with a server-rendered administrative back office, a single-page web application, and two native mobile applications.
Platforms
Android · iOS · Web & API
Stack
Laravel · PHP · Blade · Angular · TypeScript · Bootstrap
Location
Zurich, Switzerland · delivered remotely
Role
Engineering, with the team behind for mobile and QA

Delivered remotely for a business based in Zurich, Switzerland. Names withheld by agreement.

Project Overview

Industry: Workforce and staffing technology — supervised hourly and shift-based work.

Type of solution: A multi-sided marketplace and workflow platform: a token-authenticated REST API with a server-rendered administrative back office, a single-page web application, and two native mobile applications.

Business context: Businesses needing short-notice hourly labour have traditionally used agencies. Agencies are expensive, but they are not expensive for no reason — they absorb risk on both sides. The worker gets certainty of payment; the business gets certainty that hours claimed were hours worked; neither has to hold the other's bank details or chase the other for money. Any platform proposing to replace the agency has to replace that risk absorption too, or it is simply a job board with extra steps.

General users: Hourly and shift workers, the businesses that hire them, supervisors who verify work on the ground, and platform administrators.

General purpose: To make short-notice hourly hiring work end to end — discovery, hiring, verification of hours, and payment — without either side having to trust the other, and without an intermediary taking an agency margin for doing it.

The Business Challenge

Matching is a scheduling problem, not a search problem. A shift is a specific window on a specific day in a specific place requiring specific skills. Matching against it means understanding worker availability as structured data, not as a paragraph on a profile.

Nobody watched the work. Hourly work performed away from the person paying for it creates an asymmetry that has no clean technical answer. A self-reported figure is a claim. A claim is disputable. A dispute at the point of payment is exactly where a marketplace loses both participants at once.

Two parties, and only one of them is present. The business is not on site. The worker is. Asking the business to police hours it cannot observe puts it in an impossible position; asking it to accept whatever is submitted puts it in a worse one.

Money has to sit somewhere in between. If the business pays after the work, the worker carries the risk. If the worker is paid before, the business does. Someone has to hold funds during the gap, which means an internal balance, a ledger, a release condition, identity verification, and a payout path to a real bank account.

Four roles, four clients, one product. Workers are on their phones. Businesses are often at a desk. Supervisors are on site. Administrators are handling disputes and withdrawals. Every one of them needed a coherent experience, and the platform shipped on web, Android and iOS.

Trust has to be visible. Ratings, review history, verified identity and a record of completed work are not features bolted onto a marketplace — they are the reason anyone uses it in preference to a phone call to someone they already know.

Our Approach

Add the missing participant. Rather than trying to solve the verification problem between two parties who each have an interest in the answer, we modelled a third: a supervisor assigned to a job, whose approval is what releases payment. This is how supervised staffing already works off-platform, and modelling it faithfully was the single most consequential decision in the project. It is a first-class account type — its own sign-in, its own application shell on every client, its own notifications, its own back-office management.

Make hours evidenced rather than asserted. Tracked work sessions produce structured artefacts alongside the elapsed time, so an approval or a rejection is a judgement about something rather than a judgement about a claim. Artefacts are captured and uploaded in batches rather than streamed, which respects the constraints of a device carried through a working shift on a variable connection.

Model money as a ledger, not a number. Every movement is a row carrying its own credit, debit, resulting balance, type, initiating party and external reference. A balance that is only a number can be corrected but never explained; a ledger can be reconstructed, reconciled and audited.

Delegate the regulated parts. Identity verification, connected-account creation and payout execution are handled by an established payments provider rather than built in-house. This is not a shortcut — it is the correct boundary for a platform that moves money between individuals and businesses.

Encrypt personal data at the application layer. Personal fields on the user record are encrypted before they reach the database and decrypted on read, with the key held outside the codebase. This costs the ability to index or query those columns directly, which we accepted deliberately: the trade is worth making when the data in question identifies individuals.

Give the web client a real state architecture. The web application was built on a full unidirectional state store with a slice per domain concept, effects isolating all server interaction, and route resolvers prefetching data before a view activates. In a marketplace this data-dense, ad-hoc component state becomes unmaintainable well before feature-complete.

Build both mobile clients natively. Android in Kotlin with MVVM, data binding and a repository layer; iOS in Swift with MVVM and modules mirroring the platform's roles. Both clients depend heavily on camera, location and background behaviour, which is where native implementations earn their cost.

Give the marketplace a public face. Job listings and worker profiles are viewable without an account, so the platform has an indexable surface and a route from search to sign-up rather than a wall.

The Solution

Structured job posting. A job carries a skill and sub-category classification, a geographic location drawn from a country/state/city hierarchy, a rate type, a rate, a date and time window and a total-hours figure — enough structure to match a real shift rather than approximate one.

Availability as data. Workers maintain a calendar of available dates that appears on their public profile and can be matched against a shift's window.

Discovery in both directions. Businesses browse and search workers, favourite them and build a shortlist; workers search and filter jobs by category, skill and criteria, save the interesting ones and suppress the rest. Both sides can initiate: workers apply, businesses invite.

A hiring lifecycle, not a status field. Jobs move through posting, interview, award and completion, with applications, invitations, acceptances and rejections all recorded as their own events.

Supervisor assignment. A business assigns one or more supervisors to a job. Supervisors sign in to their own application experience across web, Android and iOS.

Tracked work sessions. Workers start and stop tracking against a job, with verification artefacts captured during the session and uploaded in batches. Elapsed time and the resulting charge are computed against the job's agreed rate.

Timesheets and approval. Tracked time becomes a timesheet, submitted for supervisor review and either approved or rejected, with a path for the worker to request an extension when a shift runs long. Both hourly and fixed-rate work are supported.

Wallet and ledger. Businesses fund jobs into a wallet balance. Approved work triggers release from the business wallet to the worker wallet. Every movement is recorded in a transaction ledger with a running balance.

Identity-verified payouts. Workers complete identity verification through the payments provider, connecting a bank account. Withdrawal requests are reviewed and paid out to that account.

Reputation. Bidirectional ratings and written reviews attach to completed jobs and accumulate into a public work history, alongside portfolio items and certifications.

Messaging and notifications. Direct and group messaging with read state and unread counts, a separate support channel to platform administrators, and push notifications with per-user, per-type preferences.

Administrative back office. Management of accounts across all roles, jobs, the skill and geographic taxonomies, transactions, withdrawal approvals, reported jobs, messaging, email templates and platform settings.

Key Features

Supervised timesheet approval A named third party assigned per job reviews tracked work and approves or rejects it, and that approval is what gates payment — replacing a two-party dispute with a three-party process.

Evidenced time tracking Tracked work sessions produce structured verification artefacts alongside elapsed time, uploaded in batches suited to a mobile device on a variable connection, so approval decisions rest on evidence rather than assertion.

Escrow-style wallet with a running-balance ledger Businesses fund work up front; funds release to the worker on approval; every movement is a ledger row carrying credit, debit, resulting balance, type and external reference.

Identity-verified payouts Identity verification and connected-account creation are handled through an established payments provider, with withdrawal requests reviewed before payout to the worker's own bank account.

Structured availability matching Worker availability is a calendar of dates rather than free text, so it can be matched against a shift's specific window instead of read and interpreted.

Role-specific experiences on every client Worker, business, supervisor and administrator each get a distinct navigation shell and feature set, implemented across a web application and two native mobile applications.

Bidirectional reputation and verified work history Ratings and reviews flow both ways and accumulate into a public profile alongside portfolio and certification records, giving both sides something to evaluate before committing.

Application-layer encryption of personal data Personal fields are encrypted before persistence and decrypted on read, with key material held outside the codebase, so the database alone does not yield readable personal information.

Public marketplace surface Job listings and worker profiles are viewable without an account, giving the platform an indexable presence and a direct route from search to registration.

Technical Architecture

Client layer. A single-page web application built on a unidirectional state store with a slice per domain concept, effects isolating server interaction, route resolvers prefetching data before view activation, and route guards separating the worker, business and supervisor route trees. Progressive Web App configuration caches the application shell. Alongside it, a native Android client in Kotlin using MVVM with view models, data binding, a navigation graph and a repository layer over a typed HTTP client; and a native iOS client in Swift using MVVM with modules mirroring the platform's roles.

API layer. A token-authenticated REST API using OAuth2 bearer tokens, with controllers partitioned by audience over shared base controllers and route definitions split by feature. The same application serves a session-authenticated, server-rendered administrative back office.

Domain layer. Marketplace (jobs, applications, invitations, hiring), verification (tracking sessions, artefacts, timesheets, supervisor approval), money (wallets, ledger, funding, release, withdrawals), identity (accounts, roles, verification, reputation) and communication (messaging, notifications, templated email).

Data layer. A relational database with the job and worker taxonomies, a geographic hierarchy, the transaction ledger, verification records and messaging, with personal fields stored as ciphertext.

Integration layer. An established payments provider for charges, connected accounts, identity verification and transfers; a push notification service for device delivery; three social identity providers plus native platform sign-in; SMTP for transactional email.

Delivery. Continuous-integration-triggered releases to versioned deployment directories with environment configuration and key material linked in from outside the release, followed by cache clearing and application server reload.

Flow: Web SPA / Android / iOS → OAuth2 bearer token → REST API → relational database → payments provider (funding, verification, payouts) + push and email delivery, with an administrative back office over the same domain.

Technology Stack

Category Technology
Backend language PHP
Backend framework Laravel
Database MySQL with Eloquent ORM and migration-managed schema
API authentication OAuth2 bearer tokens (Laravel Passport)
Administrative back office Blade server-rendered views with Laravel Mix asset pipeline
Web framework Angular with TypeScript
Web state management NgRx store, effects and entity — a slice per domain concept
Web data loading Route resolvers with role-based route guards
Web UI Angular Material and CDK, Bootstrap, calendar, range slider, tag input, pagination and date/time picker components
Web delivery Progressive Web App with service worker shell caching
Android Kotlin, MVVM with ViewModel and LiveData, Data Binding, Navigation Component
Android networking Retrofit with reactive adapters and an OkHttp logging interceptor
Android media Image loading and caching, image picker and cropper
iOS Swift, MVVM, CocoaPods dependency management
iOS networking & media HTTP client with JSON handling, image loading and caching
Payments Established payments provider — charges, connected accounts, identity verification, transfers, payouts
Push notifications Firebase Cloud Messaging with native platform push handling
Identity providers Facebook, Google and native platform sign-in
Location & camera Platform location services and camera access on both mobile clients
Data protection Application-layer encryption of personal fields; bcrypt password hashing
CI/CD Continuous integration triggering versioned, scripted releases

Technical Challenges & Solutions

Challenge Our Approach
Paying for hours nobody at the business observed Introduced a third participant — a supervisor assigned per job whose approval gates payment — modelled as a first-class account type with its own sign-in and its own application shell on every client, rather than asking two interested parties to agree.
A self-reported number is a claim, and claims get disputed Tracked work sessions produce structured verification artefacts alongside elapsed time, so approval is a judgement about evidence. Artefacts upload in batches rather than continuously, respecting battery and connectivity on a device carried through a shift.
Neither side wants to carry payment risk An internal wallet holds funds from posting until approval, with release triggered by the supervisor's decision — replacing the mutual trust an agency used to supply.
A balance can be corrected but not explained Modelled money as a running-balance ledger: every movement is a row with credit, debit, resulting balance, type, initiating party and external reference, so the position can be reconstructed and reconciled rather than merely read.
Moving money to individuals brings regulated obligations Identity verification, connected-account creation and payout execution delegated to an established payments provider, keeping the platform on the correct side of a boundary it should not be building itself.
Matching against a shift, not a project Structured the job around a date and time window, location, rate type and total hours, and structured worker availability as a calendar of dates — so matching is a query rather than an interpretation.
Four roles across four codebases Role-partitioned route trees with dedicated guards on the web client, and role-specific navigation shells on both native clients, sharing one API contract while keeping each role's experience focused.
Marketplace-scale client state A full unidirectional store on the web client with a slice per domain concept, effects isolating all server interaction, and resolvers prefetching route data — chosen over component-local state, which becomes unmaintainable well before a marketplace is feature-complete.
Personal data at rest Application-layer encryption of personal fields with key material held outside the codebase, accepting the loss of direct queryability on those columns as a deliberate trade.

Security & Reliability

Token-based authentication. The API authenticates clients with OAuth2 bearer tokens, with registration, verification, password recovery and account deactivation flows, plus federated sign-in through established identity providers.

Role separation across clients. The web application partitions its route tree by role behind dedicated guards; the mobile clients present role-specific shells; the administrative back office sits behind its own authentication boundary.

Personal data encrypted at rest. Personal fields on the user record are encrypted at the application layer before persistence and decrypted on read, with key material held outside the codebase, so database contents alone do not yield readable personal information. Passwords are stored as bcrypt hashes.

Verification delegated to a specialist. Identity verification and connected-account onboarding run through an established payments provider rather than being implemented in-house, keeping regulated identity handling with a party equipped for it.

An auditable money trail. Funding, release and withdrawal each produce ledger rows carrying their own credit, debit, resulting balance, type, initiating party and external reference, so financial position can be reconstructed rather than inferred.

Supervision as a control. The supervisor approval step is a security control as much as a workflow one: it places an independent party between a claim for payment and the payment itself.

Separation of configuration from code. Environment configuration and key material are linked into each release from outside the deployed tree, so credentials live with the environment rather than with the application.

Repeatable releases. Deployments run through continuous integration into versioned release directories with previous releases retained, giving a defined rollback path.

Scalability & Performance

Stateless application tier. Token authentication and externalised configuration keep application instances free of per-user state, so the API tier scales horizontally without session affinity.

Client-side state as a cache. The web application's store holds normalised domain data across components and route changes, so navigating the marketplace does not re-fetch what the client already holds.

Prefetched route data. Resolvers load what a view needs before it activates, removing the sequence of loading states that otherwise characterises a data-dense marketplace on a slow connection.

Batched upload from the field. Tracked intervals and verification artefacts are accumulated and uploaded in batches rather than streamed continuously, reducing request volume and tolerating the intermittent connectivity of a device carried through a working shift.

Paginated and filtered listings. Job, worker and history listings are filtered and paginated at the database rather than in the client, keeping result sets bounded.

Cached media on mobile. Both native clients cache remote imagery locally — profile photography, portfolio items and job media are the bulk of what these screens transfer.

An application shell that survives the network. Progressive Web App configuration caches the web application shell, so the interface loads on a poor connection and only data has to travel.

Business Outcomes

  • Hourly work off-site became payable with confidence, because approval rests on an independent supervisor reviewing evidence rather than on one party accepting the other's word.
  • The agency's risk-absorption role was replaced by mechanism — funds held from posting to approval, released against verified work, paid out to a verified account.
  • Shifts are matched, not advertised, because both the job's window and the worker's availability are structured data.
  • Disputes have something to resolve against, since tracked sessions, timesheets, approvals, rejections and every fund movement are all retained.
  • All four roles have a coherent product, on the device each of them actually uses, from a phone on site to a desk in an office.
  • Financial position is reconstructable, because money is recorded as a ledger rather than as a mutable balance.
  • Both sides have something to evaluate before committing, through bidirectional reputation, verified identity and a visible history of completed work.
  • The marketplace is discoverable, with public listings and profiles providing a route from search to registration.

Why it worked

Two-sided marketplaces are a well-understood pattern. The interesting work starts when two sides are not enough — when the transaction only closes because someone neither side controls is willing to attest to what happened. Getting that third participant right is a modelling problem before it is an engineering one, and getting it wrong produces a platform that looks complete and is quietly unusable, because the payment step never resolves.

Our team builds for that. We identified that supervised hourly work needs a supervisor in the data model, not a checkbox in a form, and gave that role its own identity, its own sign-in and its own product on every client we shipped. We treated tracked hours as something that must produce evidence rather than a number, and designed capture around the reality of a phone carried through a shift. We modelled money as a ledger because a marketplace that cannot explain a balance will eventually be asked to. And we drew the line at the regulated boundary, delegating identity verification and payout execution to a provider equipped for it rather than accumulating obligations the product did not need.

Our teams work across Laravel and modern PHP, large multi-client API design, Angular with rigorous state architecture, native Android in Kotlin and native iOS in Swift, payments and payout integration, and the workflow modelling that decides whether a marketplace closes its transactions or stalls at the last step.

Final Summary

Short-notice hourly staffing ran through agencies for a long time, and it ran through them for a reason: someone had to absorb the risk that sits between a business that cannot watch the work and a worker who cannot be certain of payment. A job board does not absorb that risk. It just moves the phone call online.

Our team built a platform that absorbs it structurally. Shifts are posted with a real window, a real location and a real rate, and matched against worker availability held as structured data. Hiring runs as a lifecycle rather than a status field, initiated from either side. Work is tracked in sessions that produce verification artefacts, and those hours are reviewed not by the business and not by the worker but by a supervisor assigned to the job — a third participant modelled as a first-class role with its own sign-in and its own product experience on every client. Approval releases funds that were held from the moment the job was posted, recorded as ledger entries rather than as an adjusted number, and paid out to an identity-verified account through an established payments provider.

Around that sit the things a marketplace needs to be used twice: bidirectional reputation, verified work history, portfolio and certification records, direct and group messaging, granular notification preferences, and public listings that give the platform a route from search to sign-up. It was delivered as a token-authenticated API with an administrative back office, a single-page web application built on a full unidirectional state architecture, and native Android and iOS clients — each of them carrying a distinct experience for every role on the platform. The result replaces the agency's margin with mechanism, which is the only substitution that actually works.

01 — Questions

asked about this kind of project

How do you verify hours on a marketplace for off-site hourly work?

Not by asking the two interested parties to agree, because they will not. Introduce a third participant with no stake in the number — in supervised staffing that is the site supervisor, a role the industry already has — and make their approval the condition that releases payment. Then make sure the tracked session produces artefacts the supervisor can actually review, so approval is a judgement about evidence rather than a rubber stamp on a claim.

Should a marketplace hold funds, or let the parties pay each other directly?

Hold them, if the marketplace is replacing an intermediary. Direct payment leaves one side carrying all the risk, and that side eventually takes the relationship off the platform. Holding funds from commitment to approval is what makes both sides willing to transact with a stranger — but it means identity verification, a proper ledger, a payout path and a real understanding of the regulatory boundary, so it is a decision to make early rather than to retrofit.

Build payment infrastructure or integrate a provider?

Integrate, in almost every case. Established providers supply identity verification, connected accounts, transfers and payout rails as products, and they carry regulatory obligations you would otherwise accumulate yourself. Build only the parts that are specific to your business — the balance model, the ledger, the release conditions — and let the provider handle the parts that are the same for everyone.

Why model money as a ledger rather than a balance field?

Because a balance can be corrected but never explained. Eventually a user disputes a figure, or a reconciliation does not tie out, and the only useful answer is a sequence of movements each carrying its own amount, resulting balance, type, initiating party and external reference. Retrofitting that after the fact is difficult and often impossible for historical data. It is one of a small number of decisions that are genuinely cheap on day one and genuinely expensive on day four hundred.

When should a marketplace go native on mobile rather than cross-platform?

When the product's core depends on device capability rather than screens — sustained background behaviour, location, camera, and reliable operation on a device carried through a working day away from power and good signal. If the mobile client is largely presenting data, the calculus is different. Here it was not, and both clients were built natively.

How do you keep a data-dense marketplace maintainable on the web?

Commit to a state architecture early. A unidirectional store with a slice per domain concept, effects isolating every server interaction, and route resolvers prefetching what a view needs before it activates. It looks like overhead in the first month and it is the reason the application is still tractable in the eighteenth. Component-local state in a marketplace becomes unmaintainable well before the feature set is complete.

How do you design for four distinct user roles without four products?

Partition by role at the routing and navigation layer while sharing the domain, networking and component layers underneath. Each role gets its own entry point, its own guarded route tree and its own navigation shell, so nobody sees a product cluttered with another role's concerns — but there is still one codebase, one API contract and one set of shared components to maintain.

What is the hardest part of building a multi-sided marketplace?

Not the software. It is being honest about what the existing intermediary was actually doing, because it is almost never just matching. Agencies, brokers and middlemen absorb risk, arbitrate disputes and carry reputational weight, and a platform that removes them without replacing those functions produces a marketplace where transactions start and never close. Find the function before you replace the actor.

03 — Similar project?

describe what is different about yours

Build yours.

Tell me what exists, what you need and the deadline. Fixed price for a defined scope, or hourly from $10 with a written estimate first.

Ahmedabad, India · IST (UTC+5:30) · --:-- IST · Mon–Fri 09:00–18:00 IST · US & EU overlap daily

No newsletter, no CRM. Just a reply.