Skip to content

Mohamed Salem Younes

All projects

Opal

livebuilt at SaySoft

A multi-tenant, multi-branch SaaS for dental clinics — patients, scheduling, an animated tooth chart, and the money — with tenant isolation enforced by the database itself.

NestJSPrismaPostgreSQLReactViteTanStack QueryTailwind CSSNext.js
132
API endpoints
821
Automated tests
50
Database tables
41
Permissions
<110 ms
Median API latency

PROBLEM

A dental clinic runs on four things that have to agree with each other: who the patient is, when they're booked, what was done to which tooth, and what that cost. Most clinics hold those in separate tools or on paper. Opal puts them in one system — sold as SaaS, so many clinics share it, each with several branches, and no clinic may ever see another's data.

WHAT'S IN IT

  • Multi-tenant and multi-branch: 45 clinic-scoped tables under forced row-level security, checked in CI, proven by a two-tenant isolation test.
  • 41 permissions across 3 roles (administrator, dentist, front desk); one person can hold several, and every endpoint requires a permission — nothing is open by default.
  • An SVG tooth chart with five clickable surfaces per tooth, adult and baby presets, two chart designs over one data model, keyboard navigation, and hover/select motion that respects reduced-motion.
  • Scheduler with day, week, month, and agenda views, drag-to-move in 15-minute snaps, ten appointment statuses shown by colour, icon, and label, and an allergy warning right on the booking.
  • Charted procedures become priced progress notes, completed ones become ledger charges — money stored as exact decimals, never floats, with doctor fees tracked separately.
  • A bilingual (English and Arabic) Next.js marketing site, and eleven name-and-logo directions built as a working demo the client chose Opal from.
  • A full QA pass — 74 findings, 63 fixed and verified — and every endpoint under 110 ms at the median against 10,000 seeded patients.

ROLE

Engineer at SaySoft — backend (NestJS, Prisma, PostgreSQL), frontend (React, Vite), the Next.js marketing site, the brand exploration the client chose from, and the QA and hardening passes.

NOTABLE DECISION

Tenant isolation lives in Postgres, not only in application WHERE clauses. Every clinic-scoped table (45 of 50) has a forced row-level-security policy keyed on the current tenant, and CI fails if a new table ships without one. Setting it up surfaced a real trap: the default database user is a superuser and silently bypasses RLS — so the running server connects as a second, restricted role, and a two-tenant test proves one clinic genuinely cannot read another's rows.