August 18, 2026
Kos Management App.
Backend ยท FrontendA boarding-house (kos) management system built as a Laravel 13 REST API with a decoupled React SPA โ multi-building, billing, tenants, and role-based access.

Description
Kos Management App (KosApp) is a boarding-house management system for owners and managers who run one or more kos (boarding houses). It is built as a Laravel 13 JSON REST API with a fully decoupled React single-page application, giving a clean separation between backend and frontend. From a single dashboard it manages buildings, rooms, tenants, billing, facilities, and staff โ with role-based access control and self-service booking for prospective tenants.
Background
The project is a from-scratch rebuild of an older Laravel 12 + Inertia (MUI) application. The database concept was kept, but the architecture was re-designed into a fully REST-based backend with a separate React SPA. The rebuild modernizes the stack, removes the tight coupling of the Inertia monolith, and adds first-class multi-building (multi-tenant) support so several properties can be operated from one system.
Goal
Give kos owners and managers one place to run their properties end to end: track rooms and their availability, manage tenants and their room history, issue invoices and record payments, and administer facilities, vehicles, and staff. Access is governed by a custom role/permission system, and prospective tenants can register, book a room, or join a waiting list through public self-service links.
Features
- Multi-building management โ operate several kos from one account; the active building is selected per request.
- Rooms โ room catalog, live availability, room history, and tenant-to-room assignment.
- Tenants (clients) โ profiles with identity images, tags and bulk tagging, per-tenant summaries and room history.
- Billing โ invoices with line items, transactions, payment methods, and PDF export.
- Operations โ facilities, add-ons, vehicles, and a configurable to-do list.
- Staff & access โ user management with a custom RBAC (roles and permissions), plus user impersonation.
- Security โ two-factor authentication via authenticator apps (TOTP QR) and WebAuthn credentials.
- Public self-service โ invite-code registration, room booking, waiting list, and a public room-availability view.
- Dashboard & UX โ summary stats, in-app messages, skeleton loading states, and modal/bottom-sheet filters with mobile-friendly toolbars.
Technologies
- Backend: Laravel 13 (PHP 8.3), JSON REST API, Laravel Sanctum (bearer tokens), a custom permission middleware, Intervention Image, Flysystem (S3), and
bacon-qr-code+otphpfor TOTP. - Frontend: React 19, React Router 7, axios, Bootstrap 5 (SCSS), Vite, plus a Markdown editor (
@uiw/react-md-editor+marked) andhtml2pdf.jsfor document export. - Tooling: DDEV for local environments, Laravel Pint, and PHPUnit.
How to Run
# Backend
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate --seed
# Frontend assets
npm install
# Run API + Vite dev server
composer run dev # or: php artisan serve & npm run dev
A DDEV setup is also included (.ddev/) for a containerized local environment. Configure the database and storage (S3/local) in .env before running the migrations.
Technical Decisions
- Fully decoupled REST API + SPA. Replacing the old Inertia monolith with a JSON API and a standalone React app gives a clear contract and lets the frontend evolve independently.
- Token abilities as permissions. A Sanctum login returns a token whose abilities are the user’s permission list (super admin gets
*); a custompermission:<cid>middleware enforces authorization and returns JSON403. - Header-based multi-tenancy. The SPA sends the active building in an
X-Building-Slugheader, resolved by middleware โ retiring the old cookie and/{slug}URL prefix. - Domain rename. The tenant entity was renamed from kos to Building across the database and permission scheme for clarity and consistency.
- Consistent UX patterns. Skeleton placeholders for loading states and modal (desktop) / bottom-sheet (mobile) filters keep every list view predictable.
What I Learned
- Designing a clean REST contract and an RBAC model that maps naturally onto token abilities.
- Implementing header-based multi-tenancy with a building-resolution middleware.
- Migrating a coupled Inertia application to a decoupled SPA without changing the underlying database concept.
- Adding TOTP and WebAuthn two-factor authentication, and handling image uploads with Intervention Image and S3.
Notes
Private repository. The original Laravel 12 application is kept under references/ (gitignored) as a behavior reference during the rebuild, which happens on the develop branch. Screenshots and a live preview will be added later.

Hey! I’m Fanny, the software engineer tending to this digital garden. You can read more about me, or subscribe by email.