Hallego is a hyperlocal second-hand marketplace for families with children, live on Google Play in Turkey. I designed and built the whole product on my own: API, mobile app, website, admin panel, infrastructure and AI moderation.
The source code is private because it is a product in production. This repository shows how it is built, with the numbers and a selection of the architecture decision records (ADRs).
Version française : README.fr.md
- App: Hallego on Google Play
- Website: hallego.com
- Open source package I extracted from the project: @mdsiha369/adonis-mercure (source)
flowchart LR
M[Flutter app<br/>Android] -->|REST| A[AdonisJS API<br/>TypeScript]
W[Next.js website] -->|REST| A
X[Next.js admin panel<br/>behind Cloudflare Access] -->|REST| A
A --> P[(PostgreSQL + PostGIS)]
A --> R[(Redis)]
R --> Q[BullMQ workers]
Q --> AI[Vision LLM<br/>moderation and trust score]
A -->|publish| H[Mercure hub<br/>SSE]
H -->|real-time messages| M
Measured on the code base on 2026-11-02.
| Part | Figure |
|---|---|
| API | 30 modules, 199 endpoints, 125 database migrations |
| Mobile app | 60 screens, 45 BLoCs (Flutter) |
| Automated tests | 1,428 API, 1,186 Flutter, 34 website, all passing |
| Architecture decisions | 27 ADRs, 5 published here |
- API: Node.js 22, AdonisJS 6, TypeScript, PostgreSQL 17 with PostGIS, Redis, BullMQ
- Mobile: Flutter, BLoC
- Web: Next.js 16, React 19, Tailwind CSS, in a pnpm monorepo (public site and admin panel)
- Real time: Mercure over Server-Sent Events
- AI: Anthropic Claude behind a provider abstraction (OpenAI and Gemini are supported)
- Infrastructure: Docker, Coolify on Hetzner, GitHub Actions, Cloudflare
The interface is in Turkish.
AI-assisted moderation. Every new ad goes through an asynchronous pipeline. A vision model analyses the photos and produces a trust score, and the result routes the ad to publication or to a human moderator. The pipeline has an automatic kill switch when the model fails, versioned prompts, a benchmark corpus to compare prompt versions, and an admin console that tracks cost, latency and quality.
Real-time messaging. Chat uses Mercure (SSE) rather than WebSockets, with token-scoped private topics. See ADR-0002. The adapter I wrote for AdonisJS is published on npm.
Clean backend structure. Each business module follows an Action, Controller, Repository layout so that controllers stay thin. See ADR-0005.
Pragmatic infrastructure choices. PostgreSQL full-text search instead of Elasticsearch (ADR-0003), and Redis with BullMQ instead of a cloud queue (ADR-0004).
Privacy by design. The product follows the Turkish data protection law (KVKK): encryption at rest, audit logs, soft deletes, and server-side obfuscation of exact locations.

The exact address is never shown: the app displays a 750 m circle computed on the server.
| ADR | Decision |
|---|---|
| 0001 | AdonisJS 6 over NestJS |
| 0002 | Mercure and SSE over WebSockets |
| 0003 | PostgreSQL full-text search over Elasticsearch |
| 0004 | BullMQ and Redis over cloud queues |
| 0005 | Action, Controller, Repository pattern |
The other ADRs cover security and operations details and stay private.
Michael DAS, full-stack software engineer, relocating to Ottawa, Canada. Email: mchdas@proton.me
© 2026 Michael DAS. All rights reserved. The text and images in this repository are shared for presentation purposes only.



