Skip to content
Ercan Labs
← All workPLATFORM · OPEN-SOURCE · shipped

Beauty Salon Platform

Multi-tenant booking and operations platform: one API, one admin panel, two Flutter apps.

134
Test files
483
Source files
4
Clients

How this was measured: Test and source files counted in the repo; tenant isolation covered by tests.

Architecture134 test files
  1. CLIENTS
    • müşteri
    • personel
    • işletme
    • admin
  2. API
    • ExpressREST
  3. TENANCY
    • tenant scopeher sorguda
  4. DATA
    • PostgreSQLSequelize
Tenant id arrives with the request and enters every query as a parameter; forgetting it breaks a test.

Problem

A salon platform is multi-tenant from the first line: every salon has its own staff, services, calendar and customers, and one salon must never see another's data.

The same product has to serve three very different users: the customer booking on a phone, the salon owner managing a team, and the platform operator watching every tenant.

Constraints

  • Tenant isolation is not a filter added per query; it is a property of the data access layer.
  • Four clients, one codebase: API, admin panel, salon app, customer app.
  • The platform must refuse to run in production with a default seed password.

Architecture decisions

01

Tenant id is a required parameter

Tenant identity is not an ambient assumption; it is passed explicitly into module calls, so a missing tenant is a compile error rather than a silent cross-tenant read.

Cost: More verbose call sites.

02

Isolation proven by tests

Cross-tenant access is tested, not assumed: reading another tenant's data is asserted to fail.

Cost: Test suite runtime.

03

One codebase, four clients

Flutter for both salon and customer apps, Next.js for admin, Express/Sequelize for the API; shared conventions and role model.

Cost: Shared model changes ripple across four clients.

04

Default password cannot reach production

Seeding with a default password is blocked in code, not by documentation.

Cost: Slightly slower first deploy.

Proof

  • Test files134
  • Source files483
  • Clients4 (API, admin, salon app, customer app)
  • Tenant isolationcovered by tests

Known limits

  • Open-source reference project; not operated commercially at scale.
  • Payment and SMS integrations are stubbed for local development.

What I learned

Multi-tenancy is decided in the data access layer, not in code review. If the tenant id can be forgotten, it will be forgotten — in the one query nobody looked at.

Stack

ExpressSequelizeNext.jsFlutterPostgreSQL