Overview
L.A. Noire is a full-stack web application built for the Web Programming course at Sharif University of Technology, styled after the Rockstar game it takes its name from. The brief asked for a CRUD application; the goal I set was production architecture.
Access control as a first-class concern
The core design problem was role-based access control. It is easy to hide a button in the UI and call that access control — and just as easy to ship a hole behind it. Here RBAC is enforced in three places that have to agree: route guards on the frontend, conditional rendering of UI actions, and permission checks on every Django REST endpoint.
The important part is the asymmetry in how those three are treated. The frontend checks exist for user experience: they keep people from walking into a door that will not open. The API checks are the actual boundary. A request that bypasses the client entirely still has to satisfy the same policy, because the policy lives on the server and the client only mirrors it.
Frontend
React with Vite, using TanStack Query for server state and Zustand for the client state that genuinely is client state — a distinction worth being strict about, since conflating the two is what turns a state layer into a second, worse cache.
Forms run through React Hook Form with Zod resolvers, so validation rules are declared once as schemas and reused for both the form and the typed API boundary. React Flow drives the graph interactions, where relationships between entities are explored visually rather than through nested tables.
Backend
Django and Django REST Framework over PostgreSQL, with JWT authentication via
PyJWT, django-filter for composable query parameters, and Gunicorn as the
application server. Permissions are attached at the viewset level so a new
endpoint is access-controlled by default rather than by remembering to add a
check.
Delivery
GitHub Actions runs build, test, and deploy on every push. The whole stack is containerized, so the environment that runs in development is the environment that runs in deployment — which removes the class of bug where something works locally and nowhere else.