LMS
CambridgeTCB
CambridgeTCB online training product delivered from the ecourse Laravel 10 tree (FreeLancer/ecourse): Breeze-authenticated learner storefront with cart middleware, course and lesson playback (including Vimeo-backed content paths), Moyasar payments, wishlist and reviews via Livewire, and a separate Board admin under /Board (dedicated admin auth) for categories, course or unit or lesson hierarchy, user enrollments, trainers, ratings, and Excel imports—plus S3-ready Flysystem, Spatie Laravel Translatable, and a minimal Sanctum API (/api/user).
Problem
What was broken
The client needed a credible course catalog with smooth purchase-to-classroom flow: searchable programs, persistent cart, trustworthy checkout, lesson delivery with progress, and a back-office that non-developers could use to publish curricula without touching production code.
Solution
How we fixed it
Implemented a two-surface Laravel app wired in `RouteServiceProvider`: `routes/web.php` drives the public Blade and Livewire experience (search, cart, checkout, lessons, profile, reviews), while `routes/board.php` isolates staff workflows behind `/Board` and `admin` middleware with resource controllers complemented by Livewire components for long forms (courses, units, lessons, users). Payments go through Moyasar; media and large assets align with S3; lesson video integrates with the Vimeo Laravel package; multilingual copy uses Spatie Translatable where modeled.
Challenges
What made this hard
Lesson and progress URLs must stay consistent when editors reorder units; Excel imports need validation so bad rows do not corrupt nested course structures; separate Board and Breeze sessions require clear logout and guard names so support staff never land on learner dashboards by mistake.
Architecture
How the system is shaped
API Structure
`routes/api.php` is intentionally thin: Sanctum’s `auth:sanctum` `/user` route for token clients. Nearly all behavior is classic web plus Livewire; Board uses its own login controller separate from Breeze’s learner auth to reduce session confusion between roles.
Data Flow
Visitor browses courses under `cart` middleware → cart session lines → Moyasar-backed checkout → order and enrollment rows. Learner opens `/course-content/{course}/lessons/{lesson}` for playback and progress storage. Staff mutate catalog and assignments in Board; Maatwebsite Excel or Spatie Simple Excel back bulk category or course imports.
Backend Decisions
Split public and Board route files so admin URL space and middleware stay predictable; prefer Livewire on repetitive CRUD and checkout UX while keeping thin controllers for document downloads and redirects; keep payment vendor logic out of Blade except through dedicated checkout components.
Decisions
Why this stack and shape
Laravel 10 and Breeze for standard auth scaffolding; Livewire 2 for cart, checkout, and Board editors; Moyasar for cards; Flysystem S3 disk for scalable file storage; Vimeo package instead of self-hosted streaming for reliability.