"case_study": "alalahub"
A LinkedIn-style super-app for the Greek market
One app serving job seekers, companies, and recruiting agencies — plus a local gig-work marketplace and bookable freelance services. Every feature exists three times, once per side of the market.
"role"
Full-stack development — React Native app, Next.js web client, Express + Prisma backend
"stack": [8]
- React Native
- Next.js
- Express.js
- Prisma
- PostgreSQL
- Socket.IO
- Firebase
- Redis
The problem
Professional networking products assume one kind of user. Alalahub serves three — individuals building a profile and applying to jobs, companies posting and managing applications, and recruiting agencies managing candidate pools — and adds two marketplaces on top: local day-work with on-site check-ins, and bookable freelance services. All of it localized for Greece and the wider EU.
That multiplies everything. Profiles, dashboards, chat, notifications, and permissions all need three variants that stay consistent with each other, in 27 languages.
What was built
- A social layer — feed, articles, comments, follows — alongside formal job posting, applications, and a job–candidate matching service.
- Separate portals for companies (job management, team management, application chat) and agencies (candidate pools, applications on behalf of candidates).
- A local gig-work marketplace with check-in/check-out, feedback, and a worker reputation system.
- Real-time messaging over Socket.IO with read receipts, plus push notifications through Firebase Cloud Messaging.
- Subscriptions and paid boosts across four payment providers: Revolut Pay, RevenueCat, Apple In-App Purchases, and Google Play Billing — each with its own webhook lifecycle.
Architecture decisions
- A single Express + Prisma backend (90+ data models on PostgreSQL) serves both the React Native app and the Next.js web client — one source of truth, two frontends.
- The EU ESCO occupations-and-skills taxonomy powers structured profiles and matching, with Redis caching to keep autocomplete fast.
- Company onboarding auto-fills from the Greek GEMI/AFM business registry instead of asking users to type registration data.
- Authentication supports Google, Apple, and email/phone OTP, with refresh tokens and multi-device session management.
- Content localization runs through a translation service and i18next — 27 locales shipped, not bolted on.
What made it hard
The payments surface was the sharpest edge: four providers means four different webhook contracts, four failure modes, and one subscription state that must stay correct across all of them. The webhook handlers and payment services are isolated per provider with a shared subscription model, so a RevenueCat event and a Revolut event resolve to the same customer state.
The second was keeping three user types coherent. A job application touches a seeker, a company, sometimes an agency, chat threads, and notifications — modeling that cleanly across 90+ tables is where most of the schema work went.