A TypeScript backend application implementing AI Chat and Subscription Bundle modules
- Accepts user questions and returns mocked OpenAI responses
- Stores questions, answers, and token usage in the database
- Tracks monthly usage per user (3 free messages per month)
- Auto-resets free quota on the 1st of each month
- Deducts usage from subscription bundles when free quota is exhausted
- Simulates OpenAI API response time delay
- Create subscription bundles (Basic, Pro, Enterprise)
- Monthly or yearly billing cycles
- Auto-renew toggle functionality
- Simulated billing logic with random payment failures
- Cancellation support with usage history preservation
| Tier | Messages | Monthly Price | Yearly Price |
|---|---|---|---|
| Basic | 10 | $9.99 | $99.99 |
| Pro | 100 | $29.99 | $299.99 |
| Enterprise | Unlimited | $99.99 | $999.99 |
src/
├── index.ts # Application entry point
├── shared/
│ ├── config/ # Configuration
│ ├── database/ # Database connection
│ ├── errors/ # Custom error classes
│ └── middleware/ # Express middleware
├── modules/
│ ├── user/
│ │ ├── domain/entities/ # User entity
│ │ ├── repositories/ # User repository
│ │ ├── services/ # User service
│ │ ├── controllers/ # User controller
│ │ └── routes/ # User routes
│ ├── chat/
│ │ ├── domain/entities/ # ChatMessage, MonthlyUsage entities
│ │ ├── repositories/ # Chat repositories
│ │ ├── services/ # Chat service, OpenAI mock
│ │ ├── controllers/ # Chat controller
│ │ └── routes/ # Chat routes
│ └── subscription/
│ ├── domain/
│ │ ├── entities/ # SubscriptionBundle entity
│ │ └── types.ts # Enums and constants
│ ├── repositories/ # Subscription repository
│ ├── services/ # Subscription service
│ ├── controllers/ # Subscription controller
│ └── routes/ # Subscription routes
- Node.js (v18+)
- PostgreSQL database
- npm or yarn
- Clone the repository and install dependencies:
npm install- Copy the example environment file and configure:
cp .env.example .env- Update
.envwith your database credentials:
NODE_ENV=development
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=your_password
DB_NAME=ai_chat_db
OPENAI_RESPONSE_DELAY_MS=1000- Create the PostgreSQL database:
CREATE DATABASE ai_chat_db;- Run the application:
# Development mode
npm run dev
# Production build
npm run build
npm start| Method | Endpoint | Description |
|---|---|---|
| POST | /api/users |
Create a new user |
| GET | /api/users |
Get all users |
| GET | /api/users/:id |
Get user by ID |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/chat/message |
Send a message |
| GET | /api/chat/history/:userId |
Get chat history |
| GET | /api/chat/usage/:userId |
Get usage information |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/subscriptions |
Create subscription |
| GET | /api/subscriptions/:id |
Get subscription by ID |
| GET | /api/subscriptions/user/:userId |
Get user subscriptions |
| PATCH | /api/subscriptions/:id |
Update subscription |
| POST | /api/subscriptions/:id/cancel |
Cancel subscription |
| POST | /api/subscriptions/process-renewals |
Process auto-renewals |
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "name": "John Doe"}'curl -X POST http://localhost:3000/api/chat/message \
-H "Content-Type: application/json" \
-d '{"userId": "user-uuid", "question": "What is the weather today?"}'curl -X POST http://localhost:3000/api/subscriptions \
-H "Content-Type: application/json" \
-d '{"userId": "user-uuid", "tier": "pro", "billingCycle": "monthly", "autoRenew": true}'curl http://localhost:3000/api/chat/usage/user-uuidThe API returns structured errors:
{
"error": {
"code": "FREE_QUOTA_EXCEEDED",
"message": "Free quota exceeded and no active subscription with remaining messages",
"details": {
"freeMessagesUsed": 3,
"freeMessagesLimit": 3,
"suggestion": "Please purchase a subscription bundle to continue using the service"
}
}
}npm run dev- Start development server with hot reloadnpm run build- Build for productionnpm start- Run production buildnpm run lint- Run ESLintnpm run lint:fix- Fix ESLint errorsnpm run format- Format code with Prettiernpm run typecheck- Run TypeScript type checking