Backend API for DiaryGarden application built with NestJS, PostgreSQL, and Prisma, featuring AI-powered emotion analysis for diary entries.
- Framework: NestJS 10
- Database: PostgreSQL with Prisma ORM 4.16.2
- Authentication: JWT (Access + Refresh tokens)
- Password Hashing: bcrypt
- AI Integration: FastAPI emotion analysis server
- Validation: class-validator, class-transformer
- Node.js (v20.16.0 or higher)
- PostgreSQL database
- FastAPI AI server running at
localhost:8000/emotions
- Clone the repository
cd DiaryGarden_BE- Install dependencies
npm install- Configure environment variables
- Copy
.env.exampleto.env - Update
DATABASE_URLwith your PostgreSQL connection string - Update
JWT_SECRETwith a secure random string
- Generate Prisma client
npx prisma generate- Run database migrations
npx prisma migrate dev --name init# Development mode with hot-reload
npm run start:dev
# Production mode
npm run build
npm run start:prodThe API will be available at http://localhost:3000
POST /api/auth/register- Register new user (username, password, displayName)POST /api/auth/login- Login user (username, password)POST /api/auth/verify- Verify JWT tokenGET /api/auth/user- Get current user info (requires auth)POST /api/auth/refresh- Refresh access token
-
POST /api/diaries- Create diary entry (requires auth)- Body:
{ treeId, content } - Automatically analyzes emotions via AI and stores results
- Body:
-
GET /api/diaries/:id- Get single diary entry- Optional authentication
-
GET /api/diaries- Get user's diary entries (requires auth)- Query params:
limit(optional),lastDocId(optional for pagination)
- Query params:
- id, uid, username, password (hashed), displayName, nickname
- Relations: RefreshTokens, Trees, Diaries
- id, userId, token, expiresAt
- Relation: User
- id, userId, name
- Relations: User, Diaries
- Default tree created on user registration
- id, userId, treeId, content, emotionScores (JSON), dominantEmotion, writtenDate
- Relations: User, Tree
The API integrates with an external FastAPI server for emotion analysis:
- Endpoint:
POST localhost:8000/emotions - Request:
{ text: string, title?: string } - Response:
{ emotionScores: Record<string, number>, dominantEmotion: string } - Fallback: Returns neutral emotion if AI service is unavailable
- User registers or logs in
- Server returns
AuthSessionwithtoken(access token) andrefreshToken - Client stores both tokens
- Client includes access token in
Authorization: Bearer <token>header for protected routes - When access token expires, client uses refresh token to get a new access token
All API responses follow this format:
Success:
{
"success": true,
"data": { ... }
}Error:
{
"success": false,
"message": "Error description"
}DATABASE_URL=postgresql://user:password@localhost:5432/diarygarden?schema=public
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_ACCESS_EXPIRATION=15m
JWT_REFRESH_EXPIRATION=7d
AI_SERVICE_URL=http://localhost:8000/emotions
PORT=3000
NODE_ENV=development
CORS_ORIGIN=http://localhost:3000,http://localhost:5000- Set up your PostgreSQL database
- Update
.envfile with your database connection string - Run migrations:
npx prisma migrate dev - Ensure your FastAPI AI server is running
- Start the development server:
npm run start:dev - Test endpoints using your Flutter app or API client
src/
├── auth/ # Authentication module (JWT, guards, strategies)
├── diary/ # Diary CRUD operations
├── ai/ # FastAPI integration for emotion analysis
├── prisma/ # Prisma service (global database access)
├── common/ # Shared filters, interceptors, decorators
├── app.module.ts # Root module
└── main.ts # Application entry point
- Swagger documentation was removed for stability
- Uses classic NestJS module structure (all files in module directory)
- Prisma 4.16.2 used for better stability with NestJS 10
- Tree model implemented in backend with default tree creation on registration
- Cursor-based pagination implemented for diary listing
- Change
JWT_SECRETin production - Set up proper CORS origins
- Configure PostgreSQL connection string
- Ensure AI service is running before creating diaries