cholid
#Laravel#Tailwind CSS#MySQL#Wasmer#Web App#PHP
Back to projects

Application Purpose

PSB-RQ (Penerimaan Santri Baru — Raudhatul Qur’an) is a web-based student admission information system for TK Tahfidz Raudhatul Qur’an, an early childhood education institution (KB/TK) focused on Quran tahfidz under Yayasan Ihyaul Qur’an Indonesia (IQI), Malang.

Background

Before this system was built, the registration process used Google Forms, and subsequent processes were entirely manual. This made it difficult for schools to manage applicant data, track status, and provide real-time information to parents.

Goals & Benefits

  1. Digital Registration — Parents can register online from anywhere without needing to visit the school, simply by filling out a multi-step form and uploading required documents (photo, family card, birth certificate).

  2. Status Transparency — Each applicant receives a unique registration number that can be used to check their admission status in real-time at any time, without needing to contact the school.

  3. Administrative Efficiency — School staff have an admin panel to manage applicant data, verify documents and payments, and monitor registration statistics through a dashboard.

  4. Period & Fee Management — The school can easily open/close registration windows and configure registration fees with detailed breakdowns independently.

  5. Complete Audit Trail — Every applicant status change is recorded in the status history, simplifying audits and tracking in case of disputes or inquiries from parents.

Application Users

User Primary Needs
Parents Register online, check status, upload payment proof
Admin/Staff Manage applicants, verify documents, configure periods & fees, publish announcements
Super Admin Full admin access + manage other admin accounts

Tech Stack Rationale

Every technology in this stack was chosen based on specific considerations of the school’s needs, resource constraints, and the project’s long-term goals. Here’s the reasoning behind each decision:

Framework: Laravel 13

Why Laravel?

  • Mature ecosystem for data-driven applications — PSB-RQ is fundamentally a CRUD application with a multi-status workflow. Laravel provides Eloquent ORM, migrations, seeders, form request validation, and queues — all features used directly without building from scratch.
  • Built-in security — The school handles parents’ personal data (names, addresses, phone numbers) and family documents. Laravel provides CSRF protection, XSS escaping, SQL injection prevention via parameter binding, and bcrypt password hashing out of the box.
  • Large community & documentation — This project is built by a single developer. Laravel’s comprehensive documentation and rich package ecosystem (Laravel Debugbar, Laravel Tinker, Laravel Pail) accelerate development without reinventing existing solutions.
  • Laravel Sail — Simplifies the development environment with Docker Compose. Just composer create-project laravel/laravel + sail up -d, and the developer has a consistent PHP + MySQL + Redis environment without manual XAMPP/LAMP configuration.

Frontend: Blade + Tailwind CSS v4

Why Blade instead of React/Vue?

  • Simplicity — This application doesn’t need heavy interactivity like an SPA (Single Page Application). Blade as Laravel’s server-side templating engine is sufficient: form validation, page navigation, and statistics dashboards can be rendered quickly on the server.
  • Single language — All logic in PHP, all templates in Blade. No need to manage two codebases (frontend & backend), no complex build steps for small changes, no client-side state management.
  • Laravel + Blade = high productivity — Features like @auth, @guest, x- components, layout inheritance, and slots enable clean, reusable template code without a JavaScript framework.

Why Tailwind CSS v4?

  • Visual consistency without custom CSS — With utility classes, the developer doesn’t need to write new CSS selectors for every component. The result: visually consistent styling across all pages.
  • Minimal production file size — Tailwind v4 uses the Vite plugin (@tailwindcss/vite) which automatically tree-shakes unused utility classes. The production CSS file only contains classes that are actually used.
  • Dark mode ready — Tailwind makes dark mode implementation easy via the dark: variant, providing flexibility for future accessibility needs.
  • Responsive without manual media queries — The sm:, md:, lg: utilities enable responsive layouts with inline declarations, without writing a single @media query.

Icons: Heroicons

Why Heroicons?

  • Consistent design — An icon set from the creators of Tailwind CSS (Tailwind Labs), so the visual style aligns with the utility framework being used.
  • Inline SVG format — No additional JavaScript library required. Heroicons for Vue (@heroicons/vue) allows using icons as Vue components directly in Blade via Alpine.js or Vue components.
  • Free & open-source — No licensing costs, suitable for a non-profit school project.

Build Tool: Vite 8

Why Vite?

  • Development speed — Vite uses native ES modules for the dev server, providing near-instant hot module replacement (HMR). No need to wait for a full bundle rebuild when changing CSS or JavaScript files.
  • Laravel integrationlaravel-vite-plugin provides one-line integration with Blade: just @vite() in the template, and Vite handles CSS/JS injection automatically.
  • Optimal production builds — Vite uses Rollup for production builds, generating automatically minified and tree-shaken bundles.

Database: MySQL 8.4

Why MySQL?

  • Hosting availability — Almost all hosting providers support MySQL. The school can easily migrate to traditional hosting if needed in the future.
  • Clear data relationships — PSB data has well-defined relationships: applicant → documents, applicant → payments, applicant → status history. MySQL with foreign key constraints ensures referential integrity.
  • Sufficient performance — At the school’s registration scale (hundreds, not millions of applicants), MySQL is more than adequate. No need for additional costs on more exotic databases.

Search: Meilisearch

Why Meilisearch (installed, but not active in production)?

  • Reserved for advanced search features — Meilisearch is installed in the development environment for search feature experimentation. However, in production, MySQL full-text search is currently sufficient for applicant data lookup.
  • Typo tolerance — If applicant data grows to thousands in the future, Meilisearch can be activated to provide a typo-tolerant search experience, useful when admins search for applicants by name that might be misspelled.

Deployment: Wasmer Edge

Why Wasmer instead of VPS/Railway/Heroku?

  • Minimal cost — Wasmer Edge offers a free tier sufficient for demo/small-scale applications. A private school with limited IT budget benefits greatly.
  • Simple configuration — Just a single app.yaml file to define the application, without needing to manage Nginx, supervisor, or systemd. The platform handles routing, SSL, and scaling automatically.
  • Edge computing — The application is deployed as a WebAssembly module, providing low latency by executing on the edge node closest to users (Malang and surrounding areas).
  • Persistent storage — A persistent volume for uploaded files ensures documents and payment proofs are not lost when the application is restarted.

Note: The deployment is currently running in demo mode (APP_IS_DEMO=true) with debug still enabled for development. For actual production, debug will be disabled and the environment adjusted accordingly.

Container: Podman + Docker Compose

Why Podman?

  • Rootless — Podman runs without a root daemon, making it more secure for development on the developer’s workstation. No need to grant root access to the container engine.
  • Docker Compose compatibility — Podman can run Docker Compose files without modification. The existing compose.yaml file works as-is without changes.

Cache & Queue: Database (MySQL)

Why the database as cache/queue (instead of Redis/SQS)?

  • Operational simplicity — At this application’s scale, adding Redis as a separate service only adds operational complexity without significant benefit. MySQL is sufficient for email notification queues and simple query caching.
  • No additional infrastructure — No need to run a Redis container, manage Redis persistent storage, or worry about cache data loss on restart. Everything is stored in the existing database.
  • Scalability as needed — If traffic increases, migration to Redis can be done by changing a single line of configuration (QUEUE_CONNECTION=redis). Laravel’s queue abstraction makes this transparent.

Application Architecture

┌────────────────────────────────────────────────────┐
│                     Wasmer Edge                     │
│  ┌──────────────────────────────────────────────┐   │
│  │           PHP-FPM + Nginx (Laravel)          │   │
│  │  ┌─────────┐ ┌──────────┐ ┌──────────────┐   │   │
│  │  │ Public  │ │  Admin   │ │  Storage     │   │   │
│  │  │ Routes  │ │  Routes  │ │  Controller  │   │   │
│  │  └────┬────┘ └────┬─────┘ └──────┬───────┘   │   │
│  │       │           │              │           │   │
│  │  ┌────▼───────────▼──────────────▼───────┐   │   │
│  │  │         Laravel Controllers           │   │   │
│  │  └────────────────┬──────────────────────┘   │   │
│  │                   │                          │   │
│  │  ┌────────────────▼──────────────────────┐   │   │
│  │  │       Registration Service            │   │   │
│  │  │       + Domain Models                 │   │   │
│  │  └────────────────┬──────────────────────┘   │   │
│  └───────────────────┬──────────────────────────┘   │
│                      │                              │
│  ┌───────────────────▼──────────────────────────┐   │
│  │              MySQL 8.4 Database              │   │
│  │  (candidates, documents, payments, fees,     │   │
│  │   registration_periods, announcements,       │   │
│  │   admins, status_history)                    │   │
│  └──────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────┐   │
│  │       Persistent Volume (storage/)           │   │
│  │  (photos, documents, payment proofs,         │   │
│  └──────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────┘

Registration Flow

  1. Parent opens the registration page
  2. Fills in the applicant’s data + parent/guardian information
  3. Uploads documents (photo, family card, birth certificate)
  4. System generates a unique registration number
  5. Parent pays the registration fee
  6. Uploads transfer proof via the payment upload page
  7. Admin verifies documents & payment
  8. Applicant status changes: Registered → Verified → Active (or Rejected)
  9. Parent can check the status anytime via the tracking page

Summary

PSB-RQ is a web application built on the principle of the right tool for the right job. Laravel was chosen for its mature ecosystem suited for multi-status CRUD applications. Blade + Tailwind were chosen for simplicity — no JavaScript framework needed for an application that is largely server-rendered. MySQL was chosen for hosting compatibility and operational simplicity. Wasmer was chosen for low cost and ease of deployment.

These technical decisions enable a single developer to build a secure, fast, and manageable production application — without burdening the school with high infrastructure costs or unnecessary complexity.

Demo

Home page : https://demo-raudhatulquran.wasmer.app/
Admin Panel : https://demo-raudhatulquran.wasmer.app/admin/login

Admin Login Credential

email : demo@raudhatulquran.com
password : 11111111