Home / Projects / FG88 Academy — Futsal Academy Management Platform
Featured Project
FG88 Academy — Futsal Academy Management Platform
Production web app for a kids' futsal academy in Karawang: semester report cards with FIFA-style player cards and radar charts, attendance, monthly fees, and parent access — 211 active students.
Role
Fullstack Developer & DevOps
Duration
Oct 2026 – present
Team
Solo developer
Tech Stack
SvelteKit · Elysia · Cloudflare Workers · Neon Postgres · Drizzle ORM · Hyperdrive · Cloudflare R2 · Tailwind CSS · daisyUI · Web Push · GitHub Actions
Architecture Diagram
Click a node for the decision behind it
- A Parents · Coaches · Admin
- Parents log in with a student ID or the child's NIK plus a password set by the academy — no email signup needed for users who will never check email.
- B SvelteKit PWA
- The SPA is a PWA with a service worker, so parents can install it on their phones and receive push notifications like a native app.
- C Elysia API on Cloudflare Workers
- One Worker serves both the SPA and /api/*, so the whole product deploys as a single unit on the free plan.
- D Neon Postgres via Hyperdrive
- Drizzle migrations apply to a Neon dev branch first; production migrations only run after checks pass in CI.
- E R2 photo & file storage
- Photos are resized to 320px in the browser before upload and stored in R2. The database keeps only file paths, which keeps Neon egress well under the 5 GB free tier.
- F Cron Trigger 17:00 WIB
- A cron trigger fires every 5 minutes in the 17:00 WIB window and sends H-1 training reminders through Web Push.
- G Web Push H-1 reminders
- Reminders arrive on parents' phones as push notifications from the installed PWA — no manual WhatsApp broadcast from the admin.
- H Analytics Engine
- Registration-funnel events (WhatsApp clicks, signup submissions) go to Analytics Engine, readable through the SQL API without a separate analytics product.
- I GitHub Actions CI/CD
- Every push runs tests and typechecks; pushes to main also migrate the production database and deploy the Worker.
A management platform for FG88, a kids’ futsal academy in Karawang. Live in production at fg88academy.id with 211 active students, used daily by coaches, admins, and parents.
Problem
The academy ran on WhatsApp and paper. Attendance lived in chat messages, monthly fees were tracked by hand, and a child’s development over a semester existed only in the coach’s head. Parents asked the same questions every month: did my kid attend, what did we pay for, is my kid actually improving?
Solution
I built one app with three login types. Parents enter a student ID or their child’s NIK — no email, because most would never verify one — and see report cards, attendance history, and fee status. Coaches take attendance per session and fill in physical and technical test results once per semester. Admins handle students, schedules, fees, coach accounts, and approve new registrations that come in through the public signup page.
The report card is the part parents actually open: each student gets a FIFA-style player card with a rating, and a radar chart compares eight physical and technical attributes against the benchmark for their age group. Report cards are per semester, so parents can see progress between periods, and they can be downloaded as a PDF.
Key Features
- Semester report cards: player card, radar chart vs age-group benchmark, PDF export, comparison with the previous semester
- Attendance per training session, with check-in and payment status per date
- Fees: monthly dues, per-visit payments, and a one-time registration fee with QRIS and receipt upload
- Public registration with admin approval, plus an event funnel tracked in Analytics Engine
- H-1 training reminders via Web Push from a cron trigger, plus a WhatsApp reminder button per parent
- PWA: installable, works on the phones parents and coaches already use
Architecture Decisions
- A single Cloudflare Worker serves the SvelteKit SPA and the Elysia API, so deploys are one unit and the free plan covers everything.
- Postgres lives on Neon behind Hyperdrive connection pooling, with Drizzle for schema and migrations.
- Photos are resized to 320px in the browser and stored in R2; the database only keeps file paths, because Neon free-tier egress is 5 GB/month.
- Passwords use PBKDF2 at 50,000 iterations — Workers caps PBKDF2 at 100k, and 50k keeps login CPU time under the free-plan limit.
- Migrations apply to a Neon dev branch first; GitHub Actions runs tests and typechecks on every push, and only main triggers the production migration and deploy.
Trade-offs
- One Worker for SPA plus API keeps operations simple, but every frontend tweak ships with the API. For a one-developer product that is a good trade.
- 320px photos and path-only storage keep the project on free tiers, at the cost of image resolution — acceptable for ID-style student photos.
- Automated WhatsApp reminders would need a paid gateway, so the app sends Web Push for users who installed it and gives admins a one-tap WhatsApp button for the rest.
What I Learned
The hardest part was not the stack; it was designing for users who are not technical. Coaches fill test results on their phones between sessions, and parents open the app maybe once a month. That shaped everything: semester-keyed test results instead of free-form entries, benchmarks per age group instead of raw numbers, and a login that works with a student ID printed on a member card.