Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/build
**/dist
LICENSE
README.md
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ next-env.d.ts

# Sentry Config File
.env.sentry-build-plugin

mongodb_data/
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM node:18-alpine

WORKDIR /app

# Copy package files first to leverage Docker cache
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the app
COPY . .

# Set environment variables
ENV PORT=3000
ENV HOST=0.0.0.0
ENV NODE_ENV=development

# Expose the port
EXPOSE 3000

# Start Next.js in development mode
CMD ["npm", "run", "dev"]
22 changes: 22 additions & 0 deletions README.Docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
### Building and running your application

When you're ready, start your application by running:
`docker compose up --build`.

Your application will be available at http://localhost:3000.

### Deploying your application to the cloud

First, build your image, e.g.: `docker build -t myapp .`.
If your cloud uses a different CPU architecture than your development
machine (e.g., you are on a Mac M1 and your cloud provider is amd64),
you'll want to build the image for that platform, e.g.:
`docker build --platform=linux/amd64 -t myapp .`.

Then, push it to your registry, e.g. `docker push myregistry.com/myapp`.

Consult Docker's [getting started](https://docs.docker.com/go/get-started-sharing/)
docs for more detail on building and pushing.

### References
* [Docker's Node.js guide](https://docs.docker.com/language/nodejs/)
51 changes: 46 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
# Subscribely

<div align="center">

[![Subscribely Logo](https://i.imgur.com/hicXmxC.png)](https://subscribely-subscription-manager.vercel.app/)

</div>

<div align="center">

[![Next.js](https://img.shields.io/badge/Next.js-15.2.3-black?style=flat-plastic&logo=next.js)](https://nextjs.org/)
[![MongoDB](https://img.shields.io/badge/MongoDB-8.12-green?style=flat-plastic&logo=mongodb)](https://www.mongodb.com/)
[![Vercel](https://img.shields.io/badge/Deployed_on-Vercel-black?style=flat-plastic&logo=vercel)](https://vercel.com)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue?style=flat-plastic&logo=docker)](https://www.docker.com/)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-plastic)](LICENSE)

</div>

## 📄 Overview

Subscribely is a creative project built to demonstrate a modern subscription management platform. This project has been in development for 2 months and serves as a showcase for implementing a comprehensive subscription system with role-based access controls.

**Note:** This is not a real-world application solving an actual business problem, but rather a creative project demonstrating various technical implementations and solutions.
Expand All @@ -27,31 +29,34 @@ Subscribely is a creative project built to demonstrate a modern subscription man
## ✨ Showcase

| ![Image 1](https://github.com/user-attachments/assets/9e557f57-79a8-4ea7-9918-1b8cd3177d71) | ![Image 2](https://github.com/user-attachments/assets/f8aec892-249c-4561-9019-58116fd76c16) |
|--------------------------------|--------------------------------|
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| ![Image 3](https://github.com/user-attachments/assets/6623ef73-e7e2-4f1f-a247-2500cf7ffbe8) | ![Image 4](https://github.com/user-attachments/assets/5bf05861-b21a-430d-bdd0-d2894664aa58) |


## 🔧 Features

### Authentication

- User registration and login system
- Role-based access control (Admin and User roles)
- Secure authentication with JWT

### User Features

- Default balance in USD for new accounts
- Subscription marketplace ("Subscription Store")
- Active subscription management (up to 3 active subscriptions)
- Subscription cancellation
- Profile settings with account deletion option

### Admin Features

- Create, edit, and delete subscription packages
- View all user subscriptions across the platform
- Ability to revoke user subscriptions with automatic email notification
- Modify user account balances

### Subscription System

- Configurable subscription packages (name, description, price, status)
- Customizable subscription durations (1 day, 14 days, 1 month, etc.)
- Automatic balance deduction on purchase
Expand All @@ -61,6 +66,7 @@ Subscribely is a creative project built to demonstrate a modern subscription man
- Admin-initiated subscription revocation

## 📐 Tech Stack

- **Framework**: Next.js 15 with TypeScript
- **Styling**: Tailwind CSS
- **Database**: MongoDB with Mongoose
Expand All @@ -71,8 +77,10 @@ Subscribely is a creative project built to demonstrate a modern subscription man
- **Monitoring**: Sentry
- **Security**: Arcjet
- **Deployment**: Vercel
- **Containerization**: Docker and Docker Compose

## 🗂️ Project Structure

The project follows a standard Next.js App Router structure with server actions and API routes.

```
Expand All @@ -93,6 +101,8 @@ The project follows a standard Next.js App Router structure with server actions
├── .gitignore
├── .prettierrc.json
├── components.json
├── docker-compose.yml
├── Dockerfile
├── eslint.config.mjs
├── instrumentation-client.ts
├── instrumentation.ts
Expand All @@ -109,6 +119,7 @@ The project follows a standard Next.js App Router structure with server actions
```

## 🌐 Development Practices

- Strongly typed with TypeScript
- Conventional commits for clear version history
- Git workflow configured with Husky and lint-staged
Expand All @@ -117,6 +128,8 @@ The project follows a standard Next.js App Router structure with server actions

## 📥 Installation

### Standard Installation

```bash
# Clone the repository
git clone https://github.com/dan0dev/Subscribely.Subscription.Manager.git
Expand All @@ -128,7 +141,34 @@ npm install
npm run dev
```

### Docker Installation

The application can also be run using Docker and Docker Compose, which sets up both the application and MongoDB database in containers with automatic file watching for development.

#### Prerequisites

- [Docker](https://www.docker.com/get-started) (20.10.0 or higher)
- [Docker Compose](https://docs.docker.com/compose/install/) (v2.0.0 or higher)

```bash
# Clone the repository
git clone https://github.com/dan0dev/Subscribely.Subscription.Manager.git

# Navigate to the project directory
cd Subscribely.Subscription.Manager

# Create .env file with your environment variables (see Environment Variables section)
# Then start the application with Docker Compose
docker compose up --build

# For development with live file watching
docker compose up
```

The application will be available at `http://localhost:3000`. Any changes made to the source files will be automatically synchronized to the container through the volume mounts and hot-reloading will be triggered by Next.js.

## 🌳 Environment Variables

Modify the `.env.local` file with your own variables data with the following:

```
Expand All @@ -145,9 +185,11 @@ SENTRY_AUTH_TOKEN=
```

## 💻 Deployment

The application is deployed on Vercel.

## 📝 Todo

- Creating test role as account
- Implement automatic subscription expiration (currently subscriptions don't expire automatically)
- Add subscription renewal options
Expand All @@ -160,7 +202,6 @@ Subscribely is an open-source project, and we welcome contributions of all kinds

We use [GitHub Issues](https://github.com/dan0dev/Subscribely.Subscription.Manager/issues) for tracking bugs and feature requests.


## 📃 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
39 changes: 39 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: "3.8"

services:
frontend:
build:
context: .
dockerfile: Dockerfile
container_name: subscribely
ports:
- "3000:3000"
develop:
watch:
- path: ./package.json
action: rebuild
- path: ./next.config.js
action: rebuild
- path: ./package-lock.json
action: rebuild
- path: .
target: /app
action: sync
environment:
- NODE_ENV=development
- PORT=3000
- HOST=0.0.0.0
- MONGODB_URI=${MONGODB_URI}
- JWT_SECRET=${JWT_SECRET}
- JWT_EXPIRES_IN=${JWT_EXPIRES_IN}
- GMAIL_USER=${GMAIL_USER}
- GMAIL_PASSWORD=${GMAIL_PASSWORD}
- ARCJET_KEY=${ARCJET_KEY}
- SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}
volumes:
- .:/app
- /app/node_modules
- /app/.next
restart: unless-stopped
tty: true
stdin_open: true
23 changes: 22 additions & 1 deletion next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ const getCspHeader = () => {
// API and WebSocket connections
"connect-src": [
"'self'",
// Sentry error reporting (update with your actual Sentry DSN)
// Docker development additions
"http://localhost:*",
"http://127.0.0.1:*",
"http://0.0.0.0:*",
"ws://localhost:*",
"ws://0.0.0.0:*",
// Sentry error reporting
"https://o4509210060587008.ingest.de.sentry.io",
// Arcjet security service
"https://api.arcjet.com",
Expand Down Expand Up @@ -111,6 +117,21 @@ const nextConfig = {
];
},

// Explicitly set server configuration
server: {
port: 3000,
hostname: "0.0.0.0",
},

// Required for webpack watcher in Docker
webpack: (config: import("webpack").Configuration): import("webpack").Configuration => {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
return config;
},

// HTTP headers for all responses
async headers() {
return [
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"dev": "next dev --hostname 0.0.0.0 --port 3000",
"build": "next build",
"start": "next start",
"start": "next start --hostname 0.0.0.0 --port 3000",
"lint": "next lint",
"prepare": "husky"
},
Expand Down