{"id":28384315,"url":"https://github.com/harishanan/subscription-tracker","last_synced_at":"2026-04-30T20:33:08.697Z","repository":{"id":295697094,"uuid":"990933840","full_name":"Harishanan/Subscription-Tracker","owner":"Harishanan","description":"Backend API for subscription management with email reminders, JWT auth, and Arcjet rate limiting. Built with Node.js, Express, and MongoDB.","archived":false,"fork":false,"pushed_at":"2025-05-26T22:33:38.000Z","size":92,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-30T20:33:02.095Z","etag":null,"topics":["arcjet","email-reminders","express","jwt","mongodb","nodejs","nodemailer","subscription-management","upstash"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Harishanan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T21:49:42.000Z","updated_at":"2025-05-26T22:37:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"f937f78d-1e5f-44d2-b61a-f857324f230d","html_url":"https://github.com/Harishanan/Subscription-Tracker","commit_stats":null,"previous_names":["harishanan/subscription-tracker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Harishanan/Subscription-Tracker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harishanan%2FSubscription-Tracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harishanan%2FSubscription-Tracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harishanan%2FSubscription-Tracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harishanan%2FSubscription-Tracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Harishanan","download_url":"https://codeload.github.com/Harishanan/Subscription-Tracker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Harishanan%2FSubscription-Tracker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32476682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arcjet","email-reminders","express","jwt","mongodb","nodejs","nodemailer","subscription-management","upstash"],"created_at":"2025-05-30T08:10:27.064Z","updated_at":"2026-04-30T20:33:08.691Z","avatar_url":"https://github.com/Harishanan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📧 TrackMySubs – Subscription Tracker API\r\nTrackMySubs is a robust backend service designed to help users manage and track their subscriptions. It provides features like automatic email reminders before subscription renewals, secure user authentication, and seamless integration with MongoDB for data persistence. Built with Node.js, Express, Mongoose, and Upstash Workflows, this API is scalable and developer-friendly.\r\n\r\n\r\n  ## Email Reminder Example\r\nBelow is an example of the email reminder sent to users for their subscription renewals:\r\n![Email Subscription example](assets/email-sub.png)\r\n\r\n\r\n## Features\r\n- **User Authentication**: Secure user registration and login with JWT-based authentication.\r\n- **Subscription Management**: Create, read, update, and delete (CRUD) subscription records.\r\n- **Automatic Email Reminders**: Sends reminders to users before subscription renewals using Upstash Workflows.\r\n- **MongoDB Integration**: Stores user and subscription data efficiently with Mongoose.\r\n- **RESTful API**: Well-structured endpoints for easy integration with frontend applications.\r\n- **Environment Configuration**: Uses environment variables for secure configuration.\r\n\r\n## Technologies Used\r\n- **Node.js**: JavaScript runtime for building the backend. [nodejs.org](https://nodejs.org)\r\n- **Express**: Web framework for creating RESTful APIs. [expressjs.com](https://expressjs.com)\r\n- **MongoDB**: NoSQL database for storing user and subscription data. [mongodb.com](https://www.mongodb.com)\r\n- **Mongoose**: ODM for MongoDB to manage data schemas. [mongoosejs.com](https://mongoosejs.com)\r\n- **Upstash Workflows**: Serverless workflow for scheduling and managing email reminders. [upstash.com](https://upstash.com)\r\n- **Arcjet**: Security platform for rate limiting using the token bucket algorithm. [arcjet.com](https://arcjet.com)\r\n- **JWT**: JSON Web Tokens for secure authentication. [jwt.io](https://jwt.io)\r\n- **Nodemailer**: For sending email reminders. [nodemailer.com](https://nodemailer.com)\r\n- **dayjs**: For date manipulation in workflows. [day.js.org](https://day.js.org)\r\n- **dotenv**: For managing environment variables. [npmjs.com/package/dotenv](https://www.npmjs.com/package/dotenv)\r\n\r\n\r\n\r\n## Technical Details\r\n- **Rate Limiting with Arcjet**: The API uses Arcjet to implement rate limiting, ensuring protection against abuse and denial-of-service attacks. Arcjet employs the **token bucket algorithm**, which allocates a fixed number of tokens to each user or IP address within a time window. Each API request consumes a token, and requests are blocked if the bucket is empty until it refills at a defined rate. This ensures fair usage and maintains API performance under high load.\r\n- **MongoDB Schema Design**: Mongoose schemas are used to enforce data consistency for users (with fields like name, email, and hashed password) and subscriptions (with fields like name, amount, and renewal date).\r\n- **Upstash Workflows for Email Reminders**: Upstash Workflows is used to schedule and manage email reminders for subscription renewals. Each subscription is associated with a workflow that triggers email reminders at 7, 5, 2, and 1 day(s) before the renewal date. The workflow, implemented using the `@upstash/workflow/express` package, leverages the `context.sleepUntil` method to pause execution until the precise date of each reminder. The workflow:\r\n  - Fetches subscription details from MongoDB using Mongoose, including user data (name and email).\r\n  - Checks if the subscription is active and if the renewal date has not passed.\r\n  - Iterates through the reminder intervals (7, 5, 2, 1 day(s)), scheduling each using `context.sleepUntil`.\r\n  - Triggers a Nodemailer task via `sendReminderEmail` to send a notification to the user’s email when the reminder date is reached.\r\n  - Uses `dayjs` for precise date calculations and comparisons.\r\n  This serverless approach ensures scalability, eliminates the need for cron jobs, and supports retries for failed email deliveries to ensure reliable notifications.\r\n\r\n## Getting Started\r\n\r\n### Prerequisites\r\n- Node.js (v16 or higher)\r\n- MongoDB Atlas account or local MongoDB instance\r\n- Upstash account for workflow and email scheduling\r\n- Email service (e.g., Gmail) for Nodemailer\r\n\r\n### Installation\r\n1. **Clone the repository**:\r\n   ```bash\r\n   git clone https://github.com/your-username/trackmysubs-api.git\r\n   cd trackmysubs-api\r\n   ```\r\n\r\n2. **Install dependencies**:\r\n   ```bash\r\n   npm install\r\n   ```\r\n\r\n3. **Set up environment variables**:\r\n   Create a `.env` file in the root directory and add the following:\r\n   ```\r\n   PORT=5000\r\n   MONGO_URI=your_mongodb_connection_string\r\n   JWT_SECRET=your_jwt_secret\r\n   UPSTASH_WORKFLOW_URL=your_upstash_workflow_url\r\n   EMAIL_SERVICE=your_email_service\r\n   EMAIL_USER=your_email_address\r\n   EMAIL_PASS=your_email_password\r\n   ```\r\n\r\n4. **Run the application**:\r\n   ```bash\r\n   npm start\r\n   ```\r\n   The server will start on `http://localhost:5000` (or the port specified in `.env`).\r\n\r\n## API Endpoints\r\n\r\n### Authentication\r\n- `POST /api/v1/auth/sign-up` - Register a new user\r\n- `POST /api/v1/auth/sign-in` - Login a user and return a JWT\r\n- `GET /api/v1/users` - Get all registered users for admin purpose\r\n### Subscriptions\r\n- `GET /api/v1/subscriptions/user/:id` - Get all subscriptions for the authenticated user\r\n- `POST /api/v1/subscriptions` - Create a new subscription\r\n\r\n**Note**: All subscription endpoints require a valid JWT in the `Authorization` header (`Bearer \u003ctoken\u003e`).\r\n\r\n\r\n## Example Usage\r\n### Register a User\r\n```bash\r\ncurl -X POST http://localhost:5000/api/v1/auth/sign-up \\\r\n-H \"Content-Type: application/json\" \\\r\n-d '{\"name\":\"Harishanan Thevarjah\",\"email\":\"harish@example.com\",\"password\":\"securepassword\"}'\r\n```\r\n\r\n### Create a Subscription\r\n```bash\r\ncurl -X POST http://localhost:5000/api/v1/subscriptions \\\r\n-H \"Content-Type: application/json\" \\\r\n-H \"Authorization: Bearer \u003cyour_jwt_token\u003e\" \\\r\n-d '{\"name\": \"Youtube Premimum\", \"price\": 11.00, \"currency\": \"GBP\", \"frequency\": \"monthly\", \"category\": \"entertainment\", \"startDate\": \"2025-05-01T00:00:00.000Z\", \"paymentMethod\": \"Llyods card\"}'\r\n```\r\n\r\n## Project Structure\r\n```\r\ntrackmysubs-api/\r\n├── controllers/      # Request handlers for auth and subscriptions\r\n├── models/           # Mongoose schemas for User and Subscription\r\n├── routes/           # Express routes for API endpoints\r\n├── middleware/       # Authentication and error handling middleware\r\n├── workflows/        # Upstash workflow for email reminders\r\n├── .env              # Environment variables (not tracked)\r\n├── server.js         # Main application entry point\r\n├── package.json      # Project metadata and dependencies\r\n└── README.md         # This file\r\n```\r\n\r\n## Contributing\r\nContributions are welcome! Please follow these steps:\r\n1. Fork the repository.\r\n2. Create a new branch (`git checkout -b feature/your-feature`).\r\n3. Make your changes and commit (`git commit -m \"Add your feature\"`).\r\n4. Push to the branch (`git push origin feature/your-feature`).\r\n5. Open a pull request.\r\n\r\n\r\n## Frequently Asked Questions (FAQ)\r\n1. **What is TrackMySubs, and who is it for?**  \r\n   TrackMySubs is a backend API for managing and tracking user subscriptions, with features like secure authentication, subscription CRUD operations, and automated email reminders. It’s designed for developers building subscription management applications, such as personal finance tools or subscription tracking apps.\r\n\r\n2. **How do I authenticate requests to the API?**  \r\n   All subscription-related endpoints require a JWT token. Register or log in via `/api/v1/auth/sign-up` or `/api/v1/auth/sign-in` to obtain a token, then include it in the `Authorization` header as `Bearer \u003ctoken\u003e` for protected routes.\r\n\r\n3. **How are email reminders scheduled and sent?**  \r\n   Email reminders are scheduled using Upstash Workflows, which triggers emails at 7, 5, 2, and 1 day(s) before a subscription’s renewal date. The workflow uses `context.sleepUntil` for precise timing and Nodemailer to send emails. Reminders are only sent for active subscriptions with future renewal dates.\r\n\r\n4. **Can I customise the email reminder intervals?**  \r\n   Yes, you can modify the `REMINDERS` array in `workflows/sendReminders.js` (currently set to `[7, 5, 2, 1]` days). Update the array with your preferred intervals and redeploy the workflow.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharishanan%2Fsubscription-tracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharishanan%2Fsubscription-tracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharishanan%2Fsubscription-tracker/lists"}