This app is for users who have few or a lot of digital services like Amazon Prime, Netflix, Starlink, Spotify and others subscriptions and have some trouble management of it.
For peoples who forgoting that fist month of subscription is free and then you must pay money. Or for people that forgot that prices in the future will change. If you want to test some service just for one month, you didn't like it but you forgot to unsubscribe from it and it will take your money until you didn't notice that at your bank mobile app. But with that also a big problem exists. When you see your monthly payments you do not always see what exactly service takes your money. Or you just want to see the amount price of all your services in one place.
So that's all about Sub-Managik, an app that was created by people who understand your problems and want to solve them for themselves and other people.
- How App Looks
- Technologies and Libraries Used
- Architecture
- Getting Started
- Contributing
- License
I used several technologies to create this app
- React v18
- Nextjs v14 — using TypeScript
- Tailwindcss — styling
- Flowbite — UI library
- Lucide — Icons
- Yup — forms validation
- React Hook Form — managing forms
- Axios and Tanstack — api requests
- sonner — beatifull toasts
- date-fns — managing dates in app
- js-cookie — handling cookies in app
NOTE: List of all dependencies, you can find at package.json file at frontend folder
- NestJs v10 — using TypeScript
- PostgreSQL — as database
- Prisma — as database ORM
- @nestjs/jwt and @nestjs/passport — managing the authentication and authorization
- @nestJs/cron — creating cron jobs
- cookie-parser — managing cookies in app
- node-telegram-bot-api — as telegram bot api
- twilio — SMS integration
- date-fns — managing dates in app
NOTE: List of all dependencies, you can find at package.json file at backend folder
So, i will describe architecture of app, database and folder structure
Frontend part as we use NextJs has own server and we use our backend wroten on NestJs which is separate from out frontend. As database we use PostgreSQL. Also we have some integrations with Twilio for SMS notifications and Telegram API for bot notifications for admin about some events, in our case if notifyng admin about new Requested Services which missing in our Application. Also we have some
The User
model represents a user in the system.
-
Fields:
id
(String): Unique identifier, generated usingcuid()
.name
(String): The user's name.email
(String): The user's email, unique.phone
(String, optional): The user's phone number, unique.password
(String): The user's password.createdAt
(DateTime): Timestamp when the user was created, defaults to the current date and time.updatedAt
(DateTime): Timestamp when the user was last updated, automatically set on update.deletedAt
(DateTime, optional): Timestamp when the user was deleted.subscriptions
(Subscription[]): List of subscriptions associated with the user.requestedServices
(RequestedService[]): List of requested services by the user.
-
Table name:
user
The Subscription
model represents a subscription to a service.
-
Fields:
id
(String): Unique identifier, generated usingcuid()
.user
(User): The user who owns the subscription.userId
(String): Foreign key referencingUser.id
.service
(Service): The service being subscribed to.serviceId
(String): Foreign key referencingService.id
.price
(Float): The price of the subscription.note
(String, optional): Additional notes about the subscription.isNotifying
(Boolean): Indicates if notifications are enabled for the subscription.nextPaymentAt
(DateTime): Timestamp for the next payment date.createdAt
(DateTime): Timestamp when the subscription was created, defaults to the current date and time.updatedAt
(DateTime): Timestamp when the subscription was last updated, automatically set on update.deletedAt
(DateTime, optional): Timestamp when the subscription was deleted.
-
Table name:
subscription
The Service
model represents a service that can be subscribed to.
-
Fields:
id
(String): Unique identifier, generated usingcuid()
.fullName
(String): Full name of the service.shortName
(String): Short name of the service.backgroundColor
(String): Background color associated with the service.subscriptions
(Subscription[]): List of subscriptions associated with the service.createdAt
(DateTime): Timestamp when the service was created, defaults to the current date and time.updatedAt
(DateTime): Timestamp when the service was last updated, automatically set on update.deletedAt
(DateTime, optional): Timestamp when the service was deleted.
-
Table name:
service
The RequestedService
model represents a service requested by a user that is not yet available.
-
Fields:
id
(String): Unique identifier, generated usingcuid()
.user
(User): The user who requested the service.userId
(String): Foreign key referencingUser.id
.name
(String): The name of the requested service.url
(String): The URL of the requested service.createdAt
(DateTime): Timestamp when the requested service was created, defaults to the current date and time.updatedAt
(DateTime): Timestamp when the requested service was last updated, automatically set on update.deletedAt
(DateTime, optional): Timestamp when the requested service was deleted.
-
Table name:
requested_service
- Each
User
can have multipleSubscription
s. - This is represented by the
subscriptions
field in theUser
model. - The relationship is established through a one-to-many relation.
- Each
User
can have multipleRequestedService
s. - This is represented by the
requestedServices
field in theUser
model. - The relationship is established through a one-to-many relation.
- Each
Subscription
belongs to a singleUser
. - This is represented by the
user
field in theSubscription
model. - The relationship is established through a many-to-one relation.
- Each
Subscription
is associated with a singleService
. - This is represented by the
service
field in theSubscription
model. - The relationship is established through a many-to-one relation.
- Each
Service
can have multipleSubscription
s. - This is represented by the
subscriptions
field in theService
model. - The relationship is established through a one-to-many relation.
- Each
RequestedService
belongs to a singleUser
. - This is represented by the
user
field in theRequestedService
model. - The relationship is established through a many-to-one relation.
The project is organized into two main directories:
backend
: Contains the server-side using NestJs code and database schema.frontend
: Contains the client-side code built with React and Next.js.docs
: Containes files required for documentation.
├─ backend/ # Root folder for backend
│ ├─ prisma # Folder with prisma schema of DB
│ ├─ seeders # Folder with seeders for DB
│ ├─ src/
│ | ├─ auth/ # Authentication module
│ │ │ ├─ .... # Other Authentication module files and folders
│ | ├─ notifications
│ | | ├─ .... # Other Authentication module files and folders
│ | ├─ requested-service
│ | | ├─ .... # Other Authentication module files and folders
│ | ├─ service
│ | | ├─ .... # Other Authentication module files and folders
│ | ├─ subscription
│ | | ├─ .... # Other Authentication module files and folders
│ | ├─ telegram
│ | | ├─ .... # Other Authentication module files and folders
│ | ├─ user
│ | | ├─ .... # Other Authentication module files and folders
│ | ├─ app.module.ts # Root module of the application
│ | ├─ main.ts # Entry point of the application
└─ frontend
├─ src
│ ├─ api
│ │ ├─ .... # Files required for making API requests
│ ├─ app
│ │ ├─ login
| │ ├─ ├─ .... # Other Login page files and folders
│ │ ├─ profile
| │ │ ├─ .... # Other Profile page files and folders
│ │ ├─ register
| │ │ ├─ .... # Other register page files and folders
│ │ ├─ request-service
| │ │ ├─ .... # Other Request Service page files and folders
│ │ └─ subscriptions
| │ │ ├─ .... # Other Subscriptions page files and folders
│ │ ├─ not-found.tsx # Not found page in App
│ │ ├─ page.tsx # Entry page in App
│ ├─ components
| │ ├─ .... # Other UI components files and folders
│ ├─ config
| │ ├─ .... # Other constants files used in app
│ ├─ constants
| │ ├─ .... # Other constants files used in app
│ ├─ hooks
| │ ├─ .... # Other hook files
│ ├─ services
| │ ├─ .... # Other services files used in app
│ └─ types
| │ ├─ .... # Other types files used in app
│ ├─ middleware.ts # Main middleware of App
├─ .... # Other fronend file
Ensure you have the following installed and have the following:
- Node.js v14+
- npm v6+
- PostgreSQL v12+
- Twilio SMS API credentials
- Telegram Bot API credentials
git clone https://github.com/nkshn/subs-managik-v2.git
cd subs-managik-v2
cd backend
npm install
cd frontend
npm install
Create a .env
file in the root of both backend
and frontend
directories and add the following:
DATABASE_URL="DATABES_URL_WITH_USER_AND_PASSWORD"
JWT_SECRET="YOUR_JWT_SECRET"
TELEGRAM_BOT_TOKEN="YOUR_TELEGRAM_BOT_TOKEN"
TELEGRAM_BOT_CHAT_ID="YOUR_TELEGRAM_BOT_CHAT_ID"
TWILIO_ACCOUNT_SID="YOUR_TWILIO_ACCOUNT_SID"
TWILIO_AUTH_TOKEN="YOUR_TWILIO_AUTH_TOKEN"
TWILIO_PHONE_NUMBER="YOUR_TWILIO_PHONE_NUMBER"
NOTE: You can find all required credentials at file: backend/.env.example
SERVER_URL="http://localhost:5000/api"
APP_DOMAIN_NAME=localhost
NOTE: You can find all required credentials at file: frontend/.env.example
cd backend
npx prisma db push
npm run seed
NOTE! This step is required! Without it, application will have erros on frontend!
The last step is left just to run the application
cd backend
npm run start:dev
cd ../frontend
npm run dev
Congrats, The application should now be running on http://localhost:3000.
Rules of contributing to project
git checkout -b feature-branch
git commit -am 'Add new feature'
git push origin feature-branch
ISC