The challenge
The food and hospitality trade has a set of problems that are usually solved by separate products. Restaurants need staff, and hospitality staff need work. Restaurants and distributors need to buy, sell and rent equipment and supplies from each other. Businesses want to promote offers to the trade. Operators want advice.
Each of those is a viable product on its own. Built as four separate products they share nothing, which means four sign-ins, four mobile apps, four sets of business rules about who a restaurant is, and four opportunities for the same company to be represented inconsistently.
The genuine difficulty is that these audiences overlap without being identical. A restaurant is an employer, a buyer, a seller and a promoter, sometimes in the same week. A distributor sells but does not recruit. A job seeker uses one part of the platform and should not be shown the rest. Modelling that as one flat user type produces an interface full of things most people cannot use, while modelling it as four separate accounts produces exactly the fragmentation the platform exists to avoid.
Approach
One identity, capabilities layered on top. An account is a single identity that holds one or more roles. A restaurant gains employer capability and trading capability. A distributor gains trading capability only. A job seeker gains applicant capability. What the interface offers follows from the capabilities held, so the same account grows into new parts of the platform without a second registration.
This is the decision that keeps the platform coherent. It also means adding a fifth module later is a capability rather than another silo.
Listings share a spine, not a schema. A job posting, an item for sale, a rental offer and a promotion are different things with genuinely different fields. What they have in common is the lifecycle: created by an account, moderated, published, expiring, renewable, withdrawn. Sharing that lifecycle while keeping each type’s own attributes separate is what allows one moderation queue, one expiry mechanism and one set of notification rules to serve all of them.
Mobile is a client, not a port. The web application and the native iOS and Android apps consume the same API. There is no second implementation of the business rules, which is the usual source of divergence in platforms that add mobile later, where an offer expires correctly on the web and stays visible in the app for another week.
Multilingual is structural. Switzerland is not a single-language market, and retrofitting translation onto a system that assumed one language is invasive. Interface text and user-generated content are handled separately, because they are different problems: interface strings are translated once by the operator, while a listing is written by a user in their own language and needs presenting sensibly to someone who does not read it.
Trading requires trust signals. A marketplace between businesses that will transact offline does not need to process the payment, but it does need the participants to be confident in each other. Verified business accounts, clear listing provenance and moderation matter more here than transactional features, because the platform’s role is to make the introduction credible.
Promotions are time-bound by nature. An offer that has expired but is still displayed is worse than no offer at all, since it produces a call to a business that cannot honour it. Expiry is enforced by the platform rather than left to the account that created it.
Results
The platform runs recruitment, a trading marketplace, a shop and promotions from a single account model spanning four user roles, delivered to browser, iOS and Android from one shared API, and built for a multilingual market from the start.
The layered capability model is what has mattered most. Because roles are additive rather than exclusive, a business that joined to hire staff can begin trading or promoting without creating anything new, and the platform can add a module without asking its existing users to sign up again.