GitHub - Gemu03/eventflow-api: EventFlow — production-grade REST API for events & ticket sales. NestJS + Prisma + PostgreSQL + Redis, JWT/RBAC auth, oversell-safe concurrency, rate limiting, Swagger, CI/CD, deployed on Google Cloud Run. · GitHub
Skip to content

Gemu03/eventflow-api

Repository files navigation

EventFlow API

CI Node NestJS Prisma PostgreSQL Redis Docker License

EventFlow is a production-grade REST API for event management and ticket sales, built with NestJS, Prisma, PostgreSQL, and Redis. Organizers (role ADMIN) create events with multiple ticket types, and users (role USER) buy tickets. Stock is handled safely under concurrency — even when several people try to buy the last ticket at the same time.

⚠️ This is an independent portfolio project. Despite its event-ticketing domain, it is not affiliated with, endorsed by, or connected to Ticketmaster or any third-party ticketing service. It does not call any external ticketing API — it is a self-contained backend.

Keywords: NestJS, TypeScript, REST API, Prisma, PostgreSQL, Redis, JWT auth, RBAC, concurrency control, rate limiting, Swagger/OpenAPI, Docker, Google Cloud Run, CI/CD.

🌐 Live Demo

Direct Cloud Run URL (same service):

Deployed on Google Cloud Run (API + Redis sidecar) with Cloud SQL (PostgreSQL). See deploy/README.md.

Table of Contents

Stack

  • NestJS (TypeScript) with a modular architecture
  • PostgreSQL + Prisma as ORM and migrations
  • Redis for listing cache and distributed rate limiting
  • JWT + Passport for authentication and role-based access control
  • Swagger for interactive API documentation
  • Jest + Supertest for unit and e2e tests
  • Docker / Podman for infrastructure and deployment

Architecture

flowchart LR
    Client[Client / Postman] -->|HTTP + JWT| API

    subgraph API[NestJS API]
        Auth[Auth + Guards]
        Events[Events]
        Orders[Orders]
        Health[Health]
    end

    API -->|Prisma| PG[(PostgreSQL)]
    API -->|cache + rate limit| Redis[(Redis)]
Loading

Every request passes through a logging interceptor and the ThrottlerGuard (rate limiting). Protected routes validate the JWT with JwtAuthGuard and, when applicable, the role with RolesGuard.

Data Model

erDiagram
    User ||--o{ Event : organizes
    User ||--o{ Order : places
    Event ||--o{ TicketType : has
    TicketType ||--o{ Ticket : issues
    Order ||--o{ Ticket : contains
Loading
Entity Key fields
User email, password (hash), name, role (USER/ADMIN)
Event title, description, venue, startsAt, published
TicketType name, priceCents, capacity, available
Order status (PENDING/PAID/CANCELLED), totalCents
Ticket code (unique)

Prices are stored in cents (integers) to avoid floating-point errors.

Getting Started

Requires Node 20+ and Podman (or Docker).

# 1. install dependencies
npm install

# 2. copy environment variables and adjust if needed
cp .env.example .env

# 3. start postgres and redis
podman compose up -d        # or: docker compose up -d

# 4. apply migrations and generate the prisma client
npm run prisma:deploy
npm run prisma:generate

# 5. (optional) load sample data
npm run prisma:seed

# 6. start the API
npm run start:dev

The API runs at http://localhost:3000/api, interactive docs at http://localhost:3000/docs, and the health check at http://localhost:3000/api/health.

To bring up the entire stack (including the API in a container):

podman compose --profile full up -d --build

Try it with Postman

Import docs/ticketmaster-api.postman_collection.json. The Login request stores the token automatically; the create-event requests store eventId and ticketTypeId to chain the purchase flow.

Sample accounts (after seeding)

Role Email Password
Admin admin@ticketmaster.test admin1234
User user@ticketmaster.test user1234

Endpoints

Method Route Access Description
POST /api/auth/register public Create account and return a token
POST /api/auth/login public Sign in
GET /api/users/me authenticated Current user profile
GET /api/events public List events (paginated + search)
GET /api/events/:id public Event detail
POST /api/events admin Create an event
PATCH /api/events/:id admin Edit/publish an event
DELETE /api/events/:id admin Delete an event
POST /api/orders authenticated Purchase tickets
GET /api/orders authenticated List own orders (paginated)
GET /api/orders/:id authenticated Own order detail
GET /api/health public API, database, and Redis status

Design Decisions

Purchase concurrency

The critical case is two users trying to buy the last ticket at the same time. The purchase runs inside a transaction that locks the ticket-type row with SELECT ... FOR UPDATE. The second transaction waits for the first to finish and then sees the already-updated stock, preventing oversell. If no stock remains, it returns 409 Conflict. An e2e test verifies this by firing two simultaneous purchases of the single available ticket.

Rate limiting

A global request limit per time window (configurable via THROTTLE_TTL and THROTTLE_LIMIT) backed by Redis, so it stays consistent even with multiple API instances.

Cache

Listings of published events are cached in Redis for 30 seconds and invalidated when an event is created, edited, or deleted.

Tests

npm test            # unit tests
npm run test:cov    # with coverage
npm run test:e2e    # end-to-end tests (requires infra up)

Tests cover oversell prevention, password hashing, login, the roles guard, date validation, and the full flow against real PostgreSQL and Redis.

License

This project is licensed under the MIT License — see the LICENSE file for details.

About

EventFlow — production-grade REST API for events & ticket sales. NestJS + Prisma + PostgreSQL + Redis, JWT/RBAC auth, oversell-safe concurrency, rate limiting, Swagger, CI/CD, deployed on Google Cloud Run.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors