An Arabic-first e-learning marketplace for Algerian students, live with thousands of enrolled learners.

Overview.
Algerian school students and their parents
From fourth grade to the baccalaureate year. They pay in dinars by CCP or BaridiMob transfer, use Arabic, and mostly browse on phones. The teachers are independent tutors who already have a following.
Tutoring runs on WhatsApp and cash
Lessons shared as loose video links, payments confirmed by chat, no progress tracking, no exams, and no way for a teacher to sell to students outside their city.
A marketplace with an operator in the loop
Teachers publish courses with video, quizzes and files. Students enrol by uploading a transfer receipt that a human approves. The platform takes a commission and gives every role its own dashboard.
Walkthrough.
A landing page that sells a school, not a SaaS
Parents and students in Algeria are the buyers. The home page speaks to them in Arabic, leads with real teachers and real numbers, and keeps every call to action pointed at the catalog or sign-up.


- 1Made in AlgeriaThe header badge, CCP payment methods and ar-DZ copy make the platform feel local. Right-to-left layout throughout, on every breakpoint.
- 2Proof up frontStudent count, five-star rating and a live-class chip sit on the hero illustration. The numbers are wired to the marketing copy, the catalog reads them from the database.
- 3Two paths, one funnelCreate account or browse courses. Both end at the same enrolment flow, so nothing on the landing page is a dead end.
Structured by school stage, fronted by people
Algerian schooling has three stages and exams that matter. The site is organised the same way, and the teachers are shown by name and subject because that is what parents ask about first.


- 1Three stagesPrimary, middle and secondary, each with its own card, course count and a direct link into the filtered catalog.
- 2Teachers by subjectPhotos, subject, stage and years of experience. The teacher record drives the course page, the revenue split and the approval queue later on.
- 3Stats stripRegistered students, teachers, hours of content and support hours, rendered from live counts rather than hard-coded text.
Sixty-nine courses, filterable in two taps
The public catalog is the busiest page. It has to work for a parent on a phone and a student comparing prices, so filtering is by stage and by course type, with prices in dinars and discounts shown honestly.


- 1Filters with countsSchool year (from fourth grade to final year) and course type (monthly, seasonal, annual). Each chip shows how many courses match before you tap.
- 2Honest pricingOriginal price, discounted price and the percentage saved on every card. Monthly subscriptions from 1,200 DZD, seasonal courses from about 3,400 DZD.
- 3Cards that load fastThumbnails are compressed to WebP on the teacher's device at upload time and served with immutable caching. That fix is what kept the platform on the free storage tier.
Everything a parent needs before paying
A course page carries the schedule, what is included, the teacher's profile and the price. It is the page people send to each other on WhatsApp, so it has to answer every question without a login.


- 1Schedule and formatLive session times, recorded replays, PDF summaries, homework and exams, all listed in the description block.
- 2Price cardDiscounted price, original price struck through, percentage saved and a single enrol button. No hidden fees.
- 3Teacher cardName, stage, subject, bio, graduates, rating and years of experience, pulled from the same teacher record the admin manages.
Pay by CCP or BaridiMob, upload the receipt, get approved
There is no Stripe in Algeria. Instead of blocking on that, the platform turns a bank transfer into a reviewable request with a clear status for the student and a queue for the teacher.

- 1Per-course payment detailsEach course carries its own CCP account or BaridiMob number, so a teacher can be paid to their own account.
- 2Receipt uploadThe student uploads a screenshot of the transfer. It lands in a pending queue with the course, the amount and the timestamp.
- 3Approval creates accessA teacher or admin approves the request, which creates the enrolment and records the commission split. Nothing on the client can grant access to itself.
Video that is hard to steal, quizzes that grade themselves
Once enrolled, students watch lessons through Mux, track progress, take quizzes and download materials from their dashboard.
- 1Mux player with hardeningBlocked context menu, intercepted fullscreen keys, tab-visibility monitoring and a security timeout around the player. It deters casual copying without pretending to stop screen capture.
- 2Quizzes with mathPassing score, time limit, attempt limits and KaTeX-rendered questions with images. Attempts are graded server-side and explanations show after submission.
- 3Files and progressPDF library per course with view-only mode through an embedded viewer when downloads are disabled. Lesson progress is stored per student.
Upload, build, publish, get paid
Teachers run their own courses: upload video straight to Mux, build lessons and quizzes, approve enrolment requests and watch net revenue after commission.
- 1Direct-to-Mux uploadThe browser uploads to Mux directly. A signed webhook reports when the asset is ready and a status function catches stuck uploads.
- 2AI quiz generationPaste lesson content and get draft questions from an LLM, then edit them in the same editor as manual questions.
- 3Requests and revenueA queue of pending subscribers to approve, and a revenue page showing gross, commission and net per course.
A marketplace needs an operator
Admins manage teachers, students, courses, commissions and reports. Staff accounts get page-level permissions so a support worker can approve payments without seeing revenue.
- 1Page-level RBACThirteen page keys such as courses, subscribers and commissions. A worker sees only the pages an admin grants.
- 2Commissions and reportsPlatform commission per enrolment, teacher net revenue, activity log and alerts.
- 3Admin-created teachersTeacher accounts are created by an edge function with the service role, never by open sign-up.
Architecture.
Engineering deep dives.
1. Manual-payment subscription pipeline
- Problem
- The Algerian market has no card gateway that students can use. Enrolment still has to be reliable and auditable.
- Approach
- Per-course payment details (CCP or BaridiMob), a receipt-upload page, a pending_subscribers queue, approval screens for teachers and admins, then course_enrollments plus a commission record so admin gross and teacher net revenue reconcile.
- Trade-off
- A human reviews every payment. Right for bank transfers, but there is no automated reconciliation.
2. Mux video pipeline with signed webhooks
- Problem
- Teachers upload large videos from ordinary connections, and the platform must know when playback is ready without polling forever.
- Approach
- Direct upload URLs from Mux, a Deno edge function that verifies the mux-signature header with HMAC-SHA256 before persisting asset and playback ids, and a separate status function for stuck uploads.
- Trade-off
- The same endpoints exist in three homes (edge functions, an Express server and serverless handlers) from a migration. Flexible, but duplicated.
3. Anti-piracy player hardening
- Problem
- Paid lessons get copied and reshared. Nothing client-side can stop a determined screen recorder, but casual copying can be made annoying.
- Approach
- Capture-phase key interception that blocks the player's own fullscreen hotkey, context-menu suppression, visibility-change monitoring and a security timeout around the player.
- Trade-off
- Client-side only. Documented as a deterrent, not a DRM system.
4. The storage-egress fix
- Problem
- Uncompressed phone-camera PNGs blew through the free-tier Supabase egress, which would have meant a paid plan for a platform charging in dinars.
- Approach
- Client-side canvas re-encoding to WebP with EXIF orientation correction, one-year immutable cache headers on upload, a lazy-loading SmartImage component, and a script plus SQL guardrails to recompress existing objects.
- Trade-off
- Compression happens on the uploader's device, so quality depends on the browser's canvas. Zero server cost in exchange.
5. Files and quizzes linked to many courses
- Problem
- A teacher's PDF or quiz often applies to several courses. A junction table would have needed a migration with downtime on a live platform.
- Approach
- A course_ids UUID array with GIN indexes and overlap queries, keeping the original course_id for backward compatibility, plus per-file visibility and download-allowed flags that drive student-side filtering.
- Trade-off
- Array columns are simpler to query but weaker on referential integrity than a junction table.
6. Auth deep links under hash routing
- Problem
- Supabase recovery emails put tokens in the URL fragment, which collides with hash-based routing. Users landed on a 404.
- Approach
- Recovery redirects to the site root, token and error hashes are rewritten into a routable reset-password URL, the app listens for the PASSWORD_RECOVERY event, and legacy double-hash links are handled by setting the session manually.
- Trade-off
- Hash routing was inherited from the original build and kept to avoid breaking shared links.
Business model.
- Browse and enrol
- Watch, quiz, download
- Track progress
- Publish courses and lessons
- Approve requests
- Net revenue and students
- Page-level permissions
- Approve payments
- Support without revenue access
- Everything, plus commissions
- Create teacher accounts
- Reports, alerts, activity log
Results.
Thousands of students, hundreds of paid enrolments
More than 2,150 registered students, over 760 approved course enrolments and 69 published courses from 13 teachers, all counted from the production database.
Still on the free storage tier
Client-side WebP compression and immutable caching brought storage egress back under the free limit after the first surge of phone-camera uploads.
Payments without a gateway, at scale
Hundreds of transfers reviewed and approved through the in-app queue, with commission and net revenue reconciled per course.
What's next.
Engineering debt I would pay first
Tighten row-level security so authorization does not rely on client-side role checks, consolidate the three Mux backends into the edge functions, add CI that runs the existing Vitest suite and type checks, and add error tracking.
Product roadmap
In-app live classes instead of external meeting links, a native app for students, automated payment reconciliation when a local gateway becomes viable, and teacher analytics on lesson completion.