Compare commits
1 commit
main
...
feature/sp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea1dfefca3 |
16 changed files with 9199 additions and 0 deletions
37
.cursorrules
Normal file
37
.cursorrules
Normal 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
26
Makefile
Normal 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
189
README.md
Normal 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
7
backend/.env.example
Normal 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
39
backend/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
11
backend/prisma/schema.prisma
Normal file
11
backend/prisma/schema.prisma
Normal 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
24
backend/tsconfig.json
Normal 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
58
docker-compose.yml
Normal 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
2
frontend/.env.example
Normal 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
7
frontend/next.config.ts
Normal 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
30
frontend/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
9
frontend/postcss.config.mjs
Normal file
9
frontend/postcss.config.mjs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
20
frontend/tailwind.config.ts
Normal file
20
frontend/tailwind.config.ts
Normal 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
27
frontend/tsconfig.json
Normal 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
8683
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
30
package.json
Normal file
30
package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue