March 2026 · Auth & payments backend · detective board & rewards frontend (team of 3)

L.A. Noire

A noir-styled investigation platform — cases, evidence, complaints, crime scenes, and a React Flow detective board — with RBAC enforced across the React client and the Django API.

ReactReact FlowDjangoPostgreSQLDockerVite

L.A. Noire screenshots

1 / 21

Overview

L.A. Noire is a full-stack investigation platform 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 was production architecture for a real domain: cases, evidence, complaints, crime scenes, witness testimony, tip rewards, and a visual detective board.

Built as a team of three. My share was auth and payment on the Django side, and on the React side the payment flow, detective board, high-priority wanted suspects, reward claim UI, plus frontend tests.

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 (@xyflow/react) drives the detective board, where relationships between cases, evidence, and suspects are explored as a graph rather than 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.