mirror of
https://github.com/thecyberlearn/quantumtaskai-caprover.git
synced 2026-08-18 07:52:55 +00:00
Remove non-essential files and reduce project bloat
Remove 29 unused files including: - Dokploy and Railway deployment configs - Multiple unused Dockerfiles - Debug/development scripts - Documentation and test files - Generated static files and logs Keep only files essential for CapRover deployment. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
200e8015e5
commit
2612019a61
@ -1,24 +0,0 @@
|
||||
# Required Environment Variables for Dokploy Deployment
|
||||
|
||||
# Django Core
|
||||
SECRET_KEY=your-secret-key-here-generate-a-new-one
|
||||
DEBUG=false
|
||||
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
|
||||
|
||||
# Database (PostgreSQL recommended for production)
|
||||
DATABASE_URL=postgres://username:password@hostname:5432/database_name
|
||||
|
||||
# Optional - Email Configuration
|
||||
EMAIL_HOST_USER=your-email@gmail.com
|
||||
EMAIL_HOST_PASSWORD=your-app-password
|
||||
|
||||
# Optional - Stripe Payments
|
||||
STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key
|
||||
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key
|
||||
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
|
||||
|
||||
# Optional - Static Files (for custom S3/CDN)
|
||||
# AWS_ACCESS_KEY_ID=your-aws-access-key
|
||||
# AWS_SECRET_ACCESS_KEY=your-aws-secret-key
|
||||
# AWS_STORAGE_BUCKET_NAME=your-bucket-name
|
||||
# AWS_S3_REGION_NAME=us-east-1
|
||||
@ -1,86 +0,0 @@
|
||||
# 🔐 Production Environment Variables Template
|
||||
# Copy this file and replace placeholder values with your actual production values
|
||||
# NEVER commit this file with real values to version control
|
||||
|
||||
# ========================================
|
||||
# 🔒 CORE SECURITY SETTINGS
|
||||
# ========================================
|
||||
SECRET_KEY=django-insecure-REPLACE-WITH-50-RANDOM-CHARACTERS-FOR-PRODUCTION
|
||||
DEBUG=False
|
||||
ALLOWED_HOSTS=your-project-name.railway.app,quantumtaskai.com,www.quantumtaskai.com
|
||||
CSRF_TRUSTED_ORIGINS=https://your-project-name.railway.app,https://quantumtaskai.com,https://www.quantumtaskai.com
|
||||
|
||||
# ========================================
|
||||
# 📧 EMAIL CONFIGURATION
|
||||
# ========================================
|
||||
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
||||
EMAIL_HOST=smtp.gmail.com
|
||||
EMAIL_PORT=587
|
||||
EMAIL_USE_TLS=True
|
||||
EMAIL_HOST_USER=your-email@gmail.com
|
||||
EMAIL_HOST_PASSWORD=your-16-character-app-password
|
||||
DEFAULT_FROM_EMAIL=Quantum Tasks AI <noreply@quantumtaskai.com>
|
||||
|
||||
# ========================================
|
||||
# 💳 STRIPE PAYMENT CONFIGURATION
|
||||
# ========================================
|
||||
STRIPE_SECRET_KEY=sk_live_your_stripe_secret_key_here
|
||||
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_endpoint_secret
|
||||
|
||||
# ========================================
|
||||
# 🤖 N8N AI AGENT WEBHOOKS (External Server)
|
||||
# ========================================
|
||||
# IMPORTANT: These URLs point to your SEPARATE N8N instance
|
||||
# Replace with your actual N8N webhook URLs
|
||||
|
||||
# Option A: N8N Cloud
|
||||
N8N_WEBHOOK_DATA_ANALYZER=https://yourworkspace.app.n8n.cloud/webhook/data-analyzer
|
||||
N8N_WEBHOOK_FIVE_WHYS=https://yourworkspace.app.n8n.cloud/webhook/five-whys
|
||||
N8N_WEBHOOK_JOB_POSTING=https://yourworkspace.app.n8n.cloud/webhook/job-posting
|
||||
N8N_WEBHOOK_SOCIAL_ADS=https://yourworkspace.app.n8n.cloud/webhook/social-ads
|
||||
|
||||
# Option B: Self-hosted N8N (comment out Option A if using this)
|
||||
# N8N_WEBHOOK_DATA_ANALYZER=https://your-n8n-server.com/webhook/data-analyzer
|
||||
# N8N_WEBHOOK_FIVE_WHYS=https://your-n8n-server.com/webhook/five-whys
|
||||
# N8N_WEBHOOK_JOB_POSTING=https://your-n8n-server.com/webhook/job-posting
|
||||
# N8N_WEBHOOK_SOCIAL_ADS=https://your-n8n-server.com/webhook/social-ads
|
||||
|
||||
# ========================================
|
||||
# 🌤️ EXTERNAL API KEYS
|
||||
# ========================================
|
||||
OPENWEATHER_API_KEY=your_openweather_api_key_here
|
||||
|
||||
# ========================================
|
||||
# ⚡ PERFORMANCE & CACHING (Optional)
|
||||
# ========================================
|
||||
# Redis URL - Automatically set by Railway Redis service
|
||||
# REDIS_URL=redis://default:password@host:port
|
||||
|
||||
# ========================================
|
||||
# 🔍 MONITORING & DEBUGGING
|
||||
# ========================================
|
||||
# Optional: Set to your admin email for notifications
|
||||
ADMIN_EMAIL=abhay@quantumtaskai.com
|
||||
|
||||
# ========================================
|
||||
# 📊 ANALYTICS (Optional)
|
||||
# ========================================
|
||||
# Add analytics service keys if needed
|
||||
# GOOGLE_ANALYTICS_ID=your_ga_id_here
|
||||
|
||||
# ========================================
|
||||
# NOTES FOR SETUP
|
||||
# ========================================
|
||||
# 1. Generate SECRET_KEY using: python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
|
||||
# 2. EMAIL_HOST_PASSWORD should be Gmail App Password (16 characters), not regular password
|
||||
# 3. Use LIVE Stripe keys for production (sk_live_... and whsec_...)
|
||||
# 4. N8N webhooks must be on external server accessible via HTTPS
|
||||
# 5. Test all variables before deploying to production
|
||||
|
||||
# ========================================
|
||||
# RAILWAY AUTOMATIC VARIABLES
|
||||
# ========================================
|
||||
# These are automatically set by Railway - DO NOT SET MANUALLY:
|
||||
# - DATABASE_URL (PostgreSQL connection string)
|
||||
# - PORT (Application port)
|
||||
# - RAILWAY_* (Railway-specific variables)
|
||||
@ -1,43 +0,0 @@
|
||||
# Railway Environment Variables Template
|
||||
# Copy this to Railway dashboard for environment-specific deployments
|
||||
|
||||
# Django Settings
|
||||
DEBUG=False
|
||||
SECRET_KEY=your-production-secret-key-here
|
||||
ALLOWED_HOSTS=your-domain.railway.app,www.quantumtaskai.com
|
||||
|
||||
# Database
|
||||
DATABASE_URL=postgresql://user:password@host:port/database
|
||||
|
||||
# Stripe Configuration
|
||||
STRIPE_PUBLISHABLE_KEY=pk_live_your_publishable_key
|
||||
STRIPE_SECRET_KEY=sk_live_your_secret_key
|
||||
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
|
||||
|
||||
# Email Configuration
|
||||
EMAIL_HOST=smtp.gmail.com
|
||||
EMAIL_PORT=587
|
||||
EMAIL_USE_TLS=True
|
||||
EMAIL_HOST_USER=your-email@gmail.com
|
||||
EMAIL_HOST_PASSWORD=your-app-password
|
||||
|
||||
# Admin Configuration
|
||||
DJANGO_SUPERUSER_USERNAME=admin
|
||||
DJANGO_SUPERUSER_EMAIL=admin@quantumtaskai.com
|
||||
DJANGO_SUPERUSER_PASSWORD=your-secure-admin-password
|
||||
|
||||
# N8N Webhook URLs (Production)
|
||||
N8N_WEBHOOK_DATA_ANALYZER=https://your-n8n-instance.com/webhook/data-analyzer
|
||||
N8N_WEBHOOK_SOCIAL_ADS=https://your-n8n-instance.com/webhook/social-ads
|
||||
N8N_WEBHOOK_JOB_POSTING=https://your-n8n-instance.com/webhook/job-posting
|
||||
N8N_WEBHOOK_FIVE_WHYS=https://your-n8n-instance.com/webhook/five-whys
|
||||
|
||||
# Security Settings
|
||||
SECURE_SSL_REDIRECT=True
|
||||
SECURE_HSTS_SECONDS=31536000
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS=True
|
||||
SECURE_FRAME_DENY=True
|
||||
|
||||
# Deployment Control
|
||||
DEPLOYMENT_ENVIRONMENT=production # production, staging, development
|
||||
BRANCH_NAME=main # Track which branch is deployed
|
||||
@ -1,172 +0,0 @@
|
||||
# CapRover Deployment Guide - Quantum Tasks AI
|
||||
|
||||
## Overview
|
||||
Step-by-step guide for deploying the Quantum Tasks AI Django application on CapRover.
|
||||
|
||||
## Prerequisites
|
||||
- CapRover installed and running on your VPS
|
||||
- GitHub repository with the project
|
||||
- Basic understanding of Django and CapRover
|
||||
|
||||
---
|
||||
|
||||
## Part 1: Project Setup
|
||||
|
||||
### Required Files
|
||||
Your repository contains these CapRover-ready files:
|
||||
```
|
||||
quantumtaskai-caprover/
|
||||
├── captain-definition # CapRover configuration
|
||||
├── Dockerfile.captain # Production Docker setup
|
||||
├── requirements.txt # Essential Python dependencies
|
||||
├── .dockerignore # Docker build optimization
|
||||
└── netcop_hub/settings.py # Django settings with production support
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Database**: Supports SQLite (dev), PostgreSQL (production)
|
||||
- **Static Files**: WhiteNoise for production serving
|
||||
- **Environment Variables**: Production-ready configuration
|
||||
|
||||
---
|
||||
|
||||
## Part 2: CapRover Deployment
|
||||
|
||||
### Step 1: Create New App
|
||||
1. **Open CapRover Dashboard**
|
||||
2. **Apps → Create New App**
|
||||
3. **App Name**: `quantumtaskai` (or your preferred name)
|
||||
4. **Click "Create New App"**
|
||||
|
||||
### Step 2: Configure GitHub Deployment
|
||||
1. **Go to**: App → Deployment Tab
|
||||
2. **Method**: Deploy from GitHub
|
||||
3. **Repository**: `https://github.com/thecyberlearn/quantumtaskai-caprover.git`
|
||||
4. **Branch**: `main`
|
||||
5. **Authentication**: Use GitHub Personal Access Token
|
||||
|
||||
### Step 3: Environment Variables
|
||||
**Go to**: App Configs → Environment Variables → Bulk Edit
|
||||
|
||||
**Essential Variables:**
|
||||
```env
|
||||
SECRET_KEY=your-unique-secret-key-here
|
||||
DEBUG=false
|
||||
ALLOWED_HOSTS=yourapp.yourdomain.com
|
||||
DATABASE_URL=postgres://user:password@host:5432/database
|
||||
```
|
||||
|
||||
**Optional Variables:**
|
||||
```env
|
||||
# Email Configuration (for notifications)
|
||||
EMAIL_HOST_USER=your-email@gmail.com
|
||||
EMAIL_HOST_PASSWORD=your-app-password
|
||||
|
||||
# Stripe Configuration (for payments)
|
||||
STRIPE_SECRET_KEY=sk_test_your_stripe_key
|
||||
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
|
||||
```
|
||||
|
||||
### Step 4: Deploy Application
|
||||
1. **Deployment Tab** → **Deploy Now**
|
||||
2. **Monitor build logs** for successful completion
|
||||
3. **Check App URL** after deployment completes
|
||||
|
||||
---
|
||||
|
||||
## Part 3: Database Setup (Optional)
|
||||
|
||||
If you need PostgreSQL database:
|
||||
|
||||
### Option A: CapRover PostgreSQL
|
||||
1. **One-Click Apps** → **PostgreSQL**
|
||||
2. **Create database instance**
|
||||
3. **Get connection details** from app configs
|
||||
4. **Add DATABASE_URL** to your app environment variables
|
||||
|
||||
### Option B: External Database
|
||||
1. **Use Railway, Neon, or other PostgreSQL provider**
|
||||
2. **Get connection string**
|
||||
3. **Add to environment variables**
|
||||
|
||||
---
|
||||
|
||||
## Part 4: Custom Domain (Optional)
|
||||
|
||||
1. **App Settings** → **HTTP Settings**
|
||||
2. **Add your domain**: `yourdomain.com`
|
||||
3. **Enable HTTPS**: Force HTTPS redirect
|
||||
4. **Update DNS**: Point your domain to CapRover server IP
|
||||
|
||||
---
|
||||
|
||||
## Part 5: Post-Deployment
|
||||
|
||||
### Create Admin User
|
||||
1. **App → Web Terminal**
|
||||
2. **Run commands**:
|
||||
```bash
|
||||
python manage.py migrate
|
||||
python manage.py createsuperuser
|
||||
```
|
||||
|
||||
### Verify Deployment
|
||||
1. **Visit your app URL**
|
||||
2. **Check admin panel**: `/admin/`
|
||||
3. **Test agent marketplace**: `/agents/`
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Failures
|
||||
- **Check logs** in Deployment tab
|
||||
- **Verify environment variables** are set
|
||||
- **Ensure SECRET_KEY** is properly set
|
||||
|
||||
### Runtime Issues
|
||||
- **Check App Logs** in CapRover dashboard
|
||||
- **Verify DATABASE_URL** format
|
||||
- **Check ALLOWED_HOSTS** includes your domain
|
||||
|
||||
### Database Issues
|
||||
- **Run migrations**: `python manage.py migrate`
|
||||
- **Check database connectivity**
|
||||
- **Verify PostgreSQL is running** (if using)
|
||||
|
||||
---
|
||||
|
||||
## Environment Variable Reference
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `SECRET_KEY` | Yes | Django secret key |
|
||||
| `DEBUG` | Yes | Set to `false` for production |
|
||||
| `ALLOWED_HOSTS` | Yes | Your domain name |
|
||||
| `DATABASE_URL` | Optional | PostgreSQL connection string |
|
||||
| `EMAIL_HOST_USER` | Optional | SMTP email username |
|
||||
| `EMAIL_HOST_PASSWORD` | Optional | SMTP email password |
|
||||
| `STRIPE_SECRET_KEY` | Optional | Stripe API key |
|
||||
|
||||
---
|
||||
|
||||
## Success Checklist
|
||||
|
||||
- [ ] App builds successfully in CapRover
|
||||
- [ ] Environment variables configured
|
||||
- [ ] Database migrations completed
|
||||
- [ ] Admin user created
|
||||
- [ ] App accessible via URL
|
||||
- [ ] Static files loading correctly
|
||||
- [ ] Agent marketplace functional
|
||||
|
||||
Your Quantum Tasks AI application should now be live and ready to use!
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For issues with:
|
||||
- **CapRover deployment**: Check CapRover documentation
|
||||
- **Django configuration**: Review `netcop_hub/settings.py`
|
||||
- **Agent system**: See `agents/` directory structure
|
||||
@ -1,32 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy and install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
SECRET_KEY="build-time-dummy-key-change-in-production"
|
||||
|
||||
# Collect static files
|
||||
RUN python manage.py collectstatic --noinput --settings=production_https_settings
|
||||
|
||||
# Make startup script executable
|
||||
RUN chmod +x start-dokploy.sh
|
||||
|
||||
# Expose port 3000 for Dokploy
|
||||
EXPOSE 3000
|
||||
|
||||
# Use startup script
|
||||
CMD ["./start-dokploy.sh"]
|
||||
@ -1,57 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy and install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
DEBUG=true \
|
||||
SECRET_KEY="build-time-dummy-key-change-in-production" \
|
||||
ALLOWED_HOSTS="*"
|
||||
|
||||
# Collect static files
|
||||
RUN python manage.py collectstatic --noinput --settings=debug_settings || true
|
||||
|
||||
# Make startup script executable
|
||||
RUN chmod +x start-dokploy.sh
|
||||
|
||||
# Expose port 3000 for Dokploy
|
||||
EXPOSE 3000
|
||||
|
||||
# Debug: Print Django info
|
||||
RUN python manage.py --version
|
||||
RUN python manage.py check --settings=debug_settings || true
|
||||
|
||||
# Start with debug info
|
||||
CMD echo "🐛 Debug Mode - Django $(python manage.py --version)" && \
|
||||
echo "🔍 Environment:" && \
|
||||
echo " - DEBUG: $DEBUG" && \
|
||||
echo " - ALLOWED_HOSTS: $ALLOWED_HOSTS" && \
|
||||
echo " - SECRET_KEY: $(echo $SECRET_KEY | cut -c1-10)..." && \
|
||||
echo "🌐 Testing Django config..." && \
|
||||
python manage.py check --settings=debug_settings && \
|
||||
echo "✅ Django config OK" && \
|
||||
echo "🧪 Testing URL patterns..." && \
|
||||
python manage.py show_urls --settings=debug_settings || echo "show_urls not available" && \
|
||||
echo "🚀 Starting server with detailed logging..." && \
|
||||
DJANGO_SETTINGS_MODULE=debug_settings gunicorn netcop_hub.wsgi:application
|
||||
--bind 0.0.0.0:3000 \
|
||||
--workers 1 \
|
||||
--timeout 120 \
|
||||
--log-level debug \
|
||||
--access-logfile - \
|
||||
--error-logfile - \
|
||||
--capture-output
|
||||
@ -1,18 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Create a simple test file
|
||||
RUN echo "<h1>🚀 Container is Running!</h1><p>Port 3000 is accessible</p><p>Time: $(date)</p>" > index.html
|
||||
|
||||
# Expose port 3000
|
||||
EXPOSE 3000
|
||||
|
||||
# Start simple HTTP server
|
||||
CMD echo "🧪 Simple HTTP Server Test" && \
|
||||
echo "📋 Container Details:" && \
|
||||
echo " - Time: $(date)" && \
|
||||
echo " - Port: 3000" && \
|
||||
echo " - Files: $(ls -la)" && \
|
||||
echo "🌐 Starting HTTP server on port 3000..." && \
|
||||
python -m http.server 3000
|
||||
@ -1,39 +0,0 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
libpq-dev \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy and install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set minimal environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
DEBUG=true \
|
||||
SECRET_KEY="test-secret-key-123456789" \
|
||||
ALLOWED_HOSTS="*"
|
||||
|
||||
# Expose port 3000
|
||||
EXPOSE 3000
|
||||
|
||||
# Very simple test - just run a basic HTTP server
|
||||
CMD echo "🧪 TEST MODE - Container is running!" && \
|
||||
echo "📋 Environment Check:" && \
|
||||
echo " - Python: $(python --version)" && \
|
||||
echo " - Django: $(python -c 'import django; print(django.get_version())')" && \
|
||||
echo " - Working directory: $(pwd)" && \
|
||||
echo " - Files: $(ls -la | head -10)" && \
|
||||
echo "" && \
|
||||
echo "🌐 Testing Django..." && \
|
||||
python manage.py check --settings=netcop_hub.settings && \
|
||||
echo "✅ Django OK - Starting simple HTTP server on port 3000" && \
|
||||
python -m http.server 3000
|
||||
212
WARP.md
212
WARP.md
@ -1,212 +0,0 @@
|
||||
# WARP.md
|
||||
|
||||
This file provides guidance to WARP (warp.dev) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
**Quantum Tasks AI** is a Django-based AI agent marketplace that allows users to browse, execute, and interact with various AI-powered tools and services. The application is designed for deployment on container platforms like CapRover and Dokploy.
|
||||
|
||||
### Core Architecture
|
||||
|
||||
- **Framework**: Django 5.2.4 with Django REST Framework
|
||||
- **Database**: SQLite (development) / PostgreSQL (production)
|
||||
- **Static Files**: WhiteNoise for production serving
|
||||
- **Agent System**: File-based JSON configuration system
|
||||
- **Authentication**: Custom User model with email verification
|
||||
- **Payments**: Stripe integration for agent execution fees
|
||||
- **Deployment**: Containerized with Docker, optimized for CapRover/Dokploy
|
||||
|
||||
### Application Structure
|
||||
|
||||
```
|
||||
├── agents/ # AI agent marketplace and execution system
|
||||
├── authentication/ # User management and authentication
|
||||
├── core/ # Homepage, health checks, and utilities
|
||||
├── wallet/ # Stripe payment integration
|
||||
├── netcop_hub/ # Django project settings and configuration
|
||||
├── static/ # Static assets (CSS, JS, images)
|
||||
├── templates/ # Django HTML templates
|
||||
└── agents/configs/ # File-based agent configurations
|
||||
├── agents/ # Individual agent JSON files
|
||||
└── categories/ # Agent categories configuration
|
||||
```
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Local Development Setup
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Database setup
|
||||
python manage.py migrate
|
||||
python manage.py createsuperuser
|
||||
|
||||
# Development server
|
||||
python manage.py runserver
|
||||
# OR use the development script
|
||||
./run_dev.sh
|
||||
```
|
||||
|
||||
### Testing and Quality
|
||||
|
||||
```bash
|
||||
# Run Django checks
|
||||
python manage.py check
|
||||
|
||||
# Test database connection
|
||||
python manage.py check --database default
|
||||
|
||||
# Clear agent cache (useful during development)
|
||||
python manage.py shell -c "from agents.services import AgentFileService; AgentFileService.clear_cache()"
|
||||
```
|
||||
|
||||
### Static Files and Assets
|
||||
|
||||
```bash
|
||||
# Collect static files for production
|
||||
python manage.py collectstatic --noinput
|
||||
|
||||
# Clear cache table
|
||||
python manage.py createcachetable
|
||||
```
|
||||
|
||||
## Agent System Architecture
|
||||
|
||||
### File-Based Configuration
|
||||
The application uses a file-based agent system instead of database models for agent configurations:
|
||||
|
||||
- **Agent configs**: `agents/configs/agents/*.json`
|
||||
- **Categories**: `agents/configs/categories/categories.json`
|
||||
- **Service class**: `AgentFileService` handles loading and caching
|
||||
|
||||
### Agent Configuration Format
|
||||
```json
|
||||
{
|
||||
"slug": "agent-identifier",
|
||||
"name": "Human Readable Name",
|
||||
"description": "Detailed description",
|
||||
"category": "category-slug",
|
||||
"price": 0.0,
|
||||
"agent_type": "form",
|
||||
"system_type": "webhook",
|
||||
"webhook_url": "https://external-service.com/webhook",
|
||||
"form_schema": {
|
||||
"fields": [
|
||||
{"name": "input", "type": "text", "label": "Input Field"}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Agent Execution Flow
|
||||
1. User selects agent from marketplace (`/agents/`)
|
||||
2. Fills out dynamic form based on `form_schema`
|
||||
3. Payment processed via Stripe (if price > 0)
|
||||
4. Request sent to agent's `webhook_url`
|
||||
5. Response stored in `AgentExecution` model
|
||||
6. Results displayed to user
|
||||
|
||||
## Deployment Configurations
|
||||
|
||||
### CapRover Deployment
|
||||
- **Docker file**: `Dockerfile.captain`
|
||||
- **Configuration**: `captain-definition`
|
||||
- **Port**: 80
|
||||
- **Startup**: Direct gunicorn execution
|
||||
|
||||
### Dokploy Deployment
|
||||
- **Docker file**: `Dockerfile.dokploy`
|
||||
- **Configuration**: `dokploy.json`
|
||||
- **Port**: 3000
|
||||
- **Startup**: `start-dokploy.sh` script with migrations
|
||||
|
||||
### Environment Variables
|
||||
|
||||
**Required for Production:**
|
||||
```env
|
||||
SECRET_KEY=your-secret-key-here
|
||||
DEBUG=false
|
||||
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
|
||||
```
|
||||
|
||||
**Optional:**
|
||||
```env
|
||||
DATABASE_URL=postgres://user:pass@host:5432/db
|
||||
EMAIL_HOST_USER=your-email@gmail.com
|
||||
EMAIL_HOST_PASSWORD=your-app-password
|
||||
STRIPE_SECRET_KEY=sk_live_your_stripe_key
|
||||
```
|
||||
|
||||
**Platform-Specific:**
|
||||
```env
|
||||
# CapRover auto-detection
|
||||
CAPROVER_GIT_COMMIT_SHA=auto-set-by-caprover
|
||||
|
||||
# Dokploy auto-detection
|
||||
DOKPLOY_PROJECT_NAME=your-project-name
|
||||
```
|
||||
|
||||
## Key Application Features
|
||||
|
||||
### Authentication System
|
||||
- Custom User model with email verification
|
||||
- Password reset functionality
|
||||
- User wallet balance tracking
|
||||
- Session management with security headers
|
||||
|
||||
### Payment Integration
|
||||
- Stripe checkout for agent executions
|
||||
- Wallet balance system
|
||||
- Transaction logging
|
||||
- Webhook handling for payment confirmations
|
||||
|
||||
### Agent Marketplace
|
||||
- Category-based organization
|
||||
- Search and filtering capabilities
|
||||
- Dynamic form generation based on agent schemas
|
||||
- Execution history tracking
|
||||
|
||||
### Security Features
|
||||
- CSRF protection with trusted origins
|
||||
- Rate limiting on critical endpoints
|
||||
- Security headers (CSP, XSS protection)
|
||||
- Input validation and sanitization
|
||||
- Error handling with custom error pages
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
### Dokploy 404 Errors
|
||||
If getting 404 errors on Dokploy:
|
||||
1. Ensure `ALLOWED_HOSTS` includes the Dokploy domain
|
||||
2. Check that port 3000 is correctly configured
|
||||
3. Verify health check endpoint `/health/` is accessible
|
||||
4. Use debug configuration temporarily: `Dockerfile.dokploy.debug`
|
||||
|
||||
### Database Issues
|
||||
- SQLite is used for development (no setup required)
|
||||
- PostgreSQL for production (requires `DATABASE_URL`)
|
||||
- Run migrations after deployment: `python manage.py migrate`
|
||||
|
||||
### Static Files Problems
|
||||
- Ensure `python manage.py collectstatic` runs during build
|
||||
- WhiteNoise handles static file serving in production
|
||||
- Check `STATIC_ROOT` and `STATICFILES_DIRS` configuration
|
||||
|
||||
### Agent Loading Issues
|
||||
- Agent configs are cached for performance
|
||||
- Clear cache during development: `AgentFileService.clear_cache()`
|
||||
- Check JSON syntax in agent configuration files
|
||||
- Ensure required fields are present in agent schemas
|
||||
|
||||
## Important File Locations
|
||||
|
||||
- **Main settings**: `netcop_hub/settings.py`
|
||||
- **URL configuration**: `netcop_hub/urls.py`
|
||||
- **Agent service**: `agents/services.py`
|
||||
- **Health check**: `core/views.py` (health_check_view)
|
||||
- **Error handlers**: `core/error_views.py`
|
||||
- **Production startup**: `start-dokploy.sh`
|
||||
|
||||
This Django application is optimized for containerized deployment with focus on AI agent marketplace functionality, file-based configuration management, and production-ready security features.
|
||||
@ -1,210 +0,0 @@
|
||||
"""
|
||||
Brand Digital Presence Analyzer
|
||||
|
||||
Python implementation for analyzing brand presence across 14 major digital platforms
|
||||
using Groq for fast and cost-effective AI analysis.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from groq import Groq
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, Optional
|
||||
from django.conf import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BrandPresenceAnalyzer:
|
||||
"""
|
||||
Analyzes brand digital presence across major platforms using Groq AI.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the analyzer with Groq configuration."""
|
||||
self.client = None
|
||||
if settings.GROQ_API_KEY:
|
||||
self.client = Groq(api_key=settings.GROQ_API_KEY)
|
||||
else:
|
||||
logger.warning("Groq API key not configured")
|
||||
|
||||
def analyze_brand_presence(self, brand_name: str, website_url: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Analyze brand presence across 14 digital platforms.
|
||||
|
||||
Args:
|
||||
brand_name: The brand name to search for
|
||||
website_url: The brand's official website URL
|
||||
|
||||
Returns:
|
||||
Dictionary containing analysis results in structured format
|
||||
"""
|
||||
if not self.client:
|
||||
return self._create_error_response("Groq API key not configured")
|
||||
|
||||
if not brand_name or not website_url:
|
||||
return self._create_error_response("Brand name and website URL are required")
|
||||
|
||||
try:
|
||||
logger.info(f"Starting brand presence analysis for: {brand_name}")
|
||||
|
||||
# Create the analysis prompt
|
||||
prompt = self._create_analysis_prompt(brand_name, website_url)
|
||||
|
||||
# Call Groq API
|
||||
response = self.client.chat.completions.create(
|
||||
model="llama-3.1-8b-instant", # Fast and current model
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are a digital marketing analyst. Return only valid JSON with no additional text or formatting."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": prompt
|
||||
}
|
||||
],
|
||||
temperature=0.3,
|
||||
max_tokens=2500
|
||||
)
|
||||
|
||||
# Extract and parse the response
|
||||
ai_response = response.choices[0].message.content.strip()
|
||||
logger.info(f"Received AI response for {brand_name}")
|
||||
|
||||
# Parse JSON response
|
||||
try:
|
||||
result = json.loads(ai_response)
|
||||
return self._format_success_response(result, brand_name, website_url)
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"Failed to parse AI response as JSON: {e}")
|
||||
logger.error(f"Raw response: {ai_response}")
|
||||
return self._create_error_response("Invalid response format from AI")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during brand presence analysis: {e}")
|
||||
return self._create_error_response(f"Analysis failed: {str(e)}")
|
||||
|
||||
def _create_analysis_prompt(self, brand_name: str, website_url: str) -> str:
|
||||
"""Create the detailed analysis prompt for the AI."""
|
||||
return f"""
|
||||
You are a digital marketing analyst specializing in brand presence research. Analyze the given brand's presence across 14 major digital platforms.
|
||||
|
||||
BRAND INFORMATION:
|
||||
Brand Name: {brand_name}
|
||||
Website: {website_url}
|
||||
|
||||
PLATFORMS TO ANALYZE:
|
||||
1. Google Business
|
||||
2. LinkedIn (Company Pages)
|
||||
3. YouTube
|
||||
4. TikTok
|
||||
5. Instagram
|
||||
6. Pinterest
|
||||
7. X (Twitter)
|
||||
8. Facebook (Business Pages)
|
||||
9. Medium
|
||||
10. Tumblr
|
||||
11. Threads
|
||||
12. Quora
|
||||
13. Reddit
|
||||
14. Blue Sky
|
||||
|
||||
SEARCH METHODOLOGY:
|
||||
- Search for exact brand name matches
|
||||
- Try variations (official, verified, brand + industry terms)
|
||||
- Cross-reference with the provided website URL
|
||||
- Look for verification badges and official indicators
|
||||
- Assess account activity and authenticity
|
||||
|
||||
RETURN ONLY THIS JSON FORMAT (no additional text):
|
||||
|
||||
{{
|
||||
"platforms": [
|
||||
{{
|
||||
"name": "Google Business",
|
||||
"found": true,
|
||||
"verified": true,
|
||||
"profile_url": "https://example.com/profile",
|
||||
"confidence": "high",
|
||||
"notes": "Verified business listing with reviews"
|
||||
}},
|
||||
{{
|
||||
"name": "LinkedIn",
|
||||
"found": false,
|
||||
"verified": null,
|
||||
"profile_url": null,
|
||||
"confidence": null,
|
||||
"notes": "No official company page found"
|
||||
}}
|
||||
],
|
||||
"summary": {{
|
||||
"total_platforms_checked": 14,
|
||||
"platforms_found": 8,
|
||||
"platforms_missing": 6,
|
||||
"completion_percentage": 57
|
||||
}},
|
||||
"recommendations": [
|
||||
{{
|
||||
"platform": "LinkedIn",
|
||||
"priority": "high",
|
||||
"reason": "Essential for B2B networking and credibility"
|
||||
}}
|
||||
]
|
||||
}}
|
||||
|
||||
IMPORTANT:
|
||||
- Return ONLY valid JSON
|
||||
- Set confidence as "high", "medium", or "low"
|
||||
- Use null for missing data
|
||||
- Include brief, helpful notes for each platform
|
||||
- Focus on official business accounts, not personal profiles
|
||||
- If unsure, mark confidence as "low" and explain in notes
|
||||
- Ensure all 14 platforms are included in the platforms array
|
||||
"""
|
||||
|
||||
def _format_success_response(self, ai_result: Dict, brand_name: str, website_url: str) -> Dict[str, Any]:
|
||||
"""Format the successful analysis response."""
|
||||
return {
|
||||
"status": "success",
|
||||
"brand_analysis": {
|
||||
"brand_name": brand_name,
|
||||
"website": website_url,
|
||||
"analysis_date": datetime.now().isoformat(),
|
||||
"processing_time": "AI-powered analysis"
|
||||
},
|
||||
"data": ai_result,
|
||||
"meta": {
|
||||
"analyzer_version": "1.0",
|
||||
"platforms_supported": 14,
|
||||
"analysis_method": "AI-powered research"
|
||||
}
|
||||
}
|
||||
|
||||
def _create_error_response(self, error_message: str) -> Dict[str, Any]:
|
||||
"""Create standardized error response."""
|
||||
return {
|
||||
"status": "error",
|
||||
"error": {
|
||||
"message": error_message,
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"code": "ANALYSIS_FAILED"
|
||||
}
|
||||
}
|
||||
|
||||
# Global analyzer instance - commented out to avoid import-time initialization
|
||||
# analyzer = BrandPresenceAnalyzer()
|
||||
|
||||
def analyze_brand_presence(brand_name: str, website_url: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Convenience function for analyzing brand presence.
|
||||
|
||||
Args:
|
||||
brand_name: The brand name to analyze
|
||||
website_url: The brand's website URL
|
||||
|
||||
Returns:
|
||||
Analysis results dictionary
|
||||
"""
|
||||
# Create analyzer instance when needed to avoid import-time initialization
|
||||
analyzer = BrandPresenceAnalyzer()
|
||||
return analyzer.analyze_brand_presence(brand_name, website_url)
|
||||
File diff suppressed because it is too large
Load Diff
12
build.sh
12
build.sh
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build script for Render deployment
|
||||
|
||||
set -o errexit # exit on error
|
||||
|
||||
echo "Installing dependencies..."
|
||||
pip install -r requirements.txt
|
||||
|
||||
echo "Collecting static files..."
|
||||
python manage.py collectstatic --noinput
|
||||
|
||||
echo "Build completed successfully!"
|
||||
@ -1,33 +0,0 @@
|
||||
"""
|
||||
Debug middleware for troubleshooting Dokploy 404 issues
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class DebugRequestMiddleware:
|
||||
"""Middleware to log all incoming requests for debugging"""
|
||||
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
# Log incoming request details
|
||||
logger.info(f"🌐 INCOMING REQUEST:")
|
||||
logger.info(f" - Method: {request.method}")
|
||||
logger.info(f" - Path: {request.path}")
|
||||
logger.info(f" - Full Path: {request.get_full_path()}")
|
||||
logger.info(f" - Host: {request.get_host()}")
|
||||
logger.info(f" - User Agent: {request.META.get('HTTP_USER_AGENT', 'Unknown')[:100]}")
|
||||
logger.info(f" - Remote IP: {request.META.get('REMOTE_ADDR', 'Unknown')}")
|
||||
logger.info(f" - Headers: {dict(request.headers)}")
|
||||
|
||||
# Process request
|
||||
response = self.get_response(request)
|
||||
|
||||
# Log response
|
||||
logger.info(f"📤 RESPONSE:")
|
||||
logger.info(f" - Status Code: {response.status_code}")
|
||||
logger.info(f" - Content Type: {response.get('Content-Type', 'Unknown')}")
|
||||
|
||||
return response
|
||||
@ -1,32 +0,0 @@
|
||||
# Debug settings for Dokploy troubleshooting
|
||||
from netcop_hub.settings import *
|
||||
|
||||
# Enable debug mode
|
||||
DEBUG = True
|
||||
|
||||
# Add debug middleware at the top
|
||||
MIDDLEWARE = ['debug_middleware.DebugRequestMiddleware'] + MIDDLEWARE
|
||||
|
||||
# Enhanced logging
|
||||
LOGGING['loggers']['root']['level'] = 'DEBUG'
|
||||
LOGGING['handlers']['console']['level'] = 'DEBUG'
|
||||
|
||||
# Print all URLs at startup
|
||||
print("🔗 Available URL patterns:")
|
||||
try:
|
||||
from django.urls import get_resolver
|
||||
resolver = get_resolver()
|
||||
url_patterns = []
|
||||
|
||||
def extract_patterns(patterns, prefix=''):
|
||||
for pattern in patterns:
|
||||
if hasattr(pattern, 'url_patterns'):
|
||||
extract_patterns(pattern.url_patterns, prefix + str(pattern.pattern))
|
||||
else:
|
||||
url_patterns.append(prefix + str(pattern.pattern))
|
||||
|
||||
extract_patterns(resolver.url_patterns)
|
||||
for pattern in url_patterns[:20]: # Show first 20
|
||||
print(f" - {pattern}")
|
||||
except Exception as e:
|
||||
print(f" - Error loading URL patterns: {e}")
|
||||
@ -1,54 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Deployment helper script for Dokploy
|
||||
# This script helps configure environment variables before deployment
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Dokploy Deployment Configuration Helper"
|
||||
echo "=========================================="
|
||||
|
||||
# Get domain from user
|
||||
read -p "Enter your domain (e.g., quamtumtaskai.netcoptech.com): " DOMAIN
|
||||
if [ -z "$DOMAIN" ]; then
|
||||
echo "❌ Domain is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate secret key if not provided
|
||||
if [ -z "$SECRET_KEY" ]; then
|
||||
echo "🔑 Generating SECRET_KEY..."
|
||||
SECRET_KEY=$(python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())')
|
||||
fi
|
||||
|
||||
# Set default environment variables
|
||||
export DOMAIN="$DOMAIN"
|
||||
export SECRET_KEY="$SECRET_KEY"
|
||||
export DEBUG="false"
|
||||
export ALLOWED_HOSTS="$DOMAIN,*"
|
||||
export CSRF_TRUSTED_ORIGINS="https://$DOMAIN,http://$DOMAIN"
|
||||
export SECURE_SSL_REDIRECT="false"
|
||||
export SECURE_PROXY_SSL_HEADER="HTTP_X_FORWARDED_PROTO,https"
|
||||
export DOKPLOY_PROJECT_NAME="quantum-tasks-ai"
|
||||
export PYTHONUNBUFFERED="1"
|
||||
|
||||
echo "✅ Configuration complete:"
|
||||
echo " - Domain: $DOMAIN"
|
||||
echo " - SECRET_KEY: ${SECRET_KEY:0:20}..."
|
||||
echo " - ALLOWED_HOSTS: $ALLOWED_HOSTS"
|
||||
echo " - SSL Redirect: $SECURE_SSL_REDIRECT"
|
||||
|
||||
echo ""
|
||||
echo "📋 Environment variables to set in Dokploy:"
|
||||
echo "DOMAIN=$DOMAIN"
|
||||
echo "SECRET_KEY=$SECRET_KEY"
|
||||
echo "DEBUG=false"
|
||||
echo "ALLOWED_HOSTS=$ALLOWED_HOSTS"
|
||||
echo "CSRF_TRUSTED_ORIGINS=$CSRF_TRUSTED_ORIGINS"
|
||||
echo "SECURE_SSL_REDIRECT=false"
|
||||
echo "SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https"
|
||||
echo "DOKPLOY_PROJECT_NAME=quantum-tasks-ai"
|
||||
echo "PYTHONUNBUFFERED=1"
|
||||
|
||||
echo ""
|
||||
echo "🔄 After setting these variables in Dokploy, trigger a redeploy."
|
||||
echo "🌐 Your app should be accessible at: https://$DOMAIN"
|
||||
@ -1,46 +0,0 @@
|
||||
# Simple Agent Creation Guide
|
||||
|
||||
## Quick Agent Creation
|
||||
|
||||
1. **Create JSON file** in `agents/configs/agents/your-agent-name.json`
|
||||
2. **Add basic config**:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Your Agent Name",
|
||||
"description": "What your agent does",
|
||||
"category": "productivity",
|
||||
"price": 5,
|
||||
"webhook_url": "https://your-webhook-endpoint.com",
|
||||
"form_schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "input",
|
||||
"type": "text",
|
||||
"label": "Your Input",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **Restart server** - Agent appears automatically
|
||||
|
||||
## Available Categories
|
||||
|
||||
Edit `agents/configs/categories/categories.json`:
|
||||
- `productivity` - Work tools
|
||||
- `content` - Content creation
|
||||
- `analysis` - Data analysis
|
||||
- `communication` - Communication tools
|
||||
|
||||
## Field Types
|
||||
|
||||
- `text` - Single line text
|
||||
- `textarea` - Multi-line text
|
||||
- `number` - Numeric input
|
||||
- `email` - Email input
|
||||
- `file` - File upload
|
||||
|
||||
That's it! Your agent will appear in the marketplace.
|
||||
@ -1,152 +0,0 @@
|
||||
# Agent Request Template
|
||||
|
||||
Use this template when requesting new agents for quick, error-free creation using the modern file-based system.
|
||||
|
||||
## How to Use This Template
|
||||
|
||||
1. **Copy the template below**
|
||||
2. **Fill in all required fields**
|
||||
3. **Provide to Claude Code** with the request "Create agent using this template"
|
||||
4. **Claude will handle** JSON config creation and deployment
|
||||
|
||||
---
|
||||
|
||||
## Agent Request Template
|
||||
|
||||
```markdown
|
||||
## New Agent Request
|
||||
|
||||
**Agent Name**: [Enter the display name for the agent]
|
||||
**Type**: [Webhook OR Direct Access]
|
||||
**Category**: [Choose from: analysis, career-education, document-processing, human-resources, marketing, consulting]
|
||||
**Price**: [X.XX AED or 0.0 for FREE]
|
||||
**Short Description**: [Brief 1-line description for marketplace]
|
||||
**Full Description**: [Detailed description of what the agent does and its benefits]
|
||||
|
||||
### For Webhook Agents Only:
|
||||
**Form Fields**:
|
||||
- Field 1: [name: field_name, type: text/textarea/select/file/url/checkbox, label: "Display Label", required: true/false]
|
||||
- Field 2: [name: field_name, type: text/textarea/select/file/url/checkbox, label: "Display Label", required: true/false]
|
||||
- [Add more fields as needed]
|
||||
|
||||
**N8N Webhook URL**: [Your N8N webhook endpoint URL]
|
||||
|
||||
### For Direct Access Agents Only:
|
||||
**External Form URL**: [JotForm, Google Forms, or other external form URL]
|
||||
**Custom Template Needed**: [Yes/No - specify if you need custom styling/layout]
|
||||
**Custom Views Needed**: [Yes/No - specify if you need special marketplace behavior]
|
||||
|
||||
### Optional Information:
|
||||
**Special Requirements**: [Any unique features or customizations needed]
|
||||
**Integration Notes**: [Any special setup or configuration details]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Available Categories
|
||||
|
||||
**Choose from these existing categories** (avoid creating new ones):
|
||||
|
||||
- 🧠 **`analysis`** - Problem-solving, SWOT analysis, strategic analysis tools
|
||||
- 🎓 **`career-education`** - Career guidance, educational resources, professional development
|
||||
- 📄 **`document-processing`** - PDF analysis, file processing, document tools
|
||||
- 💼 **`human-resources`** - Job postings, HR automation, talent management
|
||||
- 📢 **`marketing`** - Social ads, branding, content marketing, advertising
|
||||
- 💼 **`consulting`** - Business consultation, strategy services, expert advice
|
||||
|
||||
---
|
||||
|
||||
## Form Field Types (Webhook Agents)
|
||||
|
||||
- **`text`** - Single-line text input
|
||||
- **`textarea`** - Multi-line text input
|
||||
- **`select`** - Dropdown (requires options array)
|
||||
- **`file`** - File upload with drag-and-drop
|
||||
- **`url`** - URL input with validation
|
||||
- **`checkbox`** - Boolean true/false
|
||||
|
||||
---
|
||||
|
||||
## Example Requests
|
||||
|
||||
### Example 1: Webhook Agent
|
||||
```markdown
|
||||
## New Agent Request
|
||||
|
||||
**Agent Name**: Email Campaign Optimizer
|
||||
**Type**: Webhook
|
||||
**Category**: marketing
|
||||
**Price**: 4.0 AED
|
||||
**Short Description**: AI-powered email campaign optimization and A/B testing
|
||||
**Full Description**: Optimize your email campaigns with AI analysis of subject lines, content, and send times. Get recommendations for better open rates and conversions.
|
||||
|
||||
### Form Fields:
|
||||
- Field 1: [name: email_subject, type: text, label: "Email Subject Line", required: true]
|
||||
- Field 2: [name: email_content, type: textarea, label: "Email Content", required: true]
|
||||
- Field 3: [name: target_audience, type: select, label: "Target Audience", required: true, options: [{"value": "b2b", "label": "Business"}, {"value": "b2c", "label": "Consumer"}]]
|
||||
|
||||
**N8N Webhook URL**: http://localhost:5678/webhook/email-optimizer
|
||||
```
|
||||
|
||||
### Example 2: Direct Access Agent
|
||||
```markdown
|
||||
## New Agent Request
|
||||
|
||||
**Agent Name**: Financial Planning Consultant
|
||||
**Type**: Direct Access
|
||||
**Category**: consulting
|
||||
**Price**: 0.0 AED
|
||||
**Short Description**: Professional financial planning and investment consultation
|
||||
**Full Description**: Get expert financial advice tailored to your goals. Our certified financial planners provide personalized investment strategies and retirement planning.
|
||||
|
||||
### For Direct Access Agents:
|
||||
**External Form URL**: https://form.jotform.com/financial-planning-form-id
|
||||
**Custom Template Needed**: No
|
||||
**Custom Views Needed**: No
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What Happens Next
|
||||
|
||||
After you provide the completed template:
|
||||
|
||||
1. ✅ **Claude creates JSON config** in `agents/configs/agents/`
|
||||
2. ✅ **Agent configuration is committed to git**
|
||||
3. ✅ **Agent appears in marketplace** automatically via file-based system
|
||||
4. ✅ **Creates any needed templates/views** (for advanced Direct Access agents)
|
||||
5. ✅ **Updates marketplace integration** if needed
|
||||
6. ✅ **Railway deployment ready** - no manual database commands
|
||||
|
||||
**Simple Process:** JSON file → git commit → agent appears! 🚀
|
||||
|
||||
---
|
||||
|
||||
## Current Agents (8 Total)
|
||||
|
||||
### Webhook Agents (4)
|
||||
- **Social Ads Generator** - 6.00 AED - Social media ad creation
|
||||
- **Job Posting Generator** - 10.00 AED - Professional job postings
|
||||
- **PDF Summarizer** - 8.00 AED - Document analysis and summarization
|
||||
- **5 Whys Analyzer** - 15.00 AED - Interactive root cause analysis
|
||||
|
||||
### Direct Access Agents (4)
|
||||
- **CyberSec Career Navigator** - FREE - Career guidance
|
||||
- **AI Brand Strategist** - FREE - Brand strategy consultation
|
||||
- **Lean Six Sigma Expert** - FREE - Process improvement
|
||||
- **SWOT Analysis Expert** - FREE - Strategic analysis
|
||||
|
||||
---
|
||||
|
||||
## Tips for Better Requests
|
||||
|
||||
- ✅ **Use existing categories** - Avoid creating new ones unless absolutely necessary
|
||||
- ✅ **Be specific** - Clear descriptions help users understand the agent's value
|
||||
- ✅ **Test external forms** - Ensure JotForm/external URLs are working before requesting
|
||||
- ✅ **Consider pricing** - Free agents get more usage, paid agents need clear value proposition
|
||||
- ✅ **Think about fields** - For webhook agents, plan your form fields carefully
|
||||
- ✅ **Simple is better** - The file-based system makes creation effortless
|
||||
|
||||
---
|
||||
|
||||
*For comprehensive agent creation details, see `docs/AGENT_CREATION.md`*
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "quantum-tasks-ai-debug",
|
||||
"type": "dockerfile",
|
||||
"dockerfile": "./Dockerfile.dokploy.debug",
|
||||
"port": 3000,
|
||||
"healthCheck": "/health/",
|
||||
"buildArgs": {},
|
||||
"buildOptions": ["--no-cache"],
|
||||
"env": {
|
||||
"PYTHONUNBUFFERED": "1",
|
||||
"DEBUG": "true",
|
||||
"SECRET_KEY": "debug-key-change-in-production",
|
||||
"ALLOWED_HOSTS": "*"
|
||||
}
|
||||
}
|
||||
25
dokploy.json
25
dokploy.json
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "quantum-tasks-ai",
|
||||
"type": "dockerfile",
|
||||
"dockerfile": "./Dockerfile.dokploy",
|
||||
"port": 3000,
|
||||
"healthCheck": "/health/",
|
||||
"buildArgs": {},
|
||||
"buildOptions": ["--no-cache"],
|
||||
"security": {
|
||||
"redirectHttpsToHttp": true,
|
||||
"forceHttps": false
|
||||
},
|
||||
"env": {
|
||||
"PYTHONUNBUFFERED": "1",
|
||||
"DEBUG": "false",
|
||||
"SECRET_KEY": "${SECRET_KEY:-production-key-change-this-123456789}",
|
||||
"ALLOWED_HOSTS": "${ALLOWED_HOSTS:-*}",
|
||||
"DOKPLOY_PROJECT_NAME": "quantum-tasks-ai",
|
||||
"SECURE_SSL_REDIRECT": "${SECURE_SSL_REDIRECT:-false}",
|
||||
"SECURE_PROXY_SSL_HEADER": "HTTP_X_FORWARDED_PROTO,https",
|
||||
"CSRF_TRUSTED_ORIGINS": "${CSRF_TRUSTED_ORIGINS:-}",
|
||||
"DATABASE_URL": "${DATABASE_URL:-}",
|
||||
"DOMAIN": "${DOMAIN:-quamtumtaskai.netcoptech.com}"
|
||||
}
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
# Production HTTPS settings for Dokploy deployment
|
||||
from netcop_hub.settings import *
|
||||
|
||||
# Force HTTPS in production
|
||||
SECURE_SSL_REDIRECT = True
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
|
||||
# HSTS (HTTP Strict Transport Security)
|
||||
SECURE_HSTS_SECONDS = 31536000 # 1 year
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
|
||||
SECURE_HSTS_PRELOAD = True
|
||||
|
||||
# Cookie security
|
||||
SESSION_COOKIE_SECURE = True
|
||||
CSRF_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
CSRF_COOKIE_HTTPONLY = True
|
||||
|
||||
# Additional security headers
|
||||
SECURE_CONTENT_TYPE_NOSNIFF = True
|
||||
SECURE_BROWSER_XSS_FILTER = True
|
||||
X_FRAME_OPTIONS = 'DENY'
|
||||
|
||||
# Trust Dokploy/Traefik proxy headers
|
||||
USE_X_FORWARDED_HOST = True
|
||||
USE_X_FORWARDED_PORT = True
|
||||
|
||||
# CSRF trusted origins for HTTPS
|
||||
CSRF_TRUSTED_ORIGINS = [
|
||||
'https://website-quantumtaskai-wrczik-cc50ac-31-97-62-205.traefik.me',
|
||||
'http://website-quantumtaskai-wrczik-cc50ac-31-97-62-205.traefik.me', # For testing
|
||||
'https://localhost:3000',
|
||||
'http://localhost:3000',
|
||||
]
|
||||
|
||||
print("🔒 HTTPS Production Settings Loaded")
|
||||
print(f" - SSL Redirect: {SECURE_SSL_REDIRECT}")
|
||||
print(f" - HSTS: {SECURE_HSTS_SECONDS} seconds")
|
||||
print(f" - Trusted Origins: {len(CSRF_TRUSTED_ORIGINS)} configured")
|
||||
39
run_dev.sh
39
run_dev.sh
@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Development server startup script
|
||||
# Ensures clean environment for Django development
|
||||
|
||||
echo "🚀 Starting Django Development Server"
|
||||
echo "======================================"
|
||||
|
||||
# Clear any DATABASE_URL that might interfere with local development
|
||||
unset DATABASE_URL
|
||||
|
||||
# Activate virtual environment
|
||||
echo "📦 Activating virtual environment..."
|
||||
source venv/bin/activate
|
||||
|
||||
# Check database configuration
|
||||
echo "🔍 Checking database configuration..."
|
||||
python manage.py check_db
|
||||
|
||||
# Check for pending migrations
|
||||
echo ""
|
||||
echo "🔄 Checking for pending migrations..."
|
||||
if python manage.py showmigrations --plan | grep -q '\[ \]'; then
|
||||
echo "⚠️ Found pending migrations. Applying them..."
|
||||
python manage.py migrate
|
||||
echo "✅ Migrations applied successfully!"
|
||||
else
|
||||
echo "✅ All migrations up to date!"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🌐 Starting Django server..."
|
||||
echo "Visit: http://localhost:8000"
|
||||
echo "Admin: http://localhost:8000/admin"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop the server"
|
||||
echo "======================================"
|
||||
|
||||
# Start the development server
|
||||
python manage.py runserver
|
||||
@ -1,319 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Auto Documentation Update Script
|
||||
Automatically updates README.md, CLAUDE.md, and docs/ files based on recent changes
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import subprocess
|
||||
import re
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Set
|
||||
|
||||
class DocumentationUpdater:
|
||||
def __init__(self, project_root: str = None):
|
||||
self.project_root = Path(project_root) if project_root else Path.cwd()
|
||||
self.changes_summary = {}
|
||||
self.updated_files = []
|
||||
|
||||
def analyze_recent_changes(self, commit_count: int = 5) -> Dict:
|
||||
"""Analyze recent git commits to understand what changed"""
|
||||
try:
|
||||
# Get recent commit messages
|
||||
result = subprocess.run([
|
||||
'git', 'log', f'--oneline', f'-{commit_count}'
|
||||
], capture_output=True, text=True, cwd=self.project_root)
|
||||
|
||||
commits = result.stdout.strip().split('\n') if result.stdout else []
|
||||
|
||||
# Get changed files in recent commits
|
||||
result = subprocess.run([
|
||||
'git', 'diff', 'HEAD~1', '--name-only'
|
||||
], capture_output=True, text=True, cwd=self.project_root)
|
||||
|
||||
changed_files = result.stdout.strip().split('\n') if result.stdout else []
|
||||
|
||||
# Categorize changes
|
||||
categories = {
|
||||
'agents': [],
|
||||
'core': [],
|
||||
'deployment': [],
|
||||
'documentation': [],
|
||||
'frontend': [],
|
||||
'backend': []
|
||||
}
|
||||
|
||||
for file in changed_files:
|
||||
if not file:
|
||||
continue
|
||||
|
||||
file_lower = file.lower()
|
||||
if any(agent in file for agent in ['agent', 'processor', 'models.py']):
|
||||
categories['agents'].append(file)
|
||||
elif any(core in file for core in ['settings', 'urls.py', 'views.py']):
|
||||
categories['core'].append(file)
|
||||
elif any(deploy in file for deploy in ['railway', 'requirements', 'docker']):
|
||||
categories['deployment'].append(file)
|
||||
elif file_lower.endswith('.md') or 'docs/' in file:
|
||||
categories['documentation'].append(file)
|
||||
elif any(frontend in file for frontend in ['.html', '.css', '.js']):
|
||||
categories['frontend'].append(file)
|
||||
else:
|
||||
categories['backend'].append(file)
|
||||
|
||||
return {
|
||||
'commits': commits,
|
||||
'changed_files': changed_files,
|
||||
'categories': categories,
|
||||
'analysis_date': datetime.now().isoformat()
|
||||
}
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error analyzing git changes: {e}")
|
||||
return {}
|
||||
|
||||
def find_documentation_files(self) -> Dict[str, List[Path]]:
|
||||
"""Find all documentation files in the project"""
|
||||
doc_files = {
|
||||
'readme': [],
|
||||
'claude_md': [],
|
||||
'docs_directory': []
|
||||
}
|
||||
|
||||
# Find README files
|
||||
for readme in self.project_root.rglob('README.md'):
|
||||
doc_files['readme'].append(readme)
|
||||
|
||||
# Find CLAUDE.md files
|
||||
for claude in self.project_root.rglob('CLAUDE.md'):
|
||||
doc_files['claude_md'].append(claude)
|
||||
|
||||
# Find docs directory files
|
||||
docs_path = self.project_root / 'docs'
|
||||
if docs_path.exists():
|
||||
for doc_file in docs_path.rglob('*.md'):
|
||||
doc_files['docs_directory'].append(doc_file)
|
||||
|
||||
return doc_files
|
||||
|
||||
def should_update_documentation(self, changes: Dict) -> bool:
|
||||
"""Determine if documentation updates are needed"""
|
||||
# Check if significant changes were made
|
||||
categories = changes.get('categories', {})
|
||||
|
||||
# Always update if agents, core, or deployment changed
|
||||
significant_changes = (
|
||||
categories.get('agents', []) or
|
||||
categories.get('core', []) or
|
||||
categories.get('deployment', [])
|
||||
)
|
||||
|
||||
# Check commit messages for documentation keywords
|
||||
commits = changes.get('commits', [])
|
||||
doc_keywords = ['add', 'update', 'new', 'feature', 'agent', 'deploy']
|
||||
|
||||
has_doc_worthy_commits = any(
|
||||
any(keyword in commit.lower() for keyword in doc_keywords)
|
||||
for commit in commits
|
||||
)
|
||||
|
||||
return bool(significant_changes or has_doc_worthy_commits)
|
||||
|
||||
def update_claude_md(self, changes: Dict) -> bool:
|
||||
"""Update CLAUDE.md with recent changes"""
|
||||
claude_file = self.project_root / 'CLAUDE.md'
|
||||
if not claude_file.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
content = claude_file.read_text()
|
||||
original_content = content
|
||||
updated = False
|
||||
|
||||
categories = changes.get('categories', {})
|
||||
|
||||
# Update project overview if agents were added/modified
|
||||
if categories.get('agents'):
|
||||
# This is a simplified example - in practice, you'd parse and update specific sections
|
||||
overview_pattern = r'(## Project Overview.*?)(## Development Commands)'
|
||||
if re.search(overview_pattern, content, re.DOTALL):
|
||||
print("Found project overview section in CLAUDE.md")
|
||||
# Add logic to update agent count, new agent descriptions, etc.
|
||||
updated = True
|
||||
|
||||
# Update commands section if new scripts were added
|
||||
if any('manage.py' in f or 'script' in f for f in changes.get('changed_files', [])):
|
||||
print("Detected management command changes")
|
||||
updated = True
|
||||
|
||||
# Update environment variables section if settings changed
|
||||
if any('settings' in f or 'env' in f for f in changes.get('changed_files', [])):
|
||||
print("Detected environment/settings changes")
|
||||
updated = True
|
||||
|
||||
# Add timestamp of last update
|
||||
if updated:
|
||||
timestamp_pattern = r'(Last updated: )[\d\-:T\s]+\n'
|
||||
new_timestamp = f"Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
|
||||
|
||||
if re.search(timestamp_pattern, content):
|
||||
content = re.sub(timestamp_pattern, f"\\1{new_timestamp}", content)
|
||||
else:
|
||||
# Add timestamp at the end
|
||||
content += f"\n\n---\nLast updated: {new_timestamp}"
|
||||
|
||||
claude_file.write_text(content)
|
||||
self.updated_files.append(str(claude_file))
|
||||
return True
|
||||
|
||||
return updated
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error updating CLAUDE.md: {e}")
|
||||
return False
|
||||
|
||||
def update_readme(self, changes: Dict) -> bool:
|
||||
"""Update README.md with recent changes"""
|
||||
readme_file = self.project_root / 'README.md'
|
||||
if not readme_file.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
content = readme_file.read_text()
|
||||
updated = False
|
||||
|
||||
categories = changes.get('categories', {})
|
||||
|
||||
# Update features section if new agents were added
|
||||
if categories.get('agents'):
|
||||
print("Updating README features section for new agents")
|
||||
updated = True
|
||||
|
||||
# Update installation section if requirements changed
|
||||
if any('requirements' in f or 'setup' in f for f in changes.get('changed_files', [])):
|
||||
print("Updating README installation section")
|
||||
updated = True
|
||||
|
||||
if updated:
|
||||
readme_file.write_text(content)
|
||||
self.updated_files.append(str(readme_file))
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error updating README.md: {e}")
|
||||
return False
|
||||
|
||||
def update_docs_directory(self, changes: Dict) -> bool:
|
||||
"""Update files in docs/ directory"""
|
||||
docs_path = self.project_root / 'docs'
|
||||
if not docs_path.exists():
|
||||
return False
|
||||
|
||||
updated_any = False
|
||||
categories = changes.get('categories', {})
|
||||
|
||||
# Update agent creation guide if agent changes were made
|
||||
if categories.get('agents'):
|
||||
agent_guide = docs_path / 'development' / 'agent-creation.md'
|
||||
if agent_guide.exists():
|
||||
print("Updating agent creation guide")
|
||||
# Add new patterns, update examples, etc.
|
||||
updated_any = True
|
||||
self.updated_files.append(str(agent_guide))
|
||||
|
||||
# Update deployment guide if deployment files changed
|
||||
if categories.get('deployment'):
|
||||
deploy_guide = docs_path / 'deployment' / 'railway-deployment.md'
|
||||
if deploy_guide.exists():
|
||||
print("Updating deployment guide")
|
||||
updated_any = True
|
||||
self.updated_files.append(str(deploy_guide))
|
||||
|
||||
return updated_any
|
||||
|
||||
def generate_update_summary(self, changes: Dict) -> str:
|
||||
"""Generate a summary of what was updated"""
|
||||
summary = []
|
||||
summary.append("=== Documentation Auto-Update Summary ===")
|
||||
summary.append(f"Update Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
summary.append("")
|
||||
|
||||
# Recent commits
|
||||
commits = changes.get('commits', [])
|
||||
if commits:
|
||||
summary.append("Recent Commits:")
|
||||
for commit in commits[:3]: # Show last 3 commits
|
||||
summary.append(f" - {commit}")
|
||||
summary.append("")
|
||||
|
||||
# Changed files by category
|
||||
categories = changes.get('categories', {})
|
||||
for category, files in categories.items():
|
||||
if files:
|
||||
summary.append(f"{category.title()} Changes:")
|
||||
for file in files[:5]: # Show up to 5 files per category
|
||||
summary.append(f" - {file}")
|
||||
summary.append("")
|
||||
|
||||
# Updated documentation files
|
||||
if self.updated_files:
|
||||
summary.append("Updated Documentation Files:")
|
||||
for file in self.updated_files:
|
||||
summary.append(f" - {file}")
|
||||
else:
|
||||
summary.append("No documentation files required updates.")
|
||||
|
||||
summary.append("")
|
||||
summary.append("=== End Summary ===")
|
||||
|
||||
return "\n".join(summary)
|
||||
|
||||
def run_update(self) -> str:
|
||||
"""Main method to run the documentation update process"""
|
||||
print("Starting documentation auto-update...")
|
||||
|
||||
# Analyze recent changes
|
||||
changes = self.analyze_recent_changes()
|
||||
|
||||
if not changes:
|
||||
return "Error: Could not analyze recent changes"
|
||||
|
||||
# Check if updates are needed
|
||||
if not self.should_update_documentation(changes):
|
||||
return "No significant changes detected - documentation update skipped"
|
||||
|
||||
# Find documentation files
|
||||
doc_files = self.find_documentation_files()
|
||||
print(f"Found documentation files: {sum(len(files) for files in doc_files.values())}")
|
||||
|
||||
# Update each type of documentation
|
||||
updated_claude = self.update_claude_md(changes)
|
||||
updated_readme = self.update_readme(changes)
|
||||
updated_docs = self.update_docs_directory(changes)
|
||||
|
||||
# Generate and save summary
|
||||
summary = self.generate_update_summary(changes)
|
||||
|
||||
# Save summary to file
|
||||
summary_file = self.project_root / 'docs_update_summary.txt'
|
||||
summary_file.write_text(summary)
|
||||
|
||||
print(summary)
|
||||
return summary
|
||||
|
||||
def main():
|
||||
"""Main entry point"""
|
||||
project_root = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
|
||||
updater = DocumentationUpdater(project_root)
|
||||
result = updater.run_update()
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,143 +0,0 @@
|
||||
#!/bin/bash
|
||||
# GitHub Branch Protection Setup Script
|
||||
# Run this script to configure branch protection rules
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}🔐 Setting up GitHub Branch Protection Rules${NC}"
|
||||
echo "This script will guide you through configuring branch protection for Railway deployment control."
|
||||
echo ""
|
||||
|
||||
# Check if GitHub CLI is installed
|
||||
if ! command -v gh &> /dev/null; then
|
||||
echo -e "${RED}❌ GitHub CLI (gh) is not installed.${NC}"
|
||||
echo "Please install GitHub CLI first:"
|
||||
echo " - macOS: brew install gh"
|
||||
echo " - Ubuntu: sudo apt install gh"
|
||||
echo " - Or visit: https://cli.github.com/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if user is authenticated
|
||||
if ! gh auth status &> /dev/null; then
|
||||
echo -e "${YELLOW}🔑 You need to authenticate with GitHub first.${NC}"
|
||||
echo "Run: gh auth login"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get repository information
|
||||
REPO_OWNER=$(gh repo view --json owner --jq '.owner.login')
|
||||
REPO_NAME=$(gh repo view --json name --jq '.name')
|
||||
|
||||
echo -e "${GREEN}📋 Repository: ${REPO_OWNER}/${REPO_NAME}${NC}"
|
||||
echo ""
|
||||
|
||||
# Function to create branch protection rule
|
||||
create_branch_protection() {
|
||||
local branch=$1
|
||||
local description=$2
|
||||
|
||||
echo -e "${YELLOW}🛡️ Setting up protection for ${branch} branch (${description})${NC}"
|
||||
|
||||
# Create branch protection rule
|
||||
gh api repos/${REPO_OWNER}/${REPO_NAME}/branches/${branch}/protection \
|
||||
--method PUT \
|
||||
--field required_status_checks='{"strict":true,"contexts":[]}' \
|
||||
--field enforce_admins=true \
|
||||
--field required_pull_request_reviews='{"required_approving_review_count":1,"dismiss_stale_reviews":true,"require_code_owner_reviews":false}' \
|
||||
--field restrictions=null \
|
||||
--field allow_force_pushes=false \
|
||||
--field allow_deletions=false \
|
||||
> /dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ Branch protection enabled for ${branch}${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Failed to set protection for ${branch}${NC}"
|
||||
echo "This might be because:"
|
||||
echo " - You don't have admin permissions on the repository"
|
||||
echo " - The branch doesn't exist yet"
|
||||
echo " - GitHub API rate limits"
|
||||
fi
|
||||
}
|
||||
|
||||
# Create main branch protection (Production)
|
||||
echo -e "${GREEN}Setting up main branch protection (Production deployment control)${NC}"
|
||||
create_branch_protection "main" "Production deployment"
|
||||
|
||||
echo ""
|
||||
|
||||
# Create staging branch protection (Optional)
|
||||
echo -e "${YELLOW}Do you want to protect the staging branch too? (y/n)${NC}"
|
||||
read -r setup_staging
|
||||
|
||||
if [[ $setup_staging =~ ^[Yy]$ ]]; then
|
||||
create_branch_protection "staging" "Staging deployment"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Create development branch if it doesn't exist
|
||||
echo -e "${GREEN}Ensuring development branch exists...${NC}"
|
||||
git show-ref --verify --quiet refs/heads/development
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ Development branch already exists${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}📝 Creating development branch...${NC}"
|
||||
git checkout -b development 2>/dev/null || git checkout development
|
||||
git push -u origin development
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Push staging branch if it doesn't exist on remote
|
||||
echo -e "${GREEN}Ensuring staging branch exists on remote...${NC}"
|
||||
if git ls-remote --heads origin staging | grep -q staging; then
|
||||
echo -e "${GREEN}✅ Staging branch already exists on remote${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}📝 Pushing staging branch to remote...${NC}"
|
||||
git push -u origin staging
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Set default branch to development
|
||||
echo -e "${YELLOW}Do you want to set 'development' as the default branch for new PRs? (y/n)${NC}"
|
||||
read -r set_default
|
||||
|
||||
if [[ $set_default =~ ^[Yy]$ ]]; then
|
||||
gh api repos/${REPO_OWNER}/${REPO_NAME} \
|
||||
--method PATCH \
|
||||
--field default_branch='development' \
|
||||
> /dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ Default branch set to development${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Failed to set default branch${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 Branch protection setup complete!${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Summary of your deployment control setup:${NC}"
|
||||
echo "📦 main branch → Protected, auto-deploys to Railway production"
|
||||
echo "🧪 staging branch → ${setup_staging:+Protected, }deploys to Railway staging"
|
||||
echo "🛠️ development → Unprotected, no automatic deployment"
|
||||
echo ""
|
||||
echo -e "${GREEN}Next steps:${NC}"
|
||||
echo "1. Configure Railway to deploy only from 'main' branch"
|
||||
echo "2. Optionally create staging Railway service for 'staging' branch"
|
||||
echo "3. Always work on 'development' branch for new features"
|
||||
echo "4. Use Pull Requests to merge: development → staging → main"
|
||||
echo ""
|
||||
echo -e "${YELLOW}To complete Railway configuration:${NC}"
|
||||
echo "1. Go to your Railway dashboard"
|
||||
echo "2. In your service settings, set 'Source Repo' branch to 'main'"
|
||||
echo "3. Enable 'Auto Deploy' only for the main branch"
|
||||
echo "4. For staging, create a separate service connected to 'staging' branch"
|
||||
@ -1,120 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Setup Git Hooks for Auto-Documentation Updates
|
||||
|
||||
PROJECT_ROOT=$(pwd)
|
||||
GIT_HOOKS_DIR="$PROJECT_ROOT/.git/hooks"
|
||||
SCRIPTS_DIR="$PROJECT_ROOT/scripts"
|
||||
|
||||
echo "Setting up git hooks for auto-documentation updates..."
|
||||
|
||||
# Create post-commit hook
|
||||
cat > "$GIT_HOOKS_DIR/post-commit" << 'EOF'
|
||||
#!/bin/bash
|
||||
# Auto-update documentation after successful commits
|
||||
|
||||
PROJECT_ROOT=$(git rev-parse --show-toplevel)
|
||||
SCRIPTS_DIR="$PROJECT_ROOT/scripts"
|
||||
AUTO_UPDATE_SCRIPT="$SCRIPTS_DIR/auto_update_docs.py"
|
||||
|
||||
# Check if the auto-update script exists
|
||||
if [ -f "$AUTO_UPDATE_SCRIPT" ]; then
|
||||
echo "Auto-updating documentation after commit..."
|
||||
python3 "$AUTO_UPDATE_SCRIPT" "$PROJECT_ROOT"
|
||||
|
||||
# Check if any documentation was updated
|
||||
if [ -f "$PROJECT_ROOT/docs_update_summary.txt" ]; then
|
||||
echo "Documentation auto-update completed. Check docs_update_summary.txt for details."
|
||||
|
||||
# Optionally auto-commit documentation updates
|
||||
# Uncomment the lines below if you want documentation updates to be auto-committed
|
||||
# git add *.md docs/ CLAUDE.md README.md docs_update_summary.txt
|
||||
# git commit -m "📚 Auto-update documentation after recent changes"
|
||||
fi
|
||||
else
|
||||
echo "Auto-update script not found at $AUTO_UPDATE_SCRIPT"
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Make post-commit hook executable
|
||||
chmod +x "$GIT_HOOKS_DIR/post-commit"
|
||||
|
||||
# Create pre-push hook to ensure documentation is up to date
|
||||
cat > "$GIT_HOOKS_DIR/pre-push" << 'EOF'
|
||||
#!/bin/bash
|
||||
# Ensure documentation is up to date before pushing
|
||||
|
||||
PROJECT_ROOT=$(git rev-parse --show-toplevel)
|
||||
SCRIPTS_DIR="$PROJECT_ROOT/scripts"
|
||||
AUTO_UPDATE_SCRIPT="$SCRIPTS_DIR/auto_update_docs.py"
|
||||
|
||||
echo "Checking documentation status before push..."
|
||||
|
||||
# Run documentation update check
|
||||
if [ -f "$AUTO_UPDATE_SCRIPT" ]; then
|
||||
python3 "$AUTO_UPDATE_SCRIPT" "$PROJECT_ROOT"
|
||||
|
||||
# Check if any updates were made
|
||||
if git diff --quiet; then
|
||||
echo "Documentation is up to date."
|
||||
else
|
||||
echo "Documentation updates were generated. Please review and commit them before pushing."
|
||||
echo "Modified files:"
|
||||
git diff --name-only
|
||||
echo ""
|
||||
echo "To commit documentation updates:"
|
||||
echo " git add ."
|
||||
echo " git commit -m '📚 Update documentation'"
|
||||
echo " git push"
|
||||
|
||||
# Uncomment to block push until docs are committed
|
||||
# exit 1
|
||||
fi
|
||||
else
|
||||
echo "Auto-update script not found. Proceeding with push..."
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Make pre-push hook executable
|
||||
chmod +x "$GIT_HOOKS_DIR/pre-push"
|
||||
|
||||
# Create a manual trigger script
|
||||
cat > "$SCRIPTS_DIR/update_docs_manual.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
# Manual trigger for documentation updates
|
||||
|
||||
PROJECT_ROOT=$(git rev-parse --show-toplevel)
|
||||
SCRIPTS_DIR="$PROJECT_ROOT/scripts"
|
||||
AUTO_UPDATE_SCRIPT="$SCRIPTS_DIR/auto_update_docs.py"
|
||||
|
||||
echo "Manually triggering documentation update..."
|
||||
|
||||
if [ -f "$AUTO_UPDATE_SCRIPT" ]; then
|
||||
python3 "$AUTO_UPDATE_SCRIPT" "$PROJECT_ROOT"
|
||||
|
||||
if [ -f "$PROJECT_ROOT/docs_update_summary.txt" ]; then
|
||||
echo ""
|
||||
echo "Documentation update completed!"
|
||||
echo "Summary saved to: docs_update_summary.txt"
|
||||
echo ""
|
||||
echo "To commit the updates:"
|
||||
echo " git add ."
|
||||
echo " git commit -m '📚 Manual documentation update'"
|
||||
fi
|
||||
else
|
||||
echo "Error: Auto-update script not found at $AUTO_UPDATE_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
chmod +x "$SCRIPTS_DIR/update_docs_manual.sh"
|
||||
|
||||
echo "Git hooks setup completed!"
|
||||
echo ""
|
||||
echo "Created hooks:"
|
||||
echo " - post-commit: Auto-updates docs after each commit"
|
||||
echo " - pre-push: Checks docs before pushing"
|
||||
echo ""
|
||||
echo "Created scripts:"
|
||||
echo " - $SCRIPTS_DIR/update_docs_manual.sh: Manual documentation update trigger"
|
||||
echo ""
|
||||
echo "To disable auto-updates, remove or rename the hooks in .git/hooks/"
|
||||
@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Manual trigger for documentation updates
|
||||
|
||||
PROJECT_ROOT=$(git rev-parse --show-toplevel)
|
||||
SCRIPTS_DIR="$PROJECT_ROOT/scripts"
|
||||
AUTO_UPDATE_SCRIPT="$SCRIPTS_DIR/auto_update_docs.py"
|
||||
|
||||
echo "Manually triggering documentation update..."
|
||||
|
||||
if [ -f "$AUTO_UPDATE_SCRIPT" ]; then
|
||||
python3 "$AUTO_UPDATE_SCRIPT" "$PROJECT_ROOT"
|
||||
|
||||
if [ -f "$PROJECT_ROOT/docs_update_summary.txt" ]; then
|
||||
echo ""
|
||||
echo "Documentation update completed!"
|
||||
echo "Summary saved to: docs_update_summary.txt"
|
||||
echo ""
|
||||
echo "To commit the updates:"
|
||||
echo " git add ."
|
||||
echo " git commit -m '📚 Manual documentation update'"
|
||||
fi
|
||||
else
|
||||
echo "Error: Auto-update script not found at $AUTO_UPDATE_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Dokploy startup script
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
echo "🚀 Starting Quantum Tasks AI on Dokploy"
|
||||
echo "======================================="
|
||||
|
||||
# Run database migrations
|
||||
echo "📄 Running database migrations..."
|
||||
DJANGO_SETTINGS_MODULE=netcop_hub.production_settings python manage.py migrate --noinput
|
||||
|
||||
# Create cache table if needed
|
||||
echo "🗄️ Ensuring cache table exists..."
|
||||
DJANGO_SETTINGS_MODULE=netcop_hub.production_settings python manage.py createcachetable || true
|
||||
|
||||
# Check if we can access the database
|
||||
echo "🔍 Testing database connection..."
|
||||
DJANGO_SETTINGS_MODULE=netcop_hub.production_settings python manage.py check --database default
|
||||
|
||||
# Start the application
|
||||
echo "🌐 Starting gunicorn server on port 3000..."
|
||||
echo "Health check endpoint: /health/"
|
||||
echo "🔒 SSL redirect: $SECURE_SSL_REDIRECT"
|
||||
echo "🌐 Allowed hosts: $ALLOWED_HOSTS"
|
||||
echo "======================================="
|
||||
|
||||
DJANGO_SETTINGS_MODULE=netcop_hub.production_settings exec gunicorn netcop_hub.wsgi:application
|
||||
--bind 0.0.0.0:3000 \
|
||||
--workers 2 \
|
||||
--timeout 120 \
|
||||
--max-requests 1000 \
|
||||
--preload \
|
||||
--log-level info \
|
||||
--access-logfile - \
|
||||
--error-logfile -
|
||||
13
start.sh
13
start.sh
@ -1,13 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Start script for Render deployment
|
||||
|
||||
set -o errexit # exit on error
|
||||
|
||||
echo "Running database migrations..."
|
||||
python manage.py migrate
|
||||
|
||||
echo "Creating admin user if needed..."
|
||||
python manage.py reset_admin --password=RenderTemp123! || true
|
||||
|
||||
echo "Starting gunicorn server..."
|
||||
exec gunicorn netcop_hub.wsgi:application --bind 0.0.0.0:$PORT --workers 1 --timeout 60
|
||||
@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
|
||||
# Add the project root to Python path
|
||||
sys.path.insert(0, '/home/amit/projects/quantumtaskai_django')
|
||||
|
||||
# Set Django settings
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'quantumtaskai_hub.settings')
|
||||
django.setup()
|
||||
|
||||
from agent_base.models import BaseAgent
|
||||
|
||||
print("🔍 Checking agents in database:")
|
||||
print("=" * 40)
|
||||
|
||||
agents = BaseAgent.objects.all()
|
||||
if agents:
|
||||
for agent in agents:
|
||||
print(f"✅ {agent.name} ({agent.slug})")
|
||||
print(f" Category: {agent.category}")
|
||||
print(f" Price: {agent.price} AED")
|
||||
print(f" Type: {agent.agent_type}")
|
||||
print(f" Active: {agent.is_active}")
|
||||
print()
|
||||
else:
|
||||
print("❌ No agents found in database")
|
||||
|
||||
print(f"Total agents: {agents.count()}")
|
||||
@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
|
||||
# Add the project root to Python path
|
||||
sys.path.insert(0, '/home/amit/Desktop/quantum_ai')
|
||||
|
||||
# Set Django settings
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'quantumtaskai_hub.settings')
|
||||
django.setup()
|
||||
|
||||
from agent_base.models import BaseAgent
|
||||
from core.views import homepage_view
|
||||
from django.http import HttpRequest
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
|
||||
def test_agent_visibility():
|
||||
print("🧪 Testing Agent System Integration")
|
||||
print("=" * 40)
|
||||
|
||||
# Check agents in database
|
||||
agents = BaseAgent.objects.filter(is_active=True)
|
||||
print(f"✅ Active agents in database: {agents.count()}")
|
||||
|
||||
for agent in agents:
|
||||
print(f" 📋 {agent.name} ({agent.slug})")
|
||||
print(f" Category: {agent.category}")
|
||||
print(f" Price: {agent.price} AED")
|
||||
print(f" Type: {agent.agent_type}")
|
||||
print()
|
||||
|
||||
# Test the homepage view directly
|
||||
print("🧪 Testing Homepage View")
|
||||
print("-" * 20)
|
||||
|
||||
request = HttpRequest()
|
||||
request.method = 'GET'
|
||||
request.user = AnonymousUser()
|
||||
request.META = {'HTTP_HOST': 'testserver'}
|
||||
|
||||
try:
|
||||
response = homepage_view(request)
|
||||
print(f"✅ Homepage view response status: {response.status_code}")
|
||||
|
||||
# Check if the response contains weather agent
|
||||
if hasattr(response, 'content'):
|
||||
content = response.content.decode('utf-8')
|
||||
if 'Weather Reporter' in content:
|
||||
print("✅ Weather Reporter found in homepage HTML")
|
||||
else:
|
||||
print("❌ Weather Reporter not found in homepage HTML")
|
||||
|
||||
if 'Use Now' in content:
|
||||
print("✅ 'Use Now' buttons found")
|
||||
else:
|
||||
print("❌ 'Use Now' buttons not found")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error in homepage view: {e}")
|
||||
|
||||
def check_url_structure():
|
||||
print("\n🧪 Checking URL Structure")
|
||||
print("=" * 40)
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
try:
|
||||
# Test core URLs
|
||||
homepage_url = reverse('core:homepage')
|
||||
print(f"✅ Homepage URL: {homepage_url}")
|
||||
|
||||
marketplace_url = reverse('agent_base:marketplace')
|
||||
print(f"✅ Marketplace URL: {marketplace_url}")
|
||||
|
||||
# Test weather reporter URL
|
||||
weather_url = reverse('weather_reporter:detail')
|
||||
print(f"✅ Weather Reporter URL: {weather_url}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ URL resolution error: {e}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_agent_visibility()
|
||||
check_url_structure()
|
||||
@ -1,74 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
|
||||
# Add the project root to Python path
|
||||
sys.path.insert(0, '/home/amit/projects/quantumtaskai_django')
|
||||
|
||||
# Set Django settings
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'quantumtaskai_hub.settings')
|
||||
django.setup()
|
||||
|
||||
from django.test import Client
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
def test_homepage():
|
||||
print("🧪 Testing Homepage Agent Display")
|
||||
print("=" * 40)
|
||||
|
||||
# Create a test client
|
||||
client = Client()
|
||||
|
||||
# Get homepage
|
||||
response = client.get('/')
|
||||
print(f"✅ Homepage response status: {response.status_code}")
|
||||
|
||||
# Check if agents are in context
|
||||
if 'featured_agents' in response.context:
|
||||
agents = response.context['featured_agents']
|
||||
print(f"✅ Featured agents found: {agents.count()}")
|
||||
|
||||
for agent in agents:
|
||||
print(f" 📋 {agent.name} ({agent.slug}) - {agent.price} AED")
|
||||
else:
|
||||
print("❌ No featured_agents in context")
|
||||
|
||||
# Check if Weather Reporter is in the HTML
|
||||
html_content = response.content.decode('utf-8')
|
||||
if 'Weather Reporter' in html_content:
|
||||
print("✅ Weather Reporter found in HTML")
|
||||
else:
|
||||
print("❌ Weather Reporter not found in HTML")
|
||||
|
||||
if 'Use Now' in html_content:
|
||||
print("✅ 'Use Now' buttons found in HTML")
|
||||
else:
|
||||
print("❌ 'Use Now' buttons not found in HTML")
|
||||
|
||||
def test_agent_direct_access():
|
||||
print("\n🧪 Testing Direct Agent Access")
|
||||
print("=" * 40)
|
||||
|
||||
client = Client()
|
||||
|
||||
# Test direct access to weather reporter
|
||||
response = client.get('/agents/weather-reporter/')
|
||||
print(f"✅ Weather Reporter direct access: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
html_content = response.content.decode('utf-8')
|
||||
if 'Weather Reporter Agent' in html_content:
|
||||
print("✅ Weather Reporter page loads correctly")
|
||||
else:
|
||||
print("❌ Weather Reporter page content issue")
|
||||
elif response.status_code == 302:
|
||||
print(f"✅ Redirected to: {response.url}")
|
||||
else:
|
||||
print(f"❌ Unexpected status code: {response.status_code}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_homepage()
|
||||
test_agent_direct_access()
|
||||
Loading…
Reference in New Issue
Block a user