SIM Casting — PT. JBTB Casting Creative Group
A Laravel 13 system that replaced a casting agency's manual WhatsApp, Excel, and Drive workflow, so fee agreements, staff honor, and project finances are recorded instead of argued over later. Built as a team final year project, where I lead the build: data model, backend, and full-stack logic end to end.
Why I Built It
I wanted my final year project to solve a real problem for a real company, not be a tutorial-scale CRUD app. The agency's own team described how fee deals and pay were tracked across chat threads and spreadsheets, and our team took that on as the project, with me leading the system build while teammates cover the academic documentation.
Project Goal
Replace the agency's manual recruitment-and-payment process with one system that solves three concrete problems: fee agreements between Admin and Extras that can't be disputed after the fact, staff honor that comes with a clear payslip per project instead of a guess, and project finances (income, receivables, expenses, balance, projection) computed from a single source instead of scattered spreadsheets.
What It Does
- check_circleIn-app multi-round fee negotiation between Admin and Extras, every offer logged until there's a deal, so what got agreed to is never up for dispute later
- check_circleStaff honor set per event, with a payslip PDF generated automatically once the project wraps, replacing a guessed number with an actual slip
- check_circleProject finance view (income, receivables, expenses, balance, projection) computed from one source, with invoices that get signed and marked paid
- check_circleDigital contract generated automatically when a candidate is confirmed, signed on screen, and voided automatically if the booking is cancelled (audit trail preserved)
- check_circleField attendance: Extras check in with a selfie, the on-site coordinator validates or rejects it, and notes or sanctions are logged per person
- check_circleIn-app notifications as the primary channel, plus a self-hosted WhatsApp gateway running as a queued job so a failed message never blocks the action that triggered it
Key Screens
Tech Stack
Mass assignment is attribute-based (PHP 8 #[Fillable]) rather than the classic $fillable property, paired with Model::preventSilentlyDiscardingAttributes() in non-production, so a forgotten column on a new field throws immediately in dev instead of silently dropping data in production. NIK lookups use a separate HMAC-hashed column (keyed independently from APP_KEY) specifically so duplicate-detection queries never need to decrypt the encrypted NIK column itself.