Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
SamoilenkoVadym
ea1dfefca3 feat(repo): add project structure, docker-compose, and documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 22:26:13 +01:00
16 changed files with 9199 additions and 0 deletions

37
.cursorrules Normal file
View file

@ -0,0 +1,37 @@
# Project Context
This is a SaaS marketplace for n8n workflow templates with AI assistant.
# Tech Stack
- Backend: Node.js 20, Express, TypeScript, Prisma, PostgreSQL
- Frontend: Next.js 15 (App Router), React 19, TypeScript, Tailwind CSS, shadcn/ui
- Infrastructure: Docker Compose, n8n, Redis
- AI: Azure OpenAI (Claude via Anthropic SDK)
- Payments: Stripe
# Code Style
- Use TypeScript strict mode
- Use async/await (no callbacks)
- Use ES6+ features
- 2 spaces indent
- No console.log in production code
- Always add error handling
- Use Prisma for all database operations
- Follow Conventional Commits format
# File Structure Rules
- Backend files go in /backend/src/
- Frontend files go in /frontend/src/
- Shared types in /backend/src/types/
- Use named exports (not default) for services
# When Creating Files
- Always include proper TypeScript types
- Add JSDoc comments for functions
- Include error handling
- Add input validation
- Never hardcode secrets (use env variables)
# Git Rules
- Never commit to main directly
- Use feature branches: feature/sprint-X-name
- Conventional Commits: feat(scope): description

26
Makefile Normal file
View file

@ -0,0 +1,26 @@
.PHONY: up down logs clean restart backend-shell db-migrate help
help: ## Show this help message
@echo "Available commands:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
up: ## Start all services
docker-compose up -d
down: ## Stop all services
docker-compose down
logs: ## Show logs from all services
docker-compose logs -f
clean: ## Stop services and remove volumes
docker-compose down -v
restart: ## Restart all services
docker-compose restart
backend-shell: ## Open shell in backend container (requires backend to be running)
cd backend && npm run dev
db-migrate: ## Run database migrations
cd backend && npm run db:migrate

189
README.md Normal file
View file

@ -0,0 +1,189 @@
# n8n SaaS Marketplace
A comprehensive platform for discovering, purchasing, and deploying n8n workflows. This marketplace enables users to browse pre-built automation workflows, subscribe to workflow packages, and seamlessly integrate them into their n8n instances.
## Features
- **Workflow Marketplace**: Browse and discover pre-built n8n workflows
- **User Authentication**: Secure user registration and login system
- **Subscription Management**: Stripe-powered payment processing for workflow subscriptions
- **AI-Powered Recommendations**: Azure OpenAI integration for personalized workflow suggestions
- **Real-time Updates**: Redis caching for optimal performance
- **Modern UI**: Built with Next.js 15 and React 19
## Tech Stack
### Backend
- **Runtime**: Node.js with TypeScript
- **Framework**: Express.js
- **Database**: PostgreSQL with Prisma ORM
- **Cache**: Redis
- **Authentication**: JWT with bcrypt
- **Payments**: Stripe
- **AI**: Azure OpenAI
### Frontend
- **Framework**: Next.js 15
- **UI**: React 19 with Tailwind CSS
- **State Management**: Zustand
- **Data Fetching**: TanStack Query (React Query)
- **HTTP Client**: Axios
### Infrastructure
- **Containerization**: Docker & Docker Compose
- **n8n**: Self-hosted n8n instance
- **Database**: PostgreSQL 16
- **Cache**: Redis 7
## Project Structure
```
n8n-saas-marketplace/
├── backend/ # Backend API
│ ├── src/ # Source code
│ ├── prisma/ # Database schema and migrations
│ ├── package.json
│ ├── tsconfig.json
│ └── .env.example
├── frontend/ # Frontend application
│ ├── src/
│ │ ├── app/ # Next.js app directory
│ │ ├── components/ # React components
│ │ └── lib/ # Utility functions
│ ├── public/ # Static assets
│ ├── package.json
│ ├── tsconfig.json
│ ├── tailwind.config.ts
│ ├── next.config.ts
│ └── .env.example
├── docker-compose.yml # Docker services configuration
├── Makefile # Convenience commands
├── package.json # Root package.json with workspaces
└── README.md
```
## Getting Started
### Prerequisites
- Node.js 18+ and npm
- Docker and Docker Compose
- Git
### Installation
1. **Clone the repository**
```bash
git clone <repository-url>
cd n8n-saas-marketplace
```
2. **Install dependencies**
```bash
npm run install:all
```
3. **Set up environment variables**
Backend:
```bash
cp backend/.env.example backend/.env
# Edit backend/.env with your configuration
```
Frontend:
```bash
cp frontend/.env.example frontend/.env
# Edit frontend/.env with your configuration
```
4. **Start Docker services**
```bash
make up
```
This will start:
- PostgreSQL (port 5432)
- Redis (port 6379)
- n8n (port 5678)
5. **Run database migrations**
```bash
make db-migrate
```
6. **Start development servers**
```bash
npm run dev
```
This will start:
- Backend API at http://localhost:4000
- Frontend at http://localhost:3000
- n8n at http://localhost:5678
## Available Commands
### Makefile Commands
- `make up` - Start all Docker services
- `make down` - Stop all Docker services
- `make logs` - View logs from all services
- `make clean` - Stop services and remove volumes
- `make restart` - Restart all services
- `make backend-shell` - Run backend in development mode
- `make db-migrate` - Run database migrations
- `make help` - Show all available commands
### NPM Commands
- `npm run dev` - Start both backend and frontend in development mode
- `npm run dev:backend` - Start only backend
- `npm run dev:frontend` - Start only frontend
- `npm run build` - Build both applications
- `npm run build:backend` - Build backend
- `npm run build:frontend` - Build frontend
## Development
### Backend Development
```bash
cd backend
npm run dev # Start development server
npm run db:generate # Generate Prisma client
npm run db:push # Push schema changes to database
npm run db:migrate # Run migrations
npm run db:studio # Open Prisma Studio
```
### Frontend Development
```bash
cd frontend
npm run dev # Start Next.js development server
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
```
## Environment Variables
### Backend (.env)
- `PORT` - Backend server port (default: 4000)
- `DATABASE_URL` - PostgreSQL connection string
- `JWT_SECRET` - Secret key for JWT token generation
- `REDIS_URL` - Redis connection URL
- `N8N_API_URL` - n8n instance API URL
- `STRIPE_SECRET_KEY` - Stripe secret key for payments
- `AZURE_OPENAI_ENDPOINT` - Azure OpenAI service endpoint
### Frontend (.env)
- `NEXT_PUBLIC_API_URL` - Backend API URL
- `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` - Stripe publishable key
## License
ISC

7
backend/.env.example Normal file
View file

@ -0,0 +1,7 @@
PORT=4000
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/n8n_marketplace
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
REDIS_URL=redis://localhost:6379
N8N_API_URL=http://localhost:5678
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com

39
backend/package.json Normal file
View file

@ -0,0 +1,39 @@
{
"name": "backend",
"version": "1.0.0",
"description": "n8n SaaS Marketplace Backend API",
"main": "dist/index.js",
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:studio": "prisma studio"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@prisma/client": "^6.1.0",
"axios": "^1.7.9",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"helmet": "^8.0.0",
"ioredis": "^5.4.2",
"jsonwebtoken": "^9.0.2"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.6",
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "^22.10.5",
"prisma": "^6.1.0",
"tsx": "^4.19.2",
"typescript": "^5.7.2"
}
}

View file

@ -0,0 +1,11 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

24
backend/tsconfig.json Normal file
View file

@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

58
docker-compose.yml Normal file
View file

@ -0,0 +1,58 @@
services:
postgres:
image: postgres:16-alpine
container_name: n8n_marketplace_postgres
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: n8n_marketplace
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: n8n_marketplace_redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: n8nio/n8n:latest
container_name: n8n_marketplace_n8n
restart: unless-stopped
environment:
- N8N_HOST=localhost
- N8N_PORT=5678
- N8N_PROTOCOL=http
- NODE_ENV=production
- WEBHOOK_URL=http://localhost:5678/
- GENERIC_TIMEZONE=UTC
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
volumes:
postgres_data:
redis_data:
n8n_data:

2
frontend/.env.example Normal file
View file

@ -0,0 +1,2 @@
NEXT_PUBLIC_API_URL=http://localhost:4000
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key

7
frontend/next.config.ts Normal file
View file

@ -0,0 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;

30
frontend/package.json Normal file
View file

@ -0,0 +1,30 @@
{
"name": "frontend",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@tanstack/react-query": "^5.62.11",
"axios": "^1.7.9",
"next": "15.1.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"zustand": "^5.0.3"
},
"devDependencies": {
"@types/node": "^22.10.5",
"@types/react": "^19.0.6",
"@types/react-dom": "^19.0.2",
"autoprefixer": "^10.4.20",
"eslint": "^9.18.0",
"eslint-config-next": "15.1.0",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.2"
}
}

View file

@ -0,0 +1,9 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
export default config;

View file

@ -0,0 +1,20 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
primary: "#FF6D5A",
secondary: "#007AFF",
},
},
},
plugins: [],
};
export default config;

27
frontend/tsconfig.json Normal file
View file

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

8683
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

30
package.json Normal file
View file

@ -0,0 +1,30 @@
{
"name": "n8n-saas-marketplace",
"version": "1.0.0",
"description": "n8n SaaS Marketplace - A platform for discovering and deploying n8n workflows",
"private": true,
"workspaces": [
"backend",
"frontend"
],
"scripts": {
"dev": "concurrently \"npm:dev:*\"",
"dev:backend": "npm run dev --workspace=backend",
"dev:frontend": "npm run dev --workspace=frontend",
"build": "npm run build --workspaces",
"build:backend": "npm run build --workspace=backend",
"build:frontend": "npm run build --workspace=frontend",
"install:all": "npm install && npm install --workspaces"
},
"keywords": [
"n8n",
"marketplace",
"workflow",
"automation"
],
"author": "",
"license": "ISC",
"devDependencies": {
"concurrently": "^9.1.2"
}
}