Because even a URL deserves privacy.
LinkGate is a multi-role, access-controlled URL shortener built with NestJS, Prisma, and PostgreSQL.
It supports public, private, and group-scoped links with fine-grained authorization enforced at the data layer.
LinkGate is built as a learning-driven backend project, focusing on:
- real authorization problems
- correct data modeling
- type safety without over-engineering
- pragmatic NestJS + Prisma usage
- Not a toy CRUD. Not a tutorial clone.
- 🔗 URL shortening with collision-safe identifiers
- 🔐 Access control per URL:
PUBLIC– accessible by anyonePRIVATE– accessible only by the ownerGROUP– accessible by members of a specific group
- 👥 Group system with roles and membership status
- Owner / Admin / Member
- Pending / Accepted / Rejected membership
- 🧠 Authorization enforced via Prisma queries (not post-filters)
- 📦 Clean service-oriented architecture (NestJS)
- 🗄️ PostgreSQL with Prisma ORM
- ✅ DTO validation using
class-validator
- Backend: NestJS (TypeScript)
- ORM: Prisma
- Database: PostgreSQL
- Validation: class-validator
- Auth (planned): JWT
- Runtime: Node.js
src/
├── prisma/ # PrismaService, database access
├── user/ # User module
├── group/ # Group & membership logic
├── url/ # URL shortening & access control
├── utils/ # Shared utilities (hashing, ID generation)
└── generated/ # Prisma generated clientKey design decisions:
- Authorization logic is pushed into Prisma queries
- Services return explicitly shaped data, not raw models
- No global “god” services; dependencies are explicit
- User
- Group
- GroupMembers
- role:
OWNER | ADMIN | MEMBER - status:
PENDING | ACCEPTED | REJECTED
- role:
- Url
- access:
PUBLIC | PRIVATE | GROUP - ownerId
- optional groupId
- access:
Prerequisites
- Node.js ≥ 18
- PostgreSQL
- npm / pnpm / yarn
Install dependencies
npm installEnvironment variables
Create a .env file:
DATABASE_URL=postgresql://user:password@localhost:5432/linkgateDatabase setup
npx prisma migrate dev
npx prisma generateRun the app
npm run start:dev