Back to projects

Shohraty

Trilingual, RTL-first commerce and CMS platform for an Algerian marketing agency: a public site, an admin backoffice, and a versioned form-schema engine, live on the client's own infrastructure.

LiveLive, private repoTrilingual CMS and commerce platform / Mar - Sep 2026

Problem

The agency needed to run its own content, services, intake forms, careers and store without a developer in the loop — in three languages, under Algerian data protection law, and on infrastructure it owns rather than rents abroad.

Solution

A NestJS API with separate public and admin surfaces over one Prisma schema, a Refine backoffice for staff, and a Next.js public site. Service intake forms are authored by admins and frozen as immutable schema versions, so a form can change without invalidating the requests already answered against the previous shape.

Key Features

Admin-authored service intake forms: steps and fields defined in AR/FR/EN, frozen as an immutable ServiceFormVersion, and rendered as a multi-step wizard the frontend never hard-codes
Every submission records the schema version it answered, so changing a form never orphans the requests already collected against the old one
Google Sheets sync with per-row status, attempt counts and retry-with-backoff; a column-shape change spawns a new version and its own service-vN tab
Two API surfaces over one schema: open and throttled at /api/public/*, JWT cookie plus CSRF at /api/admin/*
Arabic as the default locale with RTL as the base case, and a language-aware fallback chain when a translation is missing
Algerian localisation as a constraint, not a translation: DZD pricing, wilaya and commune data, local phone validation, CCP and BaridiMob payment methods
Cookie consent gated on Algerian Law 18-07, with analytics and ad pixels loading through GTM only after the matching category is accepted
Hardening pass before launch: request timeouts, a global error boundary, on-demand revalidation, image optimisation, and accessible names on every icon-only control

System map

3 repos / 1 schema
Public siteNext 16 · AR/FR/EN · RTL16k LOC · 234 commitsBackofficeRefine · TipTap · Vite18k LOC · 145 commits/api/public/*open · throttled/api/admin/*JWT cookie + CSRFNestJS 1121 modules147 endpoints48 test filesPostgreSQLPrisma 7 · 30 modelsServiceFormVersionimmutable schemasteps → fields · AR/FR/ENSheetsone tab perservice-vNreadswritesrenders 8-step wizardretryDEPLOYEDshohraty.dz · client VPS · nginx · v1.0.0MEASURED 4 SEP 2026TTFB 87ms · FCP 568ms · LCP 1.02s · 63KB
Two client apps, two API surfaces, one schema. The violet path is the part worth asking about: an admin authors a form, the backend freezes it as an immutable version, the public wizard renders that version, and every submission is stamped with the version it answered before a retrying job mirrors it into a per-version spreadsheet tab.

Shohraty Screenshots

7 views
The live Arabic homepage. Arabic is the default locale and the whole layout is right-to-left, not a mirrored afterthought.
The same page in English. Direction, navigation order and card sequence all flip from one content tree — the pair is the clearest proof the RTL work is real.
Step 3 of 8 in the service request wizard. None of these fields is in the frontend code: an admin authored them in three languages and the backend froze that definition as an immutable form version.
The wizard renders whatever the current schema version defines, including how many steps there are. The progress indicator is generated, not hard-coded.
Services are CMS records, not routes. Each one carries its own translations, FAQ, workflow phases and request form.
Consent is gated on Algerian Law 18-07, with per-category opt-in. Analytics and ad pixels only fire through GTM once the matching category is accepted.
The Arabic homepage at 390px. RTL has to survive every breakpoint, not just the desktop one.