A fullstack application with a landing page and authentication, built with React + Redux (frontend) and NestJS + PostgreSQL (backend).
Frontend: React 18, TypeScript, Redux Toolkit, React Router v6, React Hook Form + Zod, Axios, CSS Modules Backend: NestJS, TypeScript, TypeORM, PostgreSQL, Passport JWT, bcrypt, Helmet, Throttler
test-task/
├── frontend/ # React + Vite
├── backend/ # NestJS
└── docker-compose.yml # PostgreSQL
docker-compose up -dcd backend
cp .env.example .env # edit if needed
npm install
npm run start:devBackend runs on http://localhost:3001
cd frontend
cp .env.example .env # edit if needed
npm install
npm run devFrontend runs on http://localhost:5173
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/auth/register | No | Register new user |
| POST | /api/auth/login | No | Login, returns JWT |
| GET | /api/deals | No | List open deals |
| GET | /api/deals/:id | No | Single deal |
| POST | /api/applications | No | Submit an application |
| GET | /api/applications | No | List all applications |
- Landing page with hero section and "Open Deals" grid
- Login / Register pages with form validation (Zod + React Hook Form)
- JWT authentication — token stored in
localStorage - Conditional header — shows Log In / Sign Up when logged out, Sign Out when logged in (driven by Redux state)
- Deals seeded automatically on first run from PostgreSQL
- Applications API — open endpoint to accept and persist form submissions
- Mobile responsive — hamburger menu on small screens, fluid layouts
- Rate limiting on auth endpoints (5 req/min)
- Input validation on all DTOs (class-validator)
- Password hashing with bcrypt (10 rounds)
| Variable | Default | Description |
|---|---|---|
| DATABASE_HOST | localhost | Postgres host |
| DATABASE_PORT | 5432 | Postgres port |
| DATABASE_USER | postgres | Postgres user |
| DATABASE_PASSWORD | postgres | Postgres password |
| DATABASE_NAME | realestate_db | Database name |
| JWT_SECRET | — | JWT signing secret |
| JWT_EXPIRES_IN | 7d | Token lifetime |
| PORT | 3001 | Server port |
| FRONTEND_URL | http://localhost:5173 | CORS allowed origin |
| Variable | Default | Description |
|---|---|---|
| VITE_API_URL | http://localhost:3001/api | Backend URL |