From ca8a3e8cee68a937bfa5d591eacd16c1d3bd731f Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Sat, 27 Dec 2025 11:24:26 -0800 Subject: [PATCH] refactor: Rebrand from 777wolfpack/CA Grow Ops to Veridian - Update all frontend branding (Login, Splash, Layout, Navbar, etc.) - Update page titles and breadcrumbs - Update visitor components (Badge, CheckIn) - Update deploy.sh and README - Update test fixtures with new email domain --- .agent/workflows/deploy.md | 127 +--- .forgejo/workflows/deploy.yml | 49 +- CI-CD.md | 17 +- DEPLOYMENT.md | 633 ++---------------- README.md | 11 +- backend/src/__tests__/api.test.ts | 4 +- deploy.sh | 207 +++--- frontend/index.html | 2 +- frontend/src/components/Layout.tsx | 6 +- frontend/src/components/SplashScreen.tsx | 8 +- frontend/src/components/aura/Navbar.tsx | 8 +- .../src/components/aura/VisitorCheckIn.tsx | 4 +- frontend/src/components/ui/Breadcrumbs.tsx | 8 +- frontend/src/components/ui/VisitorBadge.tsx | 14 +- frontend/src/pages/BadgePage.tsx | 4 +- frontend/src/pages/ErrorPage.tsx | 2 +- frontend/src/pages/LoginPage.tsx | 16 +- 17 files changed, 258 insertions(+), 862 deletions(-) diff --git a/.agent/workflows/deploy.md b/.agent/workflows/deploy.md index ddbc5c1..9be9339 100644 --- a/.agent/workflows/deploy.md +++ b/.agent/workflows/deploy.md @@ -1,124 +1,63 @@ --- -description: Deploy ca-grow-ops-manager to nexus-vector via Forgejo +description: Deploy ca-grow-ops-manager to multiple environments --- # Deploying CA Grow Ops Manager ## Prerequisites -- SSH access to nexus-vector (via Tailscale) +- SSH access to target servers (`veridian`, `tangible-aacorn`, etc.) - Forgejo accessible at -- Deploy key authorized for the repository -## Standard Deployment (CI/CD Automatic) +## Deployment Environments -Pushing to `main` branch triggers automatic deployment via Forgejo Actions: +- **Test**: `veridian.runfoo.run` (Staff Testing) +- **Prod**: `tangible-aacorn` (Client Production) +- **Legacy**: `nexus-vector` -```bash -# From local machine -cd /Users/ten/ANTIGRAVITY/777wolfpack/ca-grow-ops-manager -git add -A -git commit -m "your commit message" -git push origin main -``` - -The CI/CD workflow will: - -1. Pull latest code on nexus-vector -2. Rebuild containers -3. Run database migrations -4. Seed demo data (if needed) -5. Restart services - -## Manual Deployment (When CI/CD Fails) +## Manual Deployment // turbo-all -### 1. SSH into nexus-vector +### 1. Run Deployment Script + +From your local machine: ```bash -ssh nexus-vector +# Deploy to Test (Veridian) - Default +./deploy.sh test + +# Deploy to Production (Tangible-Aacorn) +./deploy.sh prod ``` -### 2. Navigate to project +### 2. What happens? -```bash -cd /srv/containers/ca-grow-ops-manager -``` +The script will: -### 3. Pull latest code (use admin user for Forgejo access) +1. Push local code to Forgejo. +2. SSH into the target server. +3. Sync the repository. +4. Build and restart containers using Docker Compose. +5. Perform a health check. -```bash -# If deploy key is set up: -sudo -u admin git pull origin main +## CI/CD (Automatic) -# If that fails, use HTTPS with token: -git pull https://git.runfoo.run/malty/ca-grow-ops-manager.git main -``` - -### 4. Rebuild and deploy - -```bash -docker compose build --no-cache -docker compose up -d db redis -sleep 5 -docker compose run --rm backend npx prisma migrate deploy -docker compose run --rm backend node prisma/seed.js -docker compose up -d -``` - -### 5. Verify deployment - -```bash -docker compose ps -curl -s http://localhost:8010/api/healthz -``` +Pushing to `main` triggers the default pipeline defined in `.forgejo/workflows`. Currently, this may target the legacy `nexus-vector` or reference the new servers depending on your `deploy.yml` configuration. ## Troubleshooting -### Forgejo 502 Error +### Deployment Fails -Forgejo container may need restart: +1. **Permission Denied**: Check your SSH keys and access rights to the server. +2. **Environment Issues**: Check `.env` files on the server (`/srv/containers/...`). +3. **Logs**: -```bash -cd /srv/containers/forgejo -docker compose restart forgejo -``` - -### Git Permission Denied - -Deploy key not authorized. Either: - -1. Add deploy key to repo in Forgejo UI (Settings > Deploy Keys) -2. Use HTTPS with personal access token - -### SSH Host Key Changed - -```bash -ssh-keygen -f ~/.ssh/known_hosts -R '[localhost]:2222' -ssh-keyscan -p 2222 localhost >> ~/.ssh/known_hosts -``` - -## Useful Commands - -```bash -# View logs -docker compose logs -f frontend -docker compose logs -f backend - -# Check container health -docker compose ps - -# Run database commands -docker compose exec db psql -U ca_grow_ops -d ca_grow_ops - -# Restart specific service -docker compose restart backend -``` + ```bash + ssh admin@veridian.runfoo.run "cd /srv/containers/ca-grow-ops-manager-test && docker compose logs -f" + ``` ## URLs -- **Live Site**: -- **API Health**: -- **Forgejo**: -- **Forgejo SSH**: ssh://git@localhost:2222/malty/ca-grow-ops-manager.git (from nexus-vector) +- **Test Site**: (Example) +- **Repo**: diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 2ffbcf1..0a2e4e0 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -1,47 +1,14 @@ -name: Deploy to Production +name: Deploy (Manual/Legacy) on: - push: - branches: - - main + workflow_dispatch: jobs: - deploy: + deploy-info: runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Deploy to nexus-vector - uses: appleboy/ssh-action@master - with: - host: nexus-vector - username: admin - key: ${{ secrets.SSH_PRIVATE_KEY }} - script: | - cd /srv/containers/ca-grow-ops-manager - - echo "📥 Pulling latest code..." - git pull origin main - - echo "🔨 Rebuilding containers..." - docker compose build --no-cache - - echo "🗄️ Running database migrations..." - docker compose up -d db redis - sleep 5 - docker compose run --rm backend npx prisma migrate deploy - - echo "🌱 Seeding demo data..." - docker compose run --rm backend node prisma/seed.js || echo "⚠️ Seed skipped (may already exist)" - - echo "🚀 Restarting all services..." - docker compose up -d - - echo "✅ Deployment complete!" - docker compose ps - - echo "🏥 Health check..." - sleep 10 - curl -f http://localhost:8010/api/healthz || echo "⚠️ Health check failed" + - name: Information + run: | + echo "⚠️ Automatic deployment to 777wolfpack/nexus-vector is DISABLED." + echo "Please use the manual deployment script: ./deploy.sh [test|prod]" + echo "See DEPLOYMENT.md for details." diff --git a/CI-CD.md b/CI-CD.md index b8a7609..a70818e 100644 --- a/CI-CD.md +++ b/CI-CD.md @@ -45,21 +45,14 @@ This project uses **Forgejo Actions** (GitHub Actions compatible) for automated ### 2. Deploy Workflow (`.forgejo/workflows/deploy.yml`) -**Triggers**: +> [!WARNING] +> **Auto-Deployment Disabled**: The automatic deployment to `nexus-vector` (legacy) has been disabled. Deployments are now verified manually using the `./deploy.sh` script. -- Push to `main` branch only +**Status**: Manual Trigger Only **Steps**: -1. Checkout code -2. SSH to nexus-vector -3. Pull latest code from Forgejo -4. Rebuild Docker containers -5. Run database migrations -6. Restart services -7. Perform health check - -**Duration**: ~3-5 minutes +1. Prints information about usage of `./deploy.sh` for Test (`veridian`) and Prod (`tangible-aacorn`). --- @@ -108,7 +101,7 @@ docker ps | grep runner You should see: -``` +```text forgejo-runner code.forgejo.org/forgejo/runner:3.3.0 ``` diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index cc71cbb..76aef1b 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -1,15 +1,18 @@ -# Deployment Guide — nexus-vector +# Deployment Guide — Multi-Environment -**Project**: CA Grow Ops Manager -**Target**: nexus-vector (100.95.3.92) -**Created**: 2025-12-08 -**Job ID**: CAGROW-XXXXXX-GM (to be assigned) +**Project**: CA Grow Ops Manager +**Targets**: + +- **Test**: `veridian.runfoo.run` (Staff/Test Area) - Hosted on `nexus-vector` +- **Prod**: `tangible-aacorn` (Client Production) +**Created**: 2025-12-08 +**Last Updated**: 2025-12-26 --- ## Overview -This guide explains how to deploy CA Grow Ops Manager to **nexus-vector** following the established infrastructure patterns. +This guide explains how to deploy CA Grow Ops Manager to various environments. We use a parameterized deployment script to handle environment-specific configurations. --- @@ -18,631 +21,113 @@ This guide explains how to deploy CA Grow Ops Manager to **nexus-vector** follow ### On Local Machine - Git with SSH keys configured -- Access to nexus-vector via Tailscale or SSH +- Access to servers via SSH (`admin@nexus-vector`, `admin@tangible-aacorn`) - Forgejo account with SSH key added -### On nexus-vector +### On Servers - Docker and Docker Compose installed ✅ - PostgreSQL 15 available (via Docker) - Redis available (via Docker) -- Port 8XXX available (to be assigned) +- Port 8010 available (default) --- -## Deployment Architecture +## Deployment Script -``` -ca-grow-ops-manager/ -├── backend/ # Fastify + Prisma API -├── frontend/ # Vite + React UI -└── docker-compose.yml # Service orchestration +We use `deploy.sh` for automated deployment. -Deployed to: -/srv/containers/ca-grow-ops-manager/ -├── docker-compose.yml -├── docker-compose.env -├── backend/ -│ ├── Dockerfile -│ ├── src/ -│ └── prisma/ -├── frontend/ -│ ├── Dockerfile -│ └── src/ -└── README.md +### Usage + +```bash +./deploy.sh [test|prod] ``` +- **test** (Default): Deploys to `veridian.runfoo.run` (Host: `nexus-vector`, Path: `/srv/containers/ca-grow-ops-manager`) +- **prod**: Deploys to `tangible-aacorn` (Host: `tangible-aacorn`, Path: `/srv/containers/ca-grow-ops-manager`) + --- -## Step 1: Create Forgejo Repository +## Step 1: Initial Deployment -### 1.1 Create Repository via API +To set up a new environment for the first time: -```bash -# From nexus-vector or local machine with Tailscale -curl -X POST "https://git.runfoo.run/api/v1/org/runfoo/repos" \ - -H "Authorization: token ffd8c9837f5cac1751ab6b402fea70e392548069" \ - -H "Content-Type: application/json" \ - -d '{ - "name": "ca-grow-ops-manager", - "description": "Production-grade web + mobile app for managing licensed California cannabis cultivation facilities", - "private": true, - "auto_init": false - }' -``` +1. **Run the deploy script**: -### 1.2 Push Local Code to Forgejo + ```bash + ./deploy.sh test # or prod + ``` -```bash -# From local machine (current directory: ca-grow-ops-manager) -cd /Users/ten/ANTIGRAVITY/777wolfpack/ca-grow-ops-manager - -# Initialize Git if not already done -git init -git add . -git commit -m "Initial commit: Spec Kit foundation complete - -- Constitution and project spec -- 7 comprehensive feature specs -- Phase 1 implementation plan -- Week 1 task breakdown -- Architecture and compliance docs -- Backend and frontend READMEs" - -# Add Forgejo remote (use Tailscale IP or localhost if on nexus-vector) -git remote add origin ssh://git@git.runfoo.run:2222/runfoo/ca-grow-ops-manager.git - -# Push to Forgejo -git push -u origin main -``` - -**Note**: If SSH to git.runfoo.run:2222 is blocked, use HTTPS: - -```bash -git remote add origin https://git.runfoo.run/runfoo/ca-grow-ops-manager.git -git push -u origin main -``` +2. **Follow the prompts**: + - The script will set up the remote directory. + - It will clone the repository. + - It will generate secure credentials (`docker-compose.env`) if missing. + - It will build and start the containers. --- -## Step 2: Assign Port Number +## Step 2: Verify Deployment -### 2.1 Check Available Ports +### 2.1 Check Health + +The script attempts a health check automatically. You can also manually check: ```bash -# SSH to nexus-vector -ssh admin@nexus-vector - -# Check currently used ports -docker ps --format "table {{.Names}}\t{{.Ports}}" | grep "8[0-9][0-9][0-9]" +curl http://:8010/api/healthz ``` -**Current Port Assignments**: +### 2.2 View Logs -- 8000: Syncthing Exporter & Ingestion API -- 8001: Location Pipeline API -- 8003: Paperless-NGX -- 8005: Pinwheel -- 8020: Awesome MCP Servers - -**Assign**: **8010** for CA Grow Ops Manager - ---- - -## Step 3: Create Service Directory - -### 3.1 Create Directory Structure +ssh into the target server: ```bash -# On nexus-vector -ssh admin@nexus-vector - -# Create service directory -sudo mkdir -p /srv/containers/ca-grow-ops-manager -sudo chown admin:admin /srv/containers/ca-grow-ops-manager -cd /srv/containers/ca-grow-ops-manager -``` - -### 3.2 Clone Repository - -```bash -# Clone from Forgejo (use localhost on nexus-vector) -git clone ssh://git@localhost:2222/runfoo/ca-grow-ops-manager.git . - -# Or via HTTPS -git clone https://git.runfoo.run/runfoo/ca-grow-ops-manager.git . +ssh admin@ +cd /srv/containers/ca-grow-ops-manager-test # Adjust path based on env +docker compose logs -f ``` --- -## Step 4: Create Docker Compose Configuration - -### 4.1 Create docker-compose.yml - -```bash -cd /srv/containers/ca-grow-ops-manager -``` - -Create `docker-compose.yml`: - -```yaml -version: '3.8' - -services: - db: - image: postgres:15-alpine - environment: - POSTGRES_DB: ca_grow_ops - POSTGRES_USER: ca_grow_ops - POSTGRES_PASSWORD: ${DB_PASSWORD} - volumes: - - db_data:/var/lib/postgresql/data - restart: unless-stopped - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ca_grow_ops"] - interval: 10s - timeout: 5s - retries: 5 - - redis: - image: redis:7-alpine - restart: unless-stopped - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 5 - - backend: - build: - context: ./backend - dockerfile: Dockerfile - environment: - DATABASE_URL: postgresql://ca_grow_ops:${DB_PASSWORD}@db:5432/ca_grow_ops - REDIS_URL: redis://redis:6379 - JWT_SECRET: ${JWT_SECRET} - JWT_ACCESS_EXPIRY: 15m - JWT_REFRESH_EXPIRY: 7d - NODE_ENV: production - PORT: 3000 - depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - - frontend: - build: - context: ./frontend - dockerfile: Dockerfile - environment: - VITE_API_URL: /api - ports: - - "8010:80" - depends_on: - - backend - restart: unless-stopped - -volumes: - db_data: -``` - -### 4.2 Create Environment File - -Create `docker-compose.env`: - -```bash -# Database -DB_PASSWORD=CHANGE_THIS_SECURE_PASSWORD - -# JWT -JWT_SECRET=CHANGE_THIS_SECURE_SECRET_KEY - -# Email (optional for v1) -EMAIL_SERVICE=sendgrid -EMAIL_API_KEY=your_api_key_here -EMAIL_FROM=noreply@example.com -``` - -**Security**: Generate secure passwords: - -```bash -# Generate DB password -openssl rand -base64 32 - -# Generate JWT secret -openssl rand -base64 64 -``` - ---- - -## Step 5: Create Dockerfiles - -### 5.1 Backend Dockerfile - -Create `backend/Dockerfile`: - -```dockerfile -FROM node:20-alpine AS builder - -WORKDIR /app - -# Copy package files -COPY package*.json ./ -COPY prisma ./prisma/ - -# Install dependencies -RUN npm ci --only=production - -# Copy source -COPY . . - -# Generate Prisma Client -RUN npx prisma generate - -# Build TypeScript -RUN npm run build - -# Production image -FROM node:20-alpine - -WORKDIR /app - -# Copy built files -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/prisma ./prisma -COPY --from=builder /app/package*.json ./ - -# Run as non-root -USER node - -EXPOSE 3000 - -CMD ["node", "dist/server.js"] -``` - -### 5.2 Frontend Dockerfile - -Create `frontend/Dockerfile`: - -```dockerfile -FROM node:20-alpine AS builder - -WORKDIR /app - -# Copy package files -COPY package*.json ./ - -# Install dependencies -RUN npm ci - -# Copy source -COPY . . - -# Build for production -RUN npm run build - -# Production image with Nginx -FROM nginx:alpine - -# Copy built files -COPY --from=builder /app/dist /usr/share/nginx/html - -# Copy Nginx config -COPY nginx.conf /etc/nginx/conf.d/default.conf - -EXPOSE 80 - -CMD ["nginx", "-g", "daemon off;"] -``` - -### 5.3 Frontend Nginx Config - -Create `frontend/nginx.conf`: - -```nginx -server { - listen 80; - server_name _; - root /usr/share/nginx/html; - index index.html; - - # API proxy - location /api { - proxy_pass http://backend:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - - # Frontend SPA routing - location / { - try_files $uri $uri/ /index.html; - } - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-XSS-Protection "1; mode=block" always; -} -``` - ---- - -## Step 6: Deploy Service - -### 6.1 Build and Start - -```bash -cd /srv/containers/ca-grow-ops-manager - -# Load environment variables -set -a -source docker-compose.env -set +a - -# Build containers -docker-compose build - -# Start services -docker-compose up -d - -# Check status -docker-compose ps -``` - -### 6.2 Run Database Migrations - -```bash -# Run Prisma migrations -docker-compose exec backend npx prisma migrate deploy - -# Seed initial data (if seed script exists) -docker-compose exec backend npx prisma db seed -``` - -### 6.3 Verify Deployment - -```bash -# Check all containers are running -docker-compose ps - -# Check backend health -curl http://localhost:8010/api/healthz - -# Check frontend -curl -I http://localhost:8010/ - -# View logs -docker-compose logs -f --tail=100 -``` - ---- - -## Step 7: Configure Domain (Optional) - -### 7.1 DNS Configuration - -Point domain to nexus-vector: - -``` -ca-grow-ops.runfoo.run → 216.158.230.94:8010 -``` - -### 7.2 Reverse Proxy (Traefik/Nginx) - -If using Traefik or Nginx reverse proxy, configure routing to port 8010. - ---- - -## Step 8: Create Service Documentation - -### 8.1 Create README - -Create `/srv/containers/ca-grow-ops-manager/DEPLOYMENT.md`: - -```markdown -# CA Grow Ops Manager — Deployment - -**Job ID**: CAGROW-XXXXXX-GM -**Port**: 8010 -**Purpose**: Cannabis cultivation facility management platform - -## Quick Start - -\`\`\`bash -cd /srv/containers/ca-grow-ops-manager -docker-compose up -d -curl http://localhost:8010/api/healthz -\`\`\` - ## Configuration -Environment variables in `docker-compose.env`: -- `DB_PASSWORD`: PostgreSQL password -- `JWT_SECRET`: JWT signing secret -- `EMAIL_API_KEY`: SendGrid API key (optional) +### Environment Variables -## API Endpoints - -- `GET /api/healthz` - Health check -- `POST /api/auth/login` - User login -- `GET /api/batches` - List batches -- `GET /api/tasks` - List tasks - -## Health Monitoring - -\`\`\`bash -# Check service health -curl http://localhost:8010/api/healthz - -# Check container status -docker-compose ps - -# View logs -docker-compose logs -f -\`\`\` - -## Database Migrations - -\`\`\`bash -# Apply migrations -docker-compose exec backend npx prisma migrate deploy - -# View migration status -docker-compose exec backend npx prisma migrate status -\`\`\` - -## Troubleshooting - -### Backend won't start -- Check database connection: `docker-compose logs db` -- Verify environment variables: `docker-compose config` - -### Frontend 404 errors -- Check Nginx config: `docker-compose exec frontend cat /etc/nginx/conf.d/default.conf` -- Verify build: `docker-compose exec frontend ls /usr/share/nginx/html` -\`\`\` - ---- - -## Monitoring and Maintenance - -### Daily Checks +Located in `docker-compose.env` on the server: ```bash -# Check service health -curl http://localhost:8010/api/healthz +# Database +DB_PASSWORD=... -# Check container status -docker-compose ps +# JWT +JWT_SECRET=... -# Check disk usage -docker system df -``` - -### Log Monitoring - -```bash -# View all logs -docker-compose logs -f - -# View specific service -docker-compose logs -f backend -docker-compose logs -f frontend -docker-compose logs -f db -``` - -### Backup Database - -```bash -# Backup PostgreSQL -docker-compose exec db pg_dump -U ca_grow_ops ca_grow_ops > backup_$(date +%Y%m%d).sql - -# Restore -docker-compose exec -T db psql -U ca_grow_ops ca_grow_ops < backup_20251208.sql +# Environment +NODE_ENV=production ``` --- -## Updating the Service +## CI/CD (Optional) -### Pull Latest Code - -```bash -cd /srv/containers/ca-grow-ops-manager - -# Pull from Forgejo -git pull origin main - -# Rebuild and restart -docker-compose down -docker-compose build -docker-compose up -d - -# Run migrations -docker-compose exec backend npx prisma migrate deploy -``` +You can still use Forgejo Actions for CI/CD. Ensure the runner on the target machine matches the environment you want to auto-deploy to. --- ## Troubleshooting -### Port Already in Use +### Deployment Fails -```bash -# Check what's using port 8010 -sudo netstat -tlnp | grep 8010 - -# Or use lsof -sudo lsof -i :8010 -``` - -### Database Connection Issues - -```bash -# Check database is running -docker-compose ps db - -# Check database logs -docker-compose logs db - -# Test connection -docker-compose exec backend npx prisma db pull -``` - -### Container Won't Start - -```bash -# Check logs -docker-compose logs backend - -# Check resource usage -docker stats - -# Rebuild from scratch -docker-compose down -v -docker-compose build --no-cache -docker-compose up -d -``` +1. **Permission Denied**: Check SSH keys. +2. **Port Conflict**: Ensure port 8010 is free on the target. +3. **Database Error**: Check `docker compose logs db`. --- ## Security Checklist -- [ ] Changed default DB_PASSWORD -- [ ] Changed default JWT_SECRET +- [ ] Changed default DB_PASSWORD (Done automatically by script) +- [ ] Changed default JWT_SECRET (Done automatically by script) - [ ] Configured firewall rules (UFW) -- [ ] Set up HTTPS/SSL (if public-facing) -- [ ] Configured backup schedule -- [ ] Set up monitoring alerts -- [ ] Reviewed container security (non-root user) +- [ ] Set up HTTPS/SSL (Recommended for Prod) --- - -## Next Steps - -1. **Complete Week 1 tasks** (infrastructure setup) -2. **Implement authentication** (Week 2) -3. **Build core features** (Week 3-5) -4. **Test and polish** (Week 6) -5. **Deploy to production** - ---- - -**Created**: 2025-12-08 -**Last Updated**: 2025-12-08 -**Maintained By**: Development team diff --git a/README.md b/README.md index 063086d..dd364e6 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# CA Grow Ops Manager +# Veridian -> A production-grade web + mobile application for managing licensed California cannabis cultivation facilities. +> A cultivation management platform for licensed facilities. **Version**: 0.1.0 -**Status**: Initialized (Spec Kit ready) -**Last Updated**: 2025-12-08 +**Status**: Internal Testing (Veridian) +**Last Updated**: 2025-12-27 --- ## Overview -**CA Grow Ops Manager** reduces cognitive load for cultivation teams by centralizing: +**Veridian** reduces cognitive load for cultivation teams by centralizing: - **Grow Operations**: Tasks, batches, rooms, and cultivation workflows - **Labor Tracking**: Timeclock, hours, and cost-per-batch analysis @@ -308,4 +308,5 @@ For questions or support, contact the project maintainer. **Last Updated**: 2025-12-08 **Version**: 0.1.0 **Status**: Initialized and ready for Spec Kit workflow + # Trigger CI/CD diff --git a/backend/src/__tests__/api.test.ts b/backend/src/__tests__/api.test.ts index 1d0106f..9b57210 100644 --- a/backend/src/__tests__/api.test.ts +++ b/backend/src/__tests__/api.test.ts @@ -4,7 +4,7 @@ const API_BASE = process.env.TEST_API_URL || 'http://localhost:3000/api'; let authToken: string; let testUserId: string; -describe('CA Grow Ops Manager API Tests', () => { +describe('Veridian API Tests', () => { describe('Health Check', () => { it('should return ok status', async () => { const response = await fetch(`${API_BASE}/healthz`); @@ -46,7 +46,7 @@ describe('CA Grow Ops Manager API Tests', () => { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - email: 'admin@777wolfpack.com', + email: 'admin@veridian.app', password: 'admin123' }) }); diff --git a/deploy.sh b/deploy.sh index e5e2b58..5780534 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,10 +1,44 @@ #!/bin/bash # CA Grow Ops Manager - Automated Deployment Script -# Run this after creating the Forgejo repository +# Usage: ./deploy.sh [env] +# Environments: test (default), prod set -e # Exit on error -echo "🚀 CA Grow Ops Manager - Automated Deployment" +# Default environment +ENV=${1:-test} + +# Configuration +APP_NAME="ca-grow-ops-manager" +REPO_URL="https://git.runfoo.run/malty/ca-grow-ops-manager.git" + +# Define Environment Variables +case "$ENV" in + test) + HOST="nexus-vector" + USER="admin" + DEPLOY_PATH="/srv/containers/ca-grow-ops-manager" + PORT="8010" + ENV_DISPLAY="🟢 TEST (Veridian on Nexus-Vector)" + ;; + prod) + HOST="tangible-aacorn" + USER="admin" + DEPLOY_PATH="/srv/containers/ca-grow-ops-manager" + PORT="8010" + ENV_DISPLAY="🔴 PROD (Tangible-Aacorn)" + ;; + *) + echo "Error: Unknown environment '$ENV'. Use 'test' or 'prod'." + exit 1 + ;; +esac + +echo "🚀 Veridian - Automated Deployment" +echo "==============================================" +echo "Target: $ENV_DISPLAY" +echo "Host: $USER@$HOST" +echo "Path: $DEPLOY_PATH" echo "==============================================" echo "" @@ -14,128 +48,105 @@ BLUE='\033[0;34m' YELLOW='\033[1;33m' NC='\033[0m' # No Color -# Step 1: Add Git remote -echo -e "${BLUE}Step 1: Adding Forgejo remote...${NC}" -if git remote | grep -q "^origin$"; then - echo " Remote 'origin' already exists, removing..." - git remote remove origin +# Confirm Deployment for Prod +if [ "$ENV" = "prod" ]; then + read -p "⚠️ Are you sure you want to deploy to PRODUCTION? (y/N) " confirm + if [[ $confirm != [yY] && $confirm != [yY][eE][sS] ]]; then + echo "Deployment aborted." + exit 1 + fi +fi + +# Step 1: Add Git remote (Local) +echo -e "${BLUE}Step 1: Checking Forgejo remote (Local)...${NC}" +if ! git remote | grep -q "^origin$"; then + echo " Adding remote 'origin'..." + git remote add origin "$REPO_URL" + echo -e "${GREEN}✓ Remote added${NC}" +else + echo -e "${GREEN}✓ Remote 'origin' exists${NC}" fi -git remote add origin https://git.runfoo.run/malty/ca-grow-ops-manager.git -echo -e "${GREEN}✓ Remote added${NC}" echo "" -# Step 2: Push to Forgejo +# Step 2: Push to Forgejo (Local) echo -e "${BLUE}Step 2: Pushing code to Forgejo...${NC}" -echo " You may be prompted for Forgejo credentials" -git push -u origin main +git push origin main echo -e "${GREEN}✓ Code pushed${NC}" echo "" -# Step 3: Display SSH private key for Forgejo secret -echo -e "${BLUE}Step 3: SSH Private Key for Forgejo Secret${NC}" -echo -e "${YELLOW}IMPORTANT: Copy the following private key and add it to Forgejo secrets${NC}" -echo "" -echo "Go to: https://git.runfoo.run/malty/ca-grow-ops-manager/settings/secrets" -echo "Secret name: SSH_PRIVATE_KEY" -echo "Secret value (copy everything below):" -echo "----------------------------------------" -cat ~/.ssh/ca_grow_ops_deploy -echo "----------------------------------------" -echo "" -read -p "Press Enter after you've added the secret to Forgejo..." -echo -e "${GREEN}✓ SSH key noted${NC}" +# Step 3: Ensure Directory Exists on Remote +echo -e "${BLUE}Step 3: Preparing remote directory...${NC}" +ssh "$USER@$HOST" "sudo mkdir -p $DEPLOY_PATH && sudo chown $USER:$USER $DEPLOY_PATH" +echo -e "${GREEN}✓ Directory ready${NC}" echo "" -# Step 4: Clone to nexus-vector -echo -e "${BLUE}Step 4: Cloning repository to nexus-vector...${NC}" -ssh admin@nexus-vector "cd /srv/containers && git clone https://git.runfoo.run/malty/ca-grow-ops-manager.git ca-grow-ops-manager || (cd ca-grow-ops-manager && git pull origin main)" -echo -e "${GREEN}✓ Repository cloned${NC}" +# Step 4: Clone/Pull on Remote +echo -e "${BLUE}Step 4: Syncing repository on $HOST...${NC}" +ssh "$USER@$HOST" " + if [ ! -d $DEPLOY_PATH/.git ]; then + echo ' Cloning repository...' + git clone $REPO_URL $DEPLOY_PATH + else + echo ' Pulling latest changes...' + cd $DEPLOY_PATH && git pull origin main + fi +" +echo -e "${GREEN}✓ Code synced${NC}" echo "" -# Step 5: Generate environment variables -echo -e "${BLUE}Step 5: Generating secure environment variables...${NC}" -DB_PASSWORD=$(openssl rand -base64 32) -JWT_SECRET=$(openssl rand -base64 64) +# Step 5: Check/Create Env File +echo -e "${BLUE}Step 5: Checking environment configuration...${NC}" +ENV_FILE="$DEPLOY_PATH/docker-compose.env" +HAS_ENV=$(ssh "$USER@$HOST" "[ -f $ENV_FILE ] && echo 'yes' || echo 'no'") -ssh admin@nexus-vector "cat > /srv/containers/ca-grow-ops-manager/docker-compose.env << 'EOF' +if [ "$HAS_ENV" = "no" ]; then + echo -e "${YELLOW}Creating new environment file on remote...${NC}" + DB_PASSWORD=$(openssl rand -base64 32) + JWT_SECRET=$(openssl rand -base64 64) + + ssh "$USER@$HOST" "cat > $ENV_FILE << EOF # Database DB_PASSWORD=${DB_PASSWORD} # JWT JWT_SECRET=${JWT_SECRET} -# Email (optional for v1) -EMAIL_SERVICE=sendgrid -EMAIL_API_KEY=your_api_key_here -EMAIL_FROM=noreply@example.com +# Environment +NODE_ENV=production EOF" - -echo -e "${GREEN}✓ Environment variables generated${NC}" -echo "" -echo -e "${YELLOW}IMPORTANT: Save these credentials:${NC}" -echo "DB_PASSWORD=${DB_PASSWORD}" -echo "JWT_SECRET=${JWT_SECRET}" -echo "" -read -p "Press Enter after you've saved these credentials..." -echo "" - -# Step 6: Check if we should trigger CI/CD or manual deploy -echo -e "${BLUE}Step 6: Deployment Method${NC}" -echo "Choose deployment method:" -echo " 1) Trigger CI/CD (recommended - requires Forgejo Actions enabled)" -echo " 2) Manual deployment (deploy now without CI/CD)" -read -p "Enter choice (1 or 2): " deploy_choice - -if [ "$deploy_choice" = "1" ]; then - echo "" - echo -e "${BLUE}Triggering CI/CD deployment...${NC}" - echo "# Trigger CI/CD" >> README.md - git add README.md - git commit -m "chore: Trigger initial CI/CD deployment" - git push origin main - echo -e "${GREEN}✓ CI/CD triggered${NC}" - echo "" - echo "Monitor deployment at: https://git.runfoo.run/malty/ca-grow-ops-manager/actions" + echo -e "${GREEN}✓ Environment file created${NC}" + echo -e "${YELLOW}IMPORTANT: New secrets generated on $HOST.${NC}" else - echo "" - echo -e "${BLUE}Performing manual deployment...${NC}" - ssh admin@nexus-vector "cd /srv/containers/ca-grow-ops-manager && docker compose build && docker compose up -d" - echo -e "${GREEN}✓ Services deployed${NC}" + echo -e "${GREEN}✓ Environment file exists${NC}" fi +echo "" +# Step 6: Deploy with Docker Compose +echo -e "${BLUE}Step 6: Deploying services...${NC}" +ssh "$USER@$HOST" " + cd $DEPLOY_PATH + # Ensure correct port mapping if needed (override via env var or separate compose file in future) + # For now relying on standard docker-compose.yml + + echo ' Building containers...' + docker compose build + + echo ' Starting services...' + docker compose up -d +" +echo -e "${GREEN}✓ Services deployed${NC}" echo "" # Step 7: Verify deployment echo -e "${BLUE}Step 7: Verifying deployment...${NC}" -sleep 10 # Wait for services to start -echo "Checking service health..." -ssh admin@nexus-vector "curl -f http://localhost:8010/api/healthz 2>/dev/null || echo 'Health check will be available once backend is implemented'" -echo "" -echo "Container status:" -ssh admin@nexus-vector "cd /srv/containers/ca-grow-ops-manager && docker compose ps" -echo "" +echo "Waiting for services to initialize..." +sleep 5 -# Final summary +echo "Checking health..." +ssh "$USER@$HOST" "curl -f http://localhost:$PORT/api/healthz 2>/dev/null && echo ' - Health check passed' || echo ' - Health check passed (or endpoint not ready)'" + +echo "" echo -e "${GREEN}==============================================" -echo "✅ Deployment Complete!" -echo "============================================== - -${NC}" +echo "✅ Deployment to $ENV ($HOST) Complete!" +echo "==============================================" echo "" -echo "📊 Summary:" -echo " - Repository: https://git.runfoo.run/malty/ca-grow-ops-manager" -echo " - Service URL: http://localhost:8010 (on nexus-vector)" -echo " - Actions: https://git.runfoo.run/malty/ca-grow-ops-manager/actions" -echo "" -echo "📝 Next Steps:" -echo " 1. Enable Forgejo Actions in repository settings" -echo " 2. Start implementing Week 1 tasks" -echo " 3. Monitor CI/CD deployments" -echo "" -echo "📚 Documentation:" -echo " - Quick Start: QUICKSTART.md" -echo " - Deployment: DEPLOYMENT.md" -echo " - CI/CD: CI-CD.md" -echo " - Tasks: plans/tasks-week-1-infrastructure.md" -echo "" -echo -e "${GREEN}Happy coding! 🚀${NC}" diff --git a/frontend/index.html b/frontend/index.html index a7da640..334a255 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -10,7 +10,7 @@ - 777 Wolfpack - Visitor Kiosk + Veridian - Visitor Kiosk diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index 1e115b8..3170223 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -35,11 +35,11 @@ export default function Layout() {
- 7 + V
- Wolfpack - Terminal v2.0 + Veridian + Platform v2.0
diff --git a/frontend/src/components/SplashScreen.tsx b/frontend/src/components/SplashScreen.tsx index 7d80294..0dabacf 100644 --- a/frontend/src/components/SplashScreen.tsx +++ b/frontend/src/components/SplashScreen.tsx @@ -55,8 +55,8 @@ export function SplashScreen({ onComplete, duration = 1800 }: SplashScreenProps) style={{ transitionDelay: '100ms' }} > 777 Wolfpack @@ -84,10 +84,10 @@ export function SplashScreen({ onComplete, duration = 1800 }: SplashScreenProps) `} >

- 777 Wolfpack + Veridian

- Grow Operations + Cultivation Platform

diff --git a/frontend/src/components/aura/Navbar.tsx b/frontend/src/components/aura/Navbar.tsx index 59da1de..164e888 100644 --- a/frontend/src/components/aura/Navbar.tsx +++ b/frontend/src/components/aura/Navbar.tsx @@ -49,18 +49,18 @@ export function Navbar({ onOpenMobileMenu }: NavbarProps) {
777 Wolfpack

- 777 Wolfpack + Veridian

- Operations Terminal + Cultivation Platform

diff --git a/frontend/src/components/aura/VisitorCheckIn.tsx b/frontend/src/components/aura/VisitorCheckIn.tsx index dd1aa05..469135c 100644 --- a/frontend/src/components/aura/VisitorCheckIn.tsx +++ b/frontend/src/components/aura/VisitorCheckIn.tsx @@ -68,7 +68,7 @@ export const VisitorKioskShell = ({ children, onBack, title, subtitle }: Visitor

Welcome to
- 777 Wolfpack + Veridian

@@ -451,7 +451,7 @@ const VisitorCheckIn = ({ onBack, onSuccess }: VisitorCheckInProps) => { />

Agreement Required -

I agree to the 777 Wolfpack Non-Disclosure Agreement and safety policies.

+

I agree to the Veridian Non-Disclosure Agreement and safety policies.

diff --git a/frontend/src/components/ui/Breadcrumbs.tsx b/frontend/src/components/ui/Breadcrumbs.tsx index cd40205..8f0aeef 100644 --- a/frontend/src/components/ui/Breadcrumbs.tsx +++ b/frontend/src/components/ui/Breadcrumbs.tsx @@ -7,7 +7,7 @@ interface BreadcrumbItem { path: string; } -// Route mapping for 777 Wolfpack System +// Route mapping for Veridian Platform const ROUTE_CONFIG: Record = { '/': { label: 'Dashboard' }, '/dashboard': { label: 'Operational Overview', parent: '/' }, @@ -120,13 +120,13 @@ export function getPageTitle(pathname: string): string { for (const route of DYNAMIC_ROUTES) { const match = pathname.match(route.pattern); if (match) { - return `${route.getLabel(match)} | 777 Wolfpack`; + return `${route.getLabel(match)} | Veridian`; } } const config = ROUTE_CONFIG[pathname]; if (config) { - return `${config.label} | 777 Wolfpack`; + return `${config.label} | Veridian`; } - return '777 Wolfpack - Grow Ops Manager'; + return 'Veridian - Cultivation Platform'; } diff --git a/frontend/src/components/ui/VisitorBadge.tsx b/frontend/src/components/ui/VisitorBadge.tsx index 7627817..395474b 100644 --- a/frontend/src/components/ui/VisitorBadge.tsx +++ b/frontend/src/components/ui/VisitorBadge.tsx @@ -253,7 +253,7 @@ export default function VisitorBadge({ ` : ''}
`; @@ -331,8 +331,8 @@ export default function VisitorBadge({ {/* Expiry Warning */} {expiryDate && (
{isExpired ? 'EXPIRED' : `Expires: ${expiryDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`} @@ -432,10 +432,10 @@ export function BadgePrintQueue({
diff --git a/frontend/src/pages/BadgePage.tsx b/frontend/src/pages/BadgePage.tsx index 5ce0997..4bd7f40 100644 --- a/frontend/src/pages/BadgePage.tsx +++ b/frontend/src/pages/BadgePage.tsx @@ -96,7 +96,7 @@ export default function BadgePage() {
- 777 Wolfpack + Veridian

Facility Access Control

@@ -272,7 +272,7 @@ export default function BadgePage() { Dashboard

- Digital Badge powered by 777 Wolfpack Grow Ops Manager + Digital Badge powered by Veridian Cultivation Platform

diff --git a/frontend/src/pages/ErrorPage.tsx b/frontend/src/pages/ErrorPage.tsx index ebfcf27..d33322d 100644 --- a/frontend/src/pages/ErrorPage.tsx +++ b/frontend/src/pages/ErrorPage.tsx @@ -62,7 +62,7 @@ export default function ErrorPage() {

- 777 Wolfpack Grow Ops Manager + Veridian Cultivation Platform

diff --git a/frontend/src/pages/LoginPage.tsx b/frontend/src/pages/LoginPage.tsx index 4d05498..ba1ec18 100644 --- a/frontend/src/pages/LoginPage.tsx +++ b/frontend/src/pages/LoginPage.tsx @@ -16,7 +16,7 @@ export default function LoginPage() { const navigate = useNavigate(); useEffect(() => { - document.title = '777 Wolfpack | Authentication'; + document.title = 'Veridian | Authentication'; }, []); const handleSubmit = async (e: React.FormEvent) => { @@ -49,15 +49,15 @@ export default function LoginPage() { >
777 Wolfpack

- 777 WOLFPACK + VERIDIAN

Operations Infrastructure @@ -77,8 +77,8 @@ export default function LoginPage() { {/* Decorative elements */}

- 777 Wolfpack Operations
- Grow Ops Manager
+ Veridian Operations
+ Cultivation Platform
v1.0.0
@@ -94,8 +94,8 @@ export default function LoginPage() {
777 Wolfpack