A comprehensive RESTful API for managing users and subscriptions with JWT authentication, subscription tracking, and renewal reminders.
- Node.js 18+
- npm or yarn
# Install dependencies
npm install
# Start development server
npm run start:dev
# API will be available at http://localhost:3000/api/v1# Run the comprehensive test suite (all 15 endpoints tested)
./test-api.sh
# Output: ✓ All 15 tests passed!- ✅ User Authentication (Sign Up, Sign In, Sign Out) with JWT
- ✅ Complete User Management (CRUD operations)
- ✅ Subscription Lifecycle Management (Create, Update, Cancel, Delete)
- ✅ Subscription Status Tracking (Active, Cancelled, Expired)
- ✅ Upcoming Renewal Alerts with configurable range
- ✅ Input Validation & Error Handling
- ✅ Password Hashing with bcryptjs
- ✅ SQLite Database with TypeORM
- ✅ Role-based access control with JWT
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /auth/sign-up | Create new user | ❌ |
| POST | /auth/sign-in | Login user | ❌ |
| POST | /auth/sign-out | Logout user | ✅ |
| GET | /users | List all users | ❌ |
| GET | /users/:id | Get user by ID | ❌ |
| POST | /users | Create user | ❌ |
| PUT | /users/:id | Update user | ✅ |
| DELETE | /users/:id | Delete user | ✅ |
| GET | /subscriptions | List all subscriptions | ❌ |
| GET | /subscriptions/:id | Get subscription by ID | ❌ |
| GET | /subscriptions/user/:id | Get user subscriptions | ❌ |
| POST | /subscriptions | Create subscription | ✅ |
| PUT | /subscriptions/:id | Update subscription | ✅ |
| PUT | /subscriptions/:id/cancel | Cancel subscription | ✅ |
| DELETE | /subscriptions/:id | Delete subscription | ✅ |
| GET | /subscriptions/upcoming-renewals | Get upcoming renewals (30 days) | ❌ |
src/
├── auth/ # Authentication module (JWT, Sign Up/In/Out)
├── users/ # User management module (CRUD)
├── subscriptions/ # Subscription management module
├── entities/ # Database entities (User, Subscription)
├── common/ # Shared utilities
└── app.module.ts # Main app module
npm run start # Start production server
npm run start:dev # Start development server with watch mode
npm run build # Build for production
npm run test # Run unit tests
npm run test:watch # Run tests in watch mode
npm run test:e2e # Run e2e tests
npm run lint # Run ESLint
npm run format # Format code with PrettierCreate a .env file (optional - defaults provided):
PORT=3000
JWT_SECRET=your-secret-key-change-in-production
NODE_ENV=developmentThe API uses SQLite for development. The database (subscription-tracker.db) is automatically created on first run.
To reset the database:
rm -f subscription-tracker.db
npm run start:devAll protected endpoints require a JWT token in the Authorization header:
curl -H "Authorization: Bearer <access_token>" \
http://localhost:3000/api/v1/subscriptionsTokens expire in 24 hours. Get a new token by signing in again.
curl -X POST http://localhost:3000/api/v1/auth/sign-up \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe"
}'Response:
{
"id": "2ce68102-af6c-41a4-8fdd-e833b752158f",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}curl -X POST http://localhost:3000/api/v1/subscriptions \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Netflix",
"description": "Streaming service",
"cost": 15.99,
"startDate": "2026-01-01",
"renewalDate": "2026-05-22"
}'curl http://localhost:3000/api/v1/subscriptions/user/2ce68102-af6c-41a4-8fdd-e833b752158fcurl "http://localhost:3000/api/v1/subscriptions/upcoming-renewals?days=30"curl -X PUT http://localhost:3000/api/v1/subscriptions/<sub_id>/cancel \
-H "Authorization: Bearer <access_token>"The API returns helpful error messages with appropriate HTTP status codes:
{
"statusCode": 409,
"message": "Email already exists",
"error": "Conflict"
}Common HTTP Status Codes:
200: OK201: Created400: Bad Request (validation error)401: Unauthorized (missing/invalid token)403: Forbidden (access denied)404: Not Found409: Conflict (duplicate email)500: Internal Server Error
- Email: Must be valid format and unique
- Password: Minimum 6 characters
- FirstName: Required string
- LastName: Required string
- Name: Required string
- Cost: Required positive number
- StartDate: Required valid date (YYYY-MM-DD)
- RenewalDate: Required, must be after startDate
- Description: Optional string
Comprehensive test suite covering all 15 endpoints:
./test-api.shTest Coverage:
- ✓ User Authentication (Sign Up, Sign In, Sign Out)
- ✓ User Management (CRUD operations)
- ✓ Subscription Management (CRUD + Cancel)
- ✓ Subscription Filtering (By User, Upcoming Renewals)
- ✓ Authorization Checks
- ✓ Input Validation
All tests pass with correct HTTP status codes and response formats.
id: UUID (Primary Key)email: String (Unique)password: String (Hashed)firstName: StringlastName: StringcreatedAt: DateTimeupdatedAt: DateTime- Relationship: One-to-Many with Subscriptions
id: UUID (Primary Key)name: Stringdescription: String (Optional)cost: Decimal (10,2)startDate: DateTimerenewalDate: DateTimestatus: Enum (active, cancelled, expired)cancelledAt: DateTime (Optional)userId: UUID (Foreign Key)createdAt: DateTimeupdatedAt: DateTime- Relationship: Many-to-One with User
| Issue | Solution |
|---|---|
| Port already in use | PORT=3001 npm run start:dev |
| Database read-only | rm -f subscription-tracker.db && npm run start:dev |
| Token expired | Sign in again with /auth/sign-in |
| Connection refused | Ensure server is running: npm run start:dev |
| Validation errors | Check request body against requirements |
- Passwords are hashed with bcryptjs (10 salt rounds)
- Database queries optimized with proper relationships
- JWT tokens use HS256 algorithm
- All requests validated with class-validator
- SQLite suitable for development; use PostgreSQL for production
- ✅ Passwords hashed with bcryptjs
- ✅ JWT tokens with 24-hour expiration
- ✅ Input validation on all endpoints
- ✅ SQL injection protection via TypeORM
- ✅ Parameter validation and sanitation
- Change JWT_SECRET environment variable
- Use PostgreSQL instead of SQLite
- Enable HTTPS/SSL
- Add rate limiting middleware
- Configure CORS properly
- Set up logging and monitoring
- Use process manager (PM2)
- Set NODE_ENV=production
- Enable database backups
See API_DOCUMENTATION.md for:
- Detailed endpoint documentation
- Request/response examples
- All query parameters
- Error scenarios
- Data models reference
UNLICENSED
For issues or examples, check the test suite:
cat test-api.shFor detailed API docs:
cat API_DOCUMENTATION.md