SubTrack is a full-stack subscription management platform built with modern web technologies. The project consists of a robust Node.js/Express API backend and a responsive React/TypeScript frontend, designed for independent deployment and scalability.
- Authentication: JWT-based auth with access & refresh tokens
- RBAC: Role-Based Access Control with 6 distinct roles (SUPER_ADMIN, ADMIN, MANAGER, USER, READ_ONLY, SERVICE)
- Subscription Management: Full CRUD operations for subscription tracking
- Audit Logging: Append-only security logging for all critical actions
- Security: Arcjet integration for rate limiting and abuse protection
- RESTful API: Clean, consistent API design with comprehensive error handling
- Modern Stack: Vite + React 18 + TypeScript + Tailwind CSS
- UI Components: Shadcn/UI component library with Radix UI primitives
- State Management: TanStack Query for server state, React Hook Form for forms
- Authentication: Protected routes with automatic token refresh
- Responsive Design: Mobile-first design with smooth animations (Framer Motion)
- Developer Experience: Hot reload, TypeScript support, ESLint configuration
- Independent Deployment: Separate backend and frontend projects for flexible scaling
- Environment Configuration: Comprehensive environment variable management
- Cross-Origin Support: CORS configuration for separate domain deployment
- Development Workflow: Independent development servers with proxy configuration
- Runtime: Node.js 18+ (ESM modules)
- Framework: Express.js
- Database: MongoDB with Mongoose ODM
- Authentication: JWT with refresh token rotation
- Security: Arcjet, bcryptjs, CORS
- Development: Nodemon, ESLint
- Build Tool: Vite
- Framework: React 18 with TypeScript
- Styling: Tailwind CSS
- UI Library: Shadcn/UI + Radix UI
- HTTP Client: Axios with interceptors
- State Management: TanStack Query (React Query)
- Forms: React Hook Form with Zod validation
- Animation: Framer Motion
- Development: ESLint, PostCSS
This project uses a monorepo structure with independent backend and frontend applications:
subscription-management-app/
โโโ backend/ # Express.js API Server
โ โโโ app.js # Main application entry point
โ โโโ package.json # Backend dependencies & scripts
โ โโโ .env.development.local # Backend environment variables
โ โโโ config/
โ โ โโโ env.js # Environment configuration
โ โโโ constants/ # Application constants
โ โโโ controllers/ # Route controllers
โ โ โโโ auth.controller.js # Authentication logic
โ โ โโโ subscription.controller.js
โ โ โโโ user.controller.js
โ โโโ database/
โ โ โโโ mongodb.js # Database connection
โ โโโ middleware/ # Custom middleware
โ โ โโโ auth.middleware.js # JWT authentication
โ โ โโโ error.middleware.js # Error handling
โ โ โโโ rbac.middleware.js # Role-based access control
โ โโโ models/ # Mongoose schemas
โ โ โโโ subscription.model.js
โ โ โโโ user.model.js
โ โ โโโ auditLog.model.js
โ โโโ routes/ # API routes
โ โ โโโ auth.routes.js
โ โ โโโ subscription.routes.js
โ โ โโโ user.routes.js
โ โโโ scripts/ # Utility scripts
โ โโโ utils/ # Helper functions
โโโ frontend/ # React Application
โ โโโ index.html # HTML entry point
โ โโโ package.json # Frontend dependencies & scripts
โ โโโ .env.development.local # Frontend environment variables
โ โโโ vite.config.ts # Vite configuration
โ โโโ tailwind.config.ts # Tailwind CSS configuration
โ โโโ components.json # Shadcn/UI configuration
โ โโโ src/
โ โ โโโ main.tsx # React entry point
โ โ โโโ App.tsx # Main app component
โ โ โโโ components/ # Reusable UI components
โ โ โโโ pages/ # Page components
โ โ โโโ lib/ # Utilities & API client
โ โ โโโ hooks/ # Custom React hooks
โ โ โโโ store/ # State management
โ โ โโโ types/ # TypeScript type definitions
โ โโโ public/ # Static assets
โโโ api/ # Vercel serverless functions
โโโ package.json # Root package.json (development scripts)
โโโ vercel.json # Vercel deployment configuration
โโโ README.md # This file
- Node.js v18 or higher
- MongoDB (Atlas or local instance)
- Git for version control
git clone https://github.com/AbhiramVSA/subscription-management-app.git
cd subscription-management-appNavigate to the backend directory and install dependencies:
cd backend
npm installCreate environment configuration file:
# Create backend/.env.development.local
PORT=8001
NODE_ENV=development
DB_URI=mongodb+srv://username:password@cluster.mongodb.net/subtrack
JWT_SECRET=your_super_secure_jwt_secret_key_here
JWT_EXPIRES_IN=15m
JWT_REFRESH_SECRET=your_super_secure_refresh_secret_key_here
JWT_REFRESH_EXPIRES_IN=604800000
ARCJET_KEY=your_arcjet_api_key_here
ALLOWED_ORIGINS=http://localhost:8080,http://localhost:5173Start the backend development server:
npm run devโ
Backend API available at: http://localhost:8001
Open a new terminal and navigate to the frontend directory:
cd frontend
npm installCreate frontend environment configuration:
# Create frontend/.env.development.local
ENV_BASE_URL=http://localhost:8001Start the frontend development server:
npm run devโ
Frontend application available at: http://localhost:8080
Both applications can be run independently:
- Backend only:
cd backend && npm run dev - Frontend only:
cd frontend && npm run dev - Both from root:
npm run dev(uses concurrently)
The frontend is configured to proxy API requests to the backend during development.
POST /api/v1/auth/sign-inโ User loginPOST /api/v1/auth/sign-upโ User registrationPOST /api/v1/auth/refreshโ Refresh access tokenPOST /api/v1/auth/sign-outโ Sign out (invalidate refresh token)POST /api/v1/auth/sign-out-allโ Sign out from all devices (requires auth)
GET /api/v1/user/usersโ Get all users (SUPER_ADMIN | ADMIN)GET /api/v1/user/:idโ Get user by ID (authenticated)PATCH /api/v1/user/:userId/roleโ Change a user's role (SUPER_ADMIN | ADMIN, with elevation guard)
GET /api/v1/subscriptions/โ List all subscriptions (SUPER_ADMIN | ADMIN | MANAGER)GET /api/v1/subscriptions/:idโ Get subscription details (owner or elevated)POST /api/v1/subscriptions/โ Create a subscription (authenticated)PUT /api/v1/subscriptions/:idโ Update a subscription (owner or elevated)DELETE /api/v1/subscriptions/:idโ Delete a subscription (owner or ADMIN | SUPER_ADMIN)GET /api/v1/subscriptions/user/:idโ Get subscriptions for a user (must match user or elevated)PUT /api/v1/subscriptions/:id/cancelโ Cancel a subscription (owner or elevated)GET /api/v1/subscriptions/upcoming-renewalsโ Get upcoming renewals
PORT=8001 # API server port
NODE_ENV=development # Environment mode
DB_URI=mongodb://... # MongoDB connection string
JWT_SECRET=your_jwt_secret # JWT signing secret
JWT_EXPIRES_IN=15m # Access token expiry
JWT_REFRESH_SECRET=refresh_secret # Refresh token secret
JWT_REFRESH_EXPIRES_IN=604800000 # Refresh token expiry (7 days)
ARCJET_KEY=your_arcjet_key # Arcjet security key
ALLOWED_ORIGINS=http://localhost:8080 # CORS originsENV_BASE_URL=http://localhost:8001 # Backend API URLThe project supports multiple deployment strategies:
- Monorepo Deployment - Deploy both apps together
- Separate Deployment - Deploy backend and frontend independently
- Serverless Deployment - Backend as Vercel functions, frontend as static site
Backend Production:
NODE_ENV=production
DB_URI=mongodb+srv://... # Production MongoDB
ALLOWED_ORIGINS=https://yourdomain.comFrontend Production:
ENV_BASE_URL=https://api.yourdomain.comRenewly implements JWT-based authentication with refresh token support for enhanced security and user experience.
- Sign Up/Sign In: Returns both access token (short-lived) and refresh token (long-lived)
- API Requests: Use access token in Authorization header
- Token Refresh: When access token expires, use refresh token to get new tokens
- Sign Out: Invalidate specific refresh token or all tokens
Environment variables for token management:
JWT_SECRET=your_jwt_secret
JWT_EXPIRES_IN=15m # Access token expiry (15 minutes)
JWT_REFRESH_SECRET=your_refresh_secret
JWT_REFRESH_EXPIRES_IN=604800000 # Refresh token expiry (7 days in ms)# Get new access token using refresh token
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refreshToken": "your_refresh_token_here"
}Response:
{
"success": true,
"message": "Token refreshed successfully",
"data": {
"token": "new_access_token",
"refreshToken": "new_refresh_token",
"user": {
"_id": "user_id",
"name": "User Name",
"email": "user@example.com",
"role": "USER"
}
}
}POST /api/v1/auth/refresh- Refresh access tokenPOST /api/v1/auth/sign-out- Sign out (invalidate refresh token)POST /api/v1/auth/sign-out-all- Sign out from all devices (requires auth)
Defined roles: SUPER_ADMIN, ADMIN, MANAGER, USER, READ_ONLY, SERVICE.
Examples:
- View all users: SUPER_ADMIN | ADMIN
- List all subscriptions: SUPER_ADMIN | ADMIN | MANAGER
- Change user role: SUPER_ADMIN | ADMIN (ADMIN cannot assign SUPER_ADMIN)
- Delete subscription: Owner OR (SUPER_ADMIN | ADMIN)
Helper middleware: requireRoles(...roles) plus ownership checks inside controllers.
Appendโonly collection AuditLog records securityโsensitive actions:
- LOGIN
- CREATE_SUBSCRIPTION / UPDATE_SUBSCRIPTION / DELETE_SUBSCRIPTION / CANCEL_SUBSCRIPTION
- ROLE_CHANGE
Immutable enforcement is done by throwing inside pre-update/delete hooks. Failing to write an audit entry never blocks the primary action (best effort logging).
- JWT auth with role + active user check.
- Arcjet middleware for basic abuse/rate protections.
- Principle of least privilege enforced via route + controller checks.
isActiveflag on users (future: implement deactivation endpoints).
PATCH /api/v1/user/<userId>/role
Authorization: Bearer <ADMIN_OR_SUPER_ADMIN_TOKEN>
Content-Type: application/json
{
"role": "MANAGER"
}
Response:
{
"success": true,
"data": { "_id": "<id>", "role": "MANAGER" }
}
POST /api/v1/subscriptions/
Authorization: Bearer <TOKEN>
Content-Type: application/json
{
"name": "Netflix Premium",
"price": 15.99,
"currency": "USD",
"frequency": "monthly",
"category": "entertainment",
"startDate": "2024-02-01T00:00:00.000Z",
"paymentMethod": "Credit Card"
}
- Advanced Filtering: Pagination and complex subscription filtering
- Audit Dashboard: Query interface for audit logs (admin only)
- Soft Delete: Recoverable deletion with restore workflows
- Notifications: Email/webhook alerts for upcoming renewals
- API Keys: Service account authentication for third-party integrations
- Enhanced RBAC: Rate limiting tiers per role
- Analytics: Subscription spending insights and trends
- Mobile App: React Native companion app
- Backup/Export: Data export functionality
- Multi-tenant: Support for multiple organizations
- โ JWT Authentication with refresh tokens
- โ Role-based access control (6 roles)
- โ Full subscription CRUD operations
- โ Audit logging for security events
- โ Modern React frontend with TypeScript
- โ Independent deployment architecture
- โ Comprehensive error handling
- โ Security middleware integration
npm run dev # Start both backend and frontend
npm run dev:server # Start backend only
npm run dev:client # Start frontend only
npm run build # Build frontend for production
npm run test # Run test suite
npm run cleanup-tokens # Clean expired refresh tokensnpm run dev # Start backend with nodemon
npm start # Start backend in production modenpm run dev # Start development server (port 8080)
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLintWe welcome contributions! Here's how to get started:
- Fork the repository on GitHub
- Clone your fork locally
- Install dependencies for both backend and frontend
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Commit your changes (
git commit -m 'Add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
- TypeScript for type safety (frontend)
- ESM modules throughout the project
- ESLint for code consistency
- Conventional commits for clear history
- Comprehensive error handling
- Security-first approach
- ๐ Bug fixes and performance improvements
- ๐ Documentation enhancements
- ๐งช Test coverage expansion
- ๐จ UI/UX improvements
- ๐ Security enhancements
- ๐ New features from the roadmap
This project is licensed under the MIT License.
If you discover a security vulnerability, please open an issue or contact the maintainers directly.
- Node.js: v18+ (ESM modules required)
- MongoDB: v4.4+ (Atlas recommended)
- Memory: 512MB+ for development
- Storage: 100MB+ for dependencies
- Modern browsers: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- Mobile: iOS Safari 14+, Chrome Mobile 90+
- API Response Time: <200ms average
- Frontend Load Time: <3s first contentful paint
- Bundle Size: <1MB total JavaScript
- Lighthouse Score: 90+ performance rating
Keywords: subscription management, react typescript, express api, nodejs backend, mongodb, jwt authentication, rbac, audit logging, vite, tailwind css, shadcn ui, vercel deployment, modern web development