prisma with psotgresql

This commit is contained in:
2025-11-23 23:53:13 +08:00
parent d88c2057c0
commit 978158353c
25 changed files with 1718 additions and 407 deletions

219
README.md
View File

@@ -1 +1,218 @@
Friendolls. Backend edition.
# Friendolls Server
Backend API for the Friendolls application built with NestJS, Keycloak authentication, and Prisma ORM.
## Tech Stack
- **Framework:** [NestJS](https://nestjs.com/) - Progressive Node.js framework
- **Authentication:** [Keycloak](https://www.keycloak.org/) - OpenID Connect (OIDC) / OAuth 2.0
- **Database ORM:** [Prisma](https://www.prisma.io/) - Next-generation TypeScript ORM
- **Database:** PostgreSQL
- **Language:** TypeScript
- **Package Manager:** pnpm
## Features
- ✅ Keycloak OIDC authentication with JWT tokens
- ✅ User management synchronized from Keycloak
- ✅ PostgreSQL database with Prisma ORM
- ✅ Swagger API documentation
- ✅ Role-based access control
- ✅ Global exception handling
- ✅ Environment-based configuration
- ✅ Comprehensive logging
## Prerequisites
- Node.js 18+
- pnpm
- PostgreSQL 14+ (or Docker)
- Keycloak instance (for authentication)
## Getting Started
### 1. Install Dependencies
```bash
pnpm install
```
### 2. Set Up Environment Variables
Create a `.env` file in the root directory:
```env
# Server Configuration
PORT=3000
NODE_ENV=development
# Database
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/friendolls_dev?schema=public"
# Keycloak OIDC Configuration
JWKS_URI=https://your-keycloak-instance.com/realms/your-realm/protocol/openid-connect/certs
JWT_ISSUER=https://your-keycloak-instance.com/realms/your-realm
JWT_AUDIENCE=your-client-id
```
### 3. Set Up PostgreSQL Database
**Option A: Using Docker (Recommended for development)**
```bash
docker run --name friendolls-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=friendolls_dev \
-p 5432:5432 \
-d postgres:16-alpine
```
**Option B: Use existing PostgreSQL installation**
```bash
createdb friendolls_dev
```
See [docs/PRISMA_SETUP.md](docs/PRISMA_SETUP.md) for detailed database setup instructions.
### 4. Generate Prisma Client and Run Migrations
```bash
# Generate Prisma Client (creates TypeScript types)
pnpm prisma:generate
# Run migrations to create database schema
pnpm prisma:migrate
# If migration already exists, it will say "Already in sync"
```
**Important:** Always run `pnpm prisma:generate` after pulling new code or changing the Prisma schema.
### 5. Start the Development Server
```bash
pnpm start:dev
```
The server will be running at `http://localhost:3000`.
## Available Scripts
### Development
- `pnpm start:dev` - Start development server with hot reload
- `pnpm start:debug` - Start development server with debugging
### Production
- `pnpm build` - Build the application
- `pnpm start:prod` - Start production server
### Database (Prisma)
- `pnpm prisma:generate` - Generate Prisma Client
- `pnpm prisma:migrate` - Create and apply database migration
- `pnpm prisma:migrate:deploy` - Apply migrations in production
- `pnpm prisma:studio` - Open Prisma Studio (visual database browser)
- `pnpm db:push` - Push schema changes (dev only)
- `pnpm db:reset` - Reset database and reapply migrations
### Code Quality
- `pnpm lint` - Lint the code
- `pnpm format` - Format code with Prettier
### Testing
- `pnpm test` - Run unit tests
- `pnpm test:watch` - Run tests in watch mode
- `pnpm test:cov` - Run tests with coverage
- `pnpm test:e2e` - Run end-to-end tests
## API Documentation
Once the server is running, access the Swagger API documentation at:
```
http://localhost:3000/api
```
## Project Structure
```
friendolls-server/
├── prisma/ # Prisma configuration
│ ├── migrations/ # Database migrations
│ └── schema.prisma # Database schema
├── src/
│ ├── auth/ # Authentication module (Keycloak OIDC)
│ ├── common/ # Shared utilities and decorators
│ ├── config/ # Configuration
│ ├── database/ # Database module (Prisma)
│ │ ├── prisma.service.ts
│ │ └── database.module.ts
│ ├── users/ # Users module
│ │ ├── dto/ # Data Transfer Objects
│ │ ├── users.controller.ts
│ │ ├── users.service.ts
│ │ └── users.entity.ts
│ ├── app.module.ts # Root application module
│ └── main.ts # Application entry point
├── test/ # E2E tests
├── .env # Environment variables (gitignored)
├── package.json
└── tsconfig.json
```
## Database Schema
The application uses Prisma with PostgreSQL. The main entity is:
### User Model
- Synchronized from Keycloak OIDC
- Stores user profile information
- Tracks login history
- Manages user roles
## Authentication Flow
1. User authenticates via Keycloak
2. Keycloak issues JWT token
3. Client sends JWT in `Authorization: Bearer <token>` header
4. Server validates JWT against Keycloak's JWKS
5. User is automatically created/synced from token on first login
6. Subsequent requests update user's last login time
## Development Workflow
1. **Make schema changes** in `prisma/schema.prisma`
2. **Create migration**: `pnpm prisma:migrate`
3. **Implement business logic** in services
4. **Create/update DTOs** for request validation
5. **Update controllers** for API endpoints
6. **Test** your changes
7. **Lint and format**: `pnpm lint && pnpm format`
8. **Commit** your changes
## Environment Variables
| Variable | Description | Required | Example |
| -------------- | ---------------------------- | ------------------ | ------------------------------------------------------------------- |
| `PORT` | Server port | No (default: 3000) | `3000` |
| `NODE_ENV` | Environment | No | `development`, `production` |
| `DATABASE_URL` | PostgreSQL connection string | **Yes** | `postgresql://user:pass@host:5432/db` |
| `JWKS_URI` | Keycloak JWKS endpoint | **Yes** | `https://keycloak.com/realms/myrealm/protocol/openid-connect/certs` |
| `JWT_ISSUER` | JWT issuer (Keycloak realm) | **Yes** | `https://keycloak.com/realms/myrealm` |
| `JWT_AUDIENCE` | JWT audience (client ID) | **Yes** | `my-client-id` |
## Production Deployment
1. **Set environment variables** (especially `DATABASE_URL`)
2. **Install dependencies**: `pnpm install --prod`
3. **Generate Prisma Client**: `pnpm prisma:generate`
4. **Run migrations**: `pnpm prisma:migrate:deploy`
5. **Build application**: `pnpm build`
6. **Start server**: `pnpm start:prod`