2026 · Lead Developer

Sakena

A residential-complex management platform for residents, managers, and service staff — a DDD/Clean Architecture Kotlin backend behind a Next.js frontend, covering units, service requests, tasks, payments, and announcements.

Next.jsKotlinSpring BootPostgreSQLDockerGrafanaLoki

Sakena screenshots

1 / 41

Overview

Sakena is a management platform for residential complexes, built as a team project for Sharif's Analysis and Software Design course. The premise is ordinary — apartment buildings need someone to log a leak, a manager needs to know which units still owe this month's shared costs, a resident wants to know whether the elevator repair got scheduled — but the system underneath had to hold up three different users with three different jobs against the same data.

Architecture as the actual deliverable

Where most course projects optimize for finishing features, this one treated the architecture itself as the graded artifact. The Kotlin backend is organized by bounded context first, then by layer inside each: domain, application, and infrastructure, with a dependency rule that only points inward — the domain layer cannot import Spring, JPA, or Jackson, full stop. Business rules live on the aggregate itself, enforced at construction and through behavior methods, rather than scattered across services that merely orchestrate. A small task module ships as the deliberate reference implementation: new bounded contexts are expected to copy its shape rather than invent a new one, which is what let four people add units, service requests, payments, announcements, chat, and more without the codebase drifting into four different styles.

Three roles, one API

Residents, building managers, and service staff all work through the same backend with role-scoped permissions rather than separate apps. A manager manages buildings and units, publishes announcements, and reviews payment history; a resident files service requests and reads what the manager posted; a service worker picks up tasks, reports on completed work with cost and notes attached, and can look back at everything they have finished. That shared surface is also why the auth layer got early, deliberate attention — role has to come from the backend's own record of who a user is, never from a client-side selection, or the three-roles model collapses into "whatever the frontend claims."

Frontend

The client is a Next.js app on the same stack I use across these projects — TanStack Query for server state, Zustand for what is genuinely client state, Zod schemas driving React Hook Form — because keeping that boundary consistent is what makes a fast-moving four-person frontend stay readable instead of accumulating four ad hoc patterns for the same problem.

What is deliberately not built

Not every backend endpoint has a UI, and that gap is documented rather than hidden: a generic task CRUD module exists only as the architecture's reference implementation, not a product feature, so the Tasks screen is wired to service requests instead. Treating "no UI for this" as a tracked, intentional decision — not an oversight to quietly leave unfinished — kept the team's actual scope legible as the project grew.