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
This commit is contained in:
parent
3aa349a63f
commit
ca8a3e8cee
17 changed files with 258 additions and 862 deletions
|
|
@ -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 <https://git.runfoo.run>
|
||||
- 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**: <https://777wolfpack.runfoo.run>
|
||||
- **API Health**: <https://777wolfpack.runfoo.run/api/healthz>
|
||||
- **Forgejo**: <https://git.runfoo.run/malty/ca-grow-ops-manager>
|
||||
- **Forgejo SSH**: ssh://git@localhost:2222/malty/ca-grow-ops-manager.git (from nexus-vector)
|
||||
- **Test Site**: <http://veridian.runfoo.run:8010> (Example)
|
||||
- **Repo**: <https://git.runfoo.run/malty/ca-grow-ops-manager>
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
17
CI-CD.md
17
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
|
||||
```
|
||||
|
||||
|
|
|
|||
633
DEPLOYMENT.md
633
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://<server-ip>: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@<server-host>
|
||||
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
|
||||
|
|
|
|||
11
README.md
11
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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
})
|
||||
});
|
||||
|
|
|
|||
207
deploy.sh
207
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}"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<meta name="apple-mobile-web-app-title" content="Visitor Kiosk" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<link rel="apple-touch-icon" href="/icons/icon-192.png" />
|
||||
<title>777 Wolfpack - Visitor Kiosk</title>
|
||||
<title>Veridian - Visitor Kiosk</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ export default function Layout() {
|
|||
<div className="h-16 flex items-center px-6 border-b border-slate-200 dark:border-slate-800">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-8 h-8 rounded-lg bg-emerald-600 flex items-center justify-center text-white font-bold text-xl italic shadow-lg shadow-emerald-500/20">
|
||||
7
|
||||
V
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold uppercase tracking-widest leading-none">Wolfpack</span>
|
||||
<span className="text-[10px] text-slate-500 font-medium uppercase tracking-tighter leading-none mt-0.5">Terminal v2.0</span>
|
||||
<span className="text-xs font-bold uppercase tracking-widest leading-none">Veridian</span>
|
||||
<span className="text-[10px] text-slate-500 font-medium uppercase tracking-tighter leading-none mt-0.5">Platform v2.0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ export function SplashScreen({ onComplete, duration = 1800 }: SplashScreenProps)
|
|||
style={{ transitionDelay: '100ms' }}
|
||||
>
|
||||
<img
|
||||
src="/assets/logo-777-wolfpack.jpg"
|
||||
alt="777 Wolfpack"
|
||||
src="/assets/logo-veridian.jpg"
|
||||
alt="Veridian"
|
||||
className="w-24 h-24 md:w-32 md:h-32 rounded-2xl shadow-xl"
|
||||
/>
|
||||
|
||||
|
|
@ -84,10 +84,10 @@ export function SplashScreen({ onComplete, duration = 1800 }: SplashScreenProps)
|
|||
`}
|
||||
>
|
||||
<h1 className="text-xl md:text-2xl font-semibold text-primary tracking-tight">
|
||||
777 Wolfpack
|
||||
Veridian
|
||||
</h1>
|
||||
<p className="text-sm text-tertiary mt-1">
|
||||
Grow Operations
|
||||
Cultivation Platform
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -49,18 +49,18 @@ export function Navbar({ onOpenMobileMenu }: NavbarProps) {
|
|||
<Link to="/dashboard" className="flex items-center gap-3 group relative z-50">
|
||||
<div className="relative">
|
||||
<img
|
||||
src="/assets/logo-777-wolfpack.jpg"
|
||||
alt="777 Wolfpack"
|
||||
src="/assets/logo-veridian.jpg"
|
||||
alt="Veridian"
|
||||
className="w-9 h-9 rounded-lg shadow-md ring-1 ring-slate-900/5 group-hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
<div className="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 bg-emerald-500 rounded-full border-2 border-white dark:border-[#050505] animate-pulse" />
|
||||
</div>
|
||||
<div className="hidden sm:block">
|
||||
<h1 className="text-sm font-bold text-slate-900 dark:text-white leading-tight tracking-tighter uppercase italic">
|
||||
777 Wolfpack
|
||||
Veridian
|
||||
</h1>
|
||||
<p className="text-[9px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-[0.3em] leading-none">
|
||||
Operations Terminal
|
||||
Cultivation Platform
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export const VisitorKioskShell = ({ children, onBack, title, subtitle }: Visitor
|
|||
<h3 className="text-4xl sm:text-5xl font-bold text-white drop-shadow-2xl leading-tight">
|
||||
Welcome to <br />
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 to-blue-500 animate-pulse-slow">
|
||||
777 Wolfpack
|
||||
Veridian
|
||||
</span>
|
||||
</h3>
|
||||
<p className="mt-4 text-lg text-slate-300 leading-relaxed">
|
||||
|
|
@ -451,7 +451,7 @@ const VisitorCheckIn = ({ onBack, onSuccess }: VisitorCheckInProps) => {
|
|||
/>
|
||||
<div className="text-sm">
|
||||
<span className="text-slate-700 font-medium">Agreement Required</span>
|
||||
<p className="text-slate-500 text-xs mt-0.5">I agree to the 777 Wolfpack Non-Disclosure Agreement and safety policies.</p>
|
||||
<p className="text-slate-500 text-xs mt-0.5">I agree to the Veridian Non-Disclosure Agreement and safety policies.</p>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ interface BreadcrumbItem {
|
|||
path: string;
|
||||
}
|
||||
|
||||
// Route mapping for 777 Wolfpack System
|
||||
// Route mapping for Veridian Platform
|
||||
const ROUTE_CONFIG: Record<string, { label: string; parent?: string }> = {
|
||||
'/': { 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';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ export default function VisitorBadge({
|
|||
` : ''}
|
||||
</div>
|
||||
<div class="footer">
|
||||
777 Wolfpack • ${checkInDate.toLocaleDateString()}
|
||||
Veridian • ${checkInDate.toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -331,8 +331,8 @@ export default function VisitorBadge({
|
|||
{/* Expiry Warning */}
|
||||
{expiryDate && (
|
||||
<div className={`text-center py-2 rounded-lg text-sm font-medium ${isExpired
|
||||
? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400'
|
||||
: 'bg-amber-50 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400'
|
||||
? 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400'
|
||||
: 'bg-amber-50 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400'
|
||||
}`}>
|
||||
<Calendar size={14} className="inline mr-1" />
|
||||
{isExpired ? 'EXPIRED' : `Expires: ${expiryDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`}
|
||||
|
|
@ -432,10 +432,10 @@ export function BadgePrintQueue({
|
|||
<div
|
||||
key={badge.visitorId}
|
||||
className={`flex items-center justify-between p-3 rounded-lg border ${badge.status === 'done'
|
||||
? 'bg-emerald-50 border-emerald-200 dark:bg-emerald-900/20 dark:border-emerald-800'
|
||||
: badge.status === 'printing'
|
||||
? 'bg-blue-50 border-blue-200 dark:bg-blue-900/20 dark:border-blue-800 animate-pulse'
|
||||
: 'bg-slate-50 border-slate-200 dark:bg-slate-900/50 dark:border-slate-700'
|
||||
? 'bg-emerald-50 border-emerald-200 dark:bg-emerald-900/20 dark:border-emerald-800'
|
||||
: badge.status === 'printing'
|
||||
? 'bg-blue-50 border-blue-200 dark:bg-blue-900/20 dark:border-blue-800 animate-pulse'
|
||||
: 'bg-slate-50 border-slate-200 dark:bg-slate-900/50 dark:border-slate-700'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export default function BadgePage() {
|
|||
<div className="mb-6 text-center">
|
||||
<div className="flex items-center justify-center gap-2 mb-2">
|
||||
<Shield className="text-emerald-500" size={28} />
|
||||
<span className="text-xl font-bold text-white tracking-tight">777 Wolfpack</span>
|
||||
<span className="text-xl font-bold text-white tracking-tight">Veridian</span>
|
||||
</div>
|
||||
<p className="text-slate-500 text-sm">Facility Access Control</p>
|
||||
</div>
|
||||
|
|
@ -272,7 +272,7 @@ export default function BadgePage() {
|
|||
<span>Dashboard</span>
|
||||
</Link>
|
||||
<p className="text-slate-600 text-xs text-center">
|
||||
Digital Badge powered by 777 Wolfpack Grow Ops Manager
|
||||
Digital Badge powered by Veridian Cultivation Platform
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export default function ErrorPage() {
|
|||
|
||||
<div className="pt-6 border-t border-subtle">
|
||||
<p className="text-xs text-tertiary font-mono uppercase tracking-wider">
|
||||
777 Wolfpack Grow Ops Manager
|
||||
Veridian Cultivation Platform
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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() {
|
|||
>
|
||||
<div className="relative group">
|
||||
<img
|
||||
src="/assets/logo-777-wolfpack.jpg"
|
||||
alt="777 Wolfpack"
|
||||
src="/assets/logo-veridian.jpg"
|
||||
alt="Veridian"
|
||||
className="w-24 h-24 rounded-3xl shadow-2xl transition-transform duration-slow ease-out-expo group-hover:scale-105"
|
||||
/>
|
||||
<div className="absolute inset-0 rounded-3xl bg-indigo-500 opacity-0 group-hover:opacity-10 transition-opacity duration-normal blur-xl" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-5xl font-bold tracking-tighter bg-gradient-to-b from-white to-slate-500 bg-clip-text text-transparent">
|
||||
777 WOLFPACK
|
||||
VERIDIAN
|
||||
</h2>
|
||||
<p className="text-slate-500 font-mono text-sm tracking-[0.3em] uppercase">
|
||||
Operations Infrastructure
|
||||
|
|
@ -77,8 +77,8 @@ export default function LoginPage() {
|
|||
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute bottom-12 left-12 text-[10px] font-mono text-slate-700 tracking-tighter uppercase leading-none">
|
||||
777 Wolfpack Operations<br />
|
||||
Grow Ops Manager<br />
|
||||
Veridian Operations<br />
|
||||
Cultivation Platform<br />
|
||||
v1.0.0
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -94,8 +94,8 @@ export default function LoginPage() {
|
|||
<div className="space-y-3">
|
||||
<motion.div variants={itemVariants} className="lg:hidden relative group w-fit mb-8">
|
||||
<img
|
||||
src="/assets/logo-777-wolfpack.jpg"
|
||||
alt="777 Wolfpack"
|
||||
src="/assets/logo-veridian.jpg"
|
||||
alt="Veridian"
|
||||
className="w-12 h-12 rounded-xl shadow-lg transition-transform duration-300 group-hover:scale-105"
|
||||
/>
|
||||
<div className="absolute inset-0 rounded-xl bg-indigo-500 opacity-0 group-hover:opacity-10 transition-opacity blur-lg" />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue