Skip to content

developer-evan/subscription-tracker-api

Repository files navigation

Subscription Tracker API

A comprehensive RESTful API for managing users and subscriptions with JWT authentication, subscription tracking, and renewal reminders.

Quick Start

Prerequisites

  • Node.js 18+
  • npm or yarn

Installation

# Install dependencies
npm install

# Start development server
npm run start:dev

# API will be available at http://localhost:3000/api/v1

Run Tests

# Run the comprehensive test suite (all 15 endpoints tested)
./test-api.sh

# Output: ✓ All 15 tests passed!

Features

  • ✅ 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

API Endpoints Summary

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)

Project Structure

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

Available Scripts

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 Prettier

Environment Variables

Create a .env file (optional - defaults provided):

PORT=3000
JWT_SECRET=your-secret-key-change-in-production
NODE_ENV=development

Database

The 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:dev

Authentication

All protected endpoints require a JWT token in the Authorization header:

curl -H "Authorization: Bearer <access_token>" \
  http://localhost:3000/api/v1/subscriptions

Tokens expire in 24 hours. Get a new token by signing in again.

Example Usage

1. Sign Up a User

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..."
}

2. Create a Subscription

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"
  }'

3. Get User Subscriptions

curl http://localhost:3000/api/v1/subscriptions/user/2ce68102-af6c-41a4-8fdd-e833b752158f

4. Get Upcoming Renewals (Next 30 Days)

curl "http://localhost:3000/api/v1/subscriptions/upcoming-renewals?days=30"

5. Cancel a Subscription

curl -X PUT http://localhost:3000/api/v1/subscriptions/<sub_id>/cancel \
  -H "Authorization: Bearer <access_token>"

Error Handling

The API returns helpful error messages with appropriate HTTP status codes:

{
  "statusCode": 409,
  "message": "Email already exists",
  "error": "Conflict"
}

Common HTTP Status Codes:

  • 200: OK
  • 201: Created
  • 400: Bad Request (validation error)
  • 401: Unauthorized (missing/invalid token)
  • 403: Forbidden (access denied)
  • 404: Not Found
  • 409: Conflict (duplicate email)
  • 500: Internal Server Error

Validation Rules

User Sign Up/Create

  • Email: Must be valid format and unique
  • Password: Minimum 6 characters
  • FirstName: Required string
  • LastName: Required string

Subscription Create

  • Name: Required string
  • Cost: Required positive number
  • StartDate: Required valid date (YYYY-MM-DD)
  • RenewalDate: Required, must be after startDate
  • Description: Optional string

Testing

Comprehensive test suite covering all 15 endpoints:

./test-api.sh

Test 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.

Database Models

User

  • id: UUID (Primary Key)
  • email: String (Unique)
  • password: String (Hashed)
  • firstName: String
  • lastName: String
  • createdAt: DateTime
  • updatedAt: DateTime
  • Relationship: One-to-Many with Subscriptions

Subscription

  • id: UUID (Primary Key)
  • name: String
  • description: String (Optional)
  • cost: Decimal (10,2)
  • startDate: DateTime
  • renewalDate: DateTime
  • status: Enum (active, cancelled, expired)
  • cancelledAt: DateTime (Optional)
  • userId: UUID (Foreign Key)
  • createdAt: DateTime
  • updatedAt: DateTime
  • Relationship: Many-to-One with User

Troubleshooting

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

Performance Notes

  • 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

Security

  • ✅ Passwords hashed with bcryptjs
  • ✅ JWT tokens with 24-hour expiration
  • ✅ Input validation on all endpoints
  • ✅ SQL injection protection via TypeORM
  • ✅ Parameter validation and sanitation

Production Checklist

  • 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

For Detailed Documentation

See API_DOCUMENTATION.md for:

  • Detailed endpoint documentation
  • Request/response examples
  • All query parameters
  • Error scenarios
  • Data models reference

License

UNLICENSED

Support

For issues or examples, check the test suite:

cat test-api.sh

For detailed API docs:

cat API_DOCUMENTATION.md

About

NestJS subscription apis

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors