Initial commit: Spec Kit foundation complete
Some checks failed
Deploy to Production / deploy (push) Failing after 0s
Test / backend-test (push) Failing after 0s
Test / frontend-test (push) Failing after 0s

- Constitution and project spec (spec.yml)
- 7 comprehensive feature specs (tasks, batches, labor, compliance, inventory, integrations, comms)
- Phase 1 implementation plan (6-week roadmap)
- Week 1 task breakdown (15 concrete tasks)
- Architecture and compliance documentation
- Backend and frontend setup guides
- Deployment guide for nexus-vector
- CI/CD workflows (Forgejo Actions)
- Quick start guide for developers

Project is ready for implementation with:
- Automated testing on every push
- Automatic deployment to nexus-vector on push to main
- Database migrations handled automatically
- Health checks and monitoring

Stack: TypeScript, Fastify, React, Vite, PostgreSQL, Prisma, Docker
This commit is contained in:
fullsizemalt 2025-12-08 23:54:12 -08:00
commit da7729d6e4
23 changed files with 7383 additions and 0 deletions

View file

@ -0,0 +1,44 @@
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
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 "🚀 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"

111
.forgejo/workflows/test.yml Normal file
View file

@ -0,0 +1,111 @@
name: Test
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
jobs:
backend-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15-alpine
env:
POSTGRES_DB: ca_grow_ops_test
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: backend/package-lock.json
- name: Install backend dependencies
working-directory: ./backend
run: npm ci
- name: Generate Prisma Client
working-directory: ./backend
run: npx prisma generate
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/ca_grow_ops_test
- name: Run database migrations
working-directory: ./backend
run: npx prisma migrate deploy
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/ca_grow_ops_test
- name: Run backend tests
working-directory: ./backend
run: npm test
env:
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/ca_grow_ops_test
REDIS_URL: redis://localhost:6379
JWT_SECRET: test_secret_key
NODE_ENV: test
- name: Run backend linter
working-directory: ./backend
run: npm run lint
frontend-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install frontend dependencies
working-directory: ./frontend
run: npm ci
- name: Run frontend tests
working-directory: ./frontend
run: npm test
- name: Run frontend linter
working-directory: ./frontend
run: npm run lint
- name: Build frontend
working-directory: ./frontend
run: npm run build
env:
VITE_API_URL: /api

View file

@ -0,0 +1,232 @@
# CA Grow Ops Manager — Constitution
This document encodes the **non-negotiable principles** that govern the design, architecture, and development of the CA Grow Ops Manager platform.
---
## 1. Mission & Purpose
**CA Grow Ops Manager** exists to **reduce cognitive load** for teams managing licensed California cannabis cultivation facilities by:
- Centralizing grow operations (tasks, batches, rooms)
- Tracking labor and associating costs to batches/rooms
- Supporting compliance-adjacent recordkeeping (while METRC remains the system of record)
- Providing scheduling and team communication tools
- Integrating with environmental monitoring systems
The platform must be **opinionated, simple to use on the floor, and safe for regulated environments**.
---
## 2. Technology Stack
### Backend
- **Language**: TypeScript
- **Runtime**: Node.js
- **Framework**: Express or Fastify
- **Database**: PostgreSQL
- **ORM**: Prisma (or similar typed ORM)
- **Testing**: Unit tests for business logic; integration tests for critical workflows (auth, tasks, time tracking, exports)
### Frontend
- **Language**: TypeScript
- **Framework**: React
- **Build Tool**: Vite or Next.js
- **Component Library**: Accessible primitives (e.g., Radix UI or shadcn-style components)
- **Styling**: Modern CSS-in-JS or utility-first CSS (Tailwind acceptable)
### Mobile
- **Primary**: Web-first, fully usable on tablets
- **Stretch Goal**: React Native or React Native Web / Capacitor-style PWA
- **Requirement**: All critical workflows must be completable on mobile/tablet devices
---
## 3. Architecture Principles
### Modularity & Domain Boundaries
- **Feature-first structure** with clear domain boundaries:
- `CultivationOps` (tasks, batches, rooms)
- `Compliance` (recordkeeping, audit packets)
- `Labor` (timeclock, hours, cost tracking)
- `Inventory` (materials, nutrients, supplies)
- `Integrations` (METRC, environmental monitoring, hardware)
- `Communications` (task comments, notifications, announcements)
### API-First Design
- All features exposed via **typed HTTP/JSON APIs**
- No hidden business logic in the UI
- Clear separation between presentation and domain logic
### Security & Compliance
- **Strict authentication** (JWT or session-based)
- **Role-Based Access Control (RBAC)** with least privilege
- **Audit logs** on all critical changes (batch updates, compliance records, labor edits)
- **Data encryption** at rest and in transit
- **Input validation** and sanitization on all endpoints
### Testing & Quality
- **Unit tests** for all business logic
- **Integration tests** for critical workflows:
- Authentication and authorization
- Task creation and completion
- Time tracking (clock in/out)
- Compliance record exports
- Batch lifecycle transitions
- **Type safety** enforced via TypeScript across frontend and backend
---
## 4. User Experience Principles
### Optimized for the Floor
- **Low-friction daily use** in noisy, physical environments
- **Big tap targets** (minimum 44×44px)
- **Dark mode** as default (with light mode option)
- **Offline-friendly patterns** where feasible (service workers, local caching)
### Workflow Efficiency
- **Every critical workflow completable in ≤ 3 screens**:
- Clock in
- Complete a task
- Log a weight
- Acknowledge an alert
- **"Today / This Week" views** tuned for on-shift workers
- **Minimal cognitive load**: clear visual hierarchy, consistent patterns, predictable navigation
### Accessibility
- **WCAG 2.1 AA compliance** minimum
- **Keyboard navigation** for all interactive elements
- **Screen reader support** for critical workflows
- **High contrast** and readable typography
---
## 5. Governance & Development Workflow
### Spec Kit Loop
Every new feature follows this workflow:
1. **Spec**: Write a feature spec in `specs/` with user stories, requirements, out-of-scope, and acceptance criteria
2. **Plan**: Create an implementation plan breaking down the spec into tasks
3. **Tasks**: Define concrete, actionable tasks with clear acceptance criteria
4. **Implement**: Build, test, and deploy the feature
### Constitution Changes
- Changes that violate this constitution **must not be merged**
- If a change requires violating the constitution, **update the constitution explicitly** with rationale and team consensus
### Code Review Standards
- All code must pass type checking
- All tests must pass
- Security-sensitive changes require additional review
- Breaking changes require migration plans
---
## 6. Data & Privacy
### Data Ownership
- **Facility data belongs to the facility owner**
- Users can export all their data at any time
- Data retention policies must comply with California cannabis regulations
### Privacy
- **Minimal data collection**: only what's necessary for functionality
- **No third-party tracking** without explicit consent
- **Clear privacy policy** and terms of service
---
## 7. Compliance Philosophy
### METRC as System of Record
- **METRC is the authoritative system** for California cannabis track-and-trace
- CA Grow Ops Manager **supports compliance-adjacent workflows** but does not replace METRC
- **Read-only METRC integration** in v1; write integration requires explicit user confirmation and robust error handling
### Audit Readiness
- Platform must support **audit packet generation** (ZIP with CSV/JSON indexes and attached documents)
- Compliance views organized by **month/quarter** with DCC-aligned checklists
- **Immutable audit logs** for critical operations
---
## 8. Extensibility & Integrations
### Integration Strategy
- **Adapter pattern** for external systems (METRC, environmental monitoring, hardware)
- **Explicit configuration** for API keys, rate limits, and permissions
- **Graceful degradation** when integrations are unavailable
- **User confirmation** required before any write operations to external systems
### Hardware Integrations
- **Read-only dashboards** for environmental data (temperature, humidity, VPD)
- **Manual fallback** for all automated data inputs
- **Clear error handling** and retry logic
---
## 9. Performance & Scalability
### Performance Targets
- **Page load**: < 2 seconds on 3G
- **Time to interactive**: < 3 seconds on 3G
- **API response time**: < 200ms for p95
### Scalability
- Architecture must support **multiple facilities** (multi-tenant)
- Database design must support **horizontal scaling**
- **Caching strategy** for frequently accessed data
---
## 10. Documentation
### Required Documentation
- **Architecture diagrams** (system, data flow, trust boundaries)
- **API documentation** (OpenAPI/Swagger)
- **Deployment guides** (local, staging, production)
- **User guides** for each major feature
- **Compliance notes** specific to California cannabis regulations
### Code Documentation
- **TSDoc comments** for all public APIs
- **README files** in each major directory
- **Inline comments** for complex business logic
---
## Amendments
This constitution is a **living document**. Amendments require:
1. Explicit proposal with rationale
2. Team discussion and consensus
3. Update to this document with changelog entry
**Last Updated**: 2025-12-08
**Version**: 1.0.0

402
CI-CD.md Normal file
View file

@ -0,0 +1,402 @@
# CI/CD Setup Guide
**Project**: CA Grow Ops Manager
**Platform**: Forgejo Actions
**Target**: nexus-vector
---
## Overview
This project uses **Forgejo Actions** (GitHub Actions compatible) for automated testing and deployment. The CI/CD pipeline automatically:
1. **Tests** code on every push and pull request
2. **Deploys** to production on push to `main` branch
3. **Runs migrations** automatically
4. **Performs health checks** after deployment
---
## Workflows
### 1. Test Workflow (`.forgejo/workflows/test.yml`)
**Triggers**:
- Push to `main` or `develop` branches
- Pull requests to `main`
**Jobs**:
- **Backend Tests**:
- Spins up PostgreSQL and Redis services
- Runs Prisma migrations
- Executes Jest tests
- Runs ESLint
- **Frontend Tests**:
- Runs Vitest tests
- Runs ESLint
- Builds production bundle
**Duration**: ~5-10 minutes
---
### 2. Deploy Workflow (`.forgejo/workflows/deploy.yml`)
**Triggers**:
- Push to `main` branch 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
---
## Setup Instructions
### Step 1: Add SSH Private Key to Forgejo Secrets
The deployment workflow needs SSH access to nexus-vector.
#### 1.1 Generate SSH Key (if needed)
```bash
# On your local machine or nexus-vector
ssh-keygen -t ed25519 -C "forgejo-deploy" -f ~/.ssh/forgejo_deploy
```
#### 1.2 Add Public Key to nexus-vector
```bash
# Copy public key to nexus-vector
ssh admin@nexus-vector "echo '$(cat ~/.ssh/forgejo_deploy.pub)' >> ~/.ssh/authorized_keys"
# Test connection
ssh -i ~/.ssh/forgejo_deploy admin@nexus-vector "echo 'Connection successful'"
```
#### 1.3 Add Private Key to Forgejo Secrets
1. Navigate to repository: <https://git.runfoo.run/runfoo/ca-grow-ops-manager>
2. Go to **Settings** → **Secrets**
3. Click **Add Secret**
4. Name: `SSH_PRIVATE_KEY`
5. Value: Paste contents of `~/.ssh/forgejo_deploy` (the **private** key)
6. Click **Add Secret**
---
### Step 2: Enable Forgejo Actions
#### 2.1 Check Runner Status
```bash
# On nexus-vector
docker ps | grep runner
```
You should see:
```
forgejo-runner code.forgejo.org/forgejo/runner:3.3.0
```
#### 2.2 Enable Actions in Repository
1. Navigate to: <https://git.runfoo.run/runfoo/ca-grow-ops-manager>
2. Go to **Settings** → **Actions**
3. Enable **Actions** (if not already enabled)
4. Set **Default workflow permissions** to **Read and write**
---
### Step 3: Test the Workflows
#### 3.1 Test Workflow (Manual Trigger)
```bash
# Make a small change and push
cd /Users/ten/ANTIGRAVITY/777wolfpack/ca-grow-ops-manager
echo "# Test CI/CD" >> README.md
git add README.md
git commit -m "test: Trigger CI/CD pipeline"
git push origin main
```
#### 3.2 Monitor Workflow Execution
1. Go to: <https://git.runfoo.run/runfoo/ca-grow-ops-manager/actions>
2. Click on the latest workflow run
3. Watch the logs in real-time
**Expected**:
- ✅ Test workflow completes successfully
- ✅ Deploy workflow starts automatically
- ✅ Deployment completes with health check
---
### Step 4: Verify Deployment
```bash
# SSH to nexus-vector
ssh admin@nexus-vector
# Check service status
cd /srv/containers/ca-grow-ops-manager
docker compose ps
# Check health
curl http://localhost:8010/api/healthz
# View logs
docker compose logs -f --tail=50
```
---
## Workflow Details
### Test Workflow
```yaml
# Runs on: ubuntu-latest
# Services: PostgreSQL 15, Redis 7
# Node.js: 20.x
Backend:
- npm ci
- prisma generate
- prisma migrate deploy
- npm test
- npm run lint
Frontend:
- npm ci
- npm test
- npm run lint
- npm run build
```
### Deploy Workflow
```yaml
# Runs on: ubuntu-latest
# Target: nexus-vector via SSH
Steps:
1. git pull origin main
2. docker compose build --no-cache
3. docker compose up -d db redis
4. docker compose run --rm backend npx prisma migrate deploy
5. docker compose up -d
6. curl http://localhost:8010/api/healthz
```
---
## Troubleshooting
### Workflow Fails: "Permission denied (publickey)"
**Cause**: SSH private key not configured or incorrect
**Solution**:
1. Verify secret exists: Settings → Secrets → `SSH_PRIVATE_KEY`
2. Verify public key is in `~/.ssh/authorized_keys` on nexus-vector
3. Test SSH connection manually
---
### Workflow Fails: "Database migration failed"
**Cause**: Database schema conflict or connection issue
**Solution**:
```bash
# SSH to nexus-vector
ssh admin@nexus-vector
cd /srv/containers/ca-grow-ops-manager
# Check database status
docker compose logs db
# Reset database (⚠️ DESTRUCTIVE)
docker compose down -v
docker compose up -d db
docker compose exec backend npx prisma migrate deploy
```
---
### Workflow Fails: "Health check failed"
**Cause**: Service didn't start properly
**Solution**:
```bash
# Check container logs
docker compose logs backend
docker compose logs frontend
# Check container status
docker compose ps
# Restart services
docker compose restart
```
---
### Workflow Stuck: "Waiting for runner"
**Cause**: Forgejo runner is offline or busy
**Solution**:
```bash
# Check runner status
docker ps | grep runner
# Restart runner (if needed)
docker restart forgejo-runner
# Check runner logs
docker logs forgejo-runner
```
---
## Best Practices
### Branch Strategy
- **`main`**: Production branch (auto-deploys)
- **`develop`**: Development branch (tests only)
- **Feature branches**: `feature/task-name` (tests only)
### Workflow
```bash
# 1. Create feature branch
git checkout -b feature/add-authentication
# 2. Make changes and commit
git add .
git commit -m "feat: Add JWT authentication"
# 3. Push and create PR
git push origin feature/add-authentication
# 4. Tests run automatically on PR
# 5. Merge to main → Auto-deploys
```
### Commit Messages
Follow conventional commits:
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation
- `test:` Tests
- `chore:` Maintenance
---
## Monitoring Deployments
### View Deployment History
1. Go to: <https://git.runfoo.run/runfoo/ca-grow-ops-manager/actions>
2. Filter by **Deploy to Production**
3. View logs for each deployment
### Rollback
If deployment fails:
```bash
# SSH to nexus-vector
ssh admin@nexus-vector
cd /srv/containers/ca-grow-ops-manager
# Checkout previous commit
git log --oneline -n 5
git checkout <previous-commit-hash>
# Rebuild and restart
docker compose build
docker compose up -d
```
---
## Advanced Configuration
### Environment-Specific Deployments
To add staging environment:
1. Create `.forgejo/workflows/deploy-staging.yml`
2. Change target branch to `develop`
3. Change deployment path to `/srv/containers/ca-grow-ops-manager-staging`
4. Use different port (e.g., 8011)
### Notifications
Add Slack/Discord notifications:
```yaml
- name: Notify deployment
if: always()
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
-H 'Content-Type: application/json' \
-d '{"text":"Deployment ${{ job.status }}"}'
```
---
## Security Checklist
- [x] SSH private key stored as Forgejo secret
- [x] Secrets not committed to repository
- [x] Workflow runs on trusted runner
- [x] Database migrations run before deployment
- [x] Health check verifies deployment
- [ ] Add deployment approval for production (optional)
- [ ] Add rollback automation (optional)
---
## Next Steps
1. ✅ Set up SSH key and Forgejo secret
2. ✅ Enable Actions in repository
3. ✅ Push code to trigger first deployment
4. ⏭️ Monitor deployment logs
5. ⏭️ Verify service health
6. ⏭️ Set up monitoring alerts (optional)
---
**Created**: 2025-12-08
**Last Updated**: 2025-12-08
**Maintained By**: Development team

648
DEPLOYMENT.md Normal file
View file

@ -0,0 +1,648 @@
# Deployment Guide — nexus-vector
**Project**: CA Grow Ops Manager
**Target**: nexus-vector (100.95.3.92)
**Created**: 2025-12-08
**Job ID**: CAGROW-XXXXXX-GM (to be assigned)
---
## Overview
This guide explains how to deploy CA Grow Ops Manager to **nexus-vector** following the established infrastructure patterns.
---
## Prerequisites
### On Local Machine
- Git with SSH keys configured
- Access to nexus-vector via Tailscale or SSH
- Forgejo account with SSH key added
### On nexus-vector
- Docker and Docker Compose installed ✅
- PostgreSQL 15 available (via Docker)
- Redis available (via Docker)
- Port 8XXX available (to be assigned)
---
## Deployment Architecture
```
ca-grow-ops-manager/
├── backend/ # Fastify + Prisma API
├── frontend/ # Vite + React UI
└── docker-compose.yml # Service orchestration
Deployed to:
/srv/containers/ca-grow-ops-manager/
├── docker-compose.yml
├── docker-compose.env
├── backend/
│ ├── Dockerfile
│ ├── src/
│ └── prisma/
├── frontend/
│ ├── Dockerfile
│ └── src/
└── README.md
```
---
## Step 1: Create Forgejo Repository
### 1.1 Create Repository via API
```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.2 Push Local Code to Forgejo
```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
```
---
## Step 2: Assign Port Number
### 2.1 Check Available Ports
```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]"
```
**Current Port Assignments**:
- 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
```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 .
```
---
## 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)
## 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
```bash
# Check service health
curl http://localhost:8010/api/healthz
# Check container status
docker-compose ps
# 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
```
---
## Updating the Service
### 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
```
---
## Troubleshooting
### Port Already in Use
```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
```
---
## Security Checklist
- [ ] Changed default DB_PASSWORD
- [ ] Changed default JWT_SECRET
- [ ] Configured firewall rules (UFW)
- [ ] Set up HTTPS/SSL (if public-facing)
- [ ] Configured backup schedule
- [ ] Set up monitoring alerts
- [ ] Reviewed container security (non-root user)
---
## 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

383
QUICKSTART.md Normal file
View file

@ -0,0 +1,383 @@
# Quick Start Guide
**CA Grow Ops Manager** — Get up and running in 15 minutes
---
## Prerequisites
Before you begin, ensure you have:
- **Node.js** 20.x LTS ([Download](https://nodejs.org))
- **Docker Desktop** ([Download](https://www.docker.com/products/docker-desktop))
- **Git** ([Download](https://git-scm.com))
- **VS Code** (recommended) ([Download](https://code.visualstudio.com))
---
## Option 1: Docker Compose (Recommended)
The fastest way to get the full stack running:
### 1. Clone the Repository
```bash
git clone <repository-url>
cd ca-grow-ops-manager
```
### 2. Start All Services
```bash
docker-compose up
```
This will start:
- **Backend** on `http://localhost:3000`
- **Frontend** on `http://localhost:5173`
- **PostgreSQL** on `localhost:5432`
- **Redis** on `localhost:6379`
### 3. Open in Browser
Navigate to `http://localhost:5173` to see the frontend.
### 4. Stop Services
```bash
docker-compose down
```
---
## Option 2: Local Development (Without Docker)
For a more traditional development setup:
### 1. Set Up PostgreSQL
Install PostgreSQL 15 locally or use a cloud instance.
Create a database:
```bash
createdb ca_grow_ops_dev
```
### 2. Set Up Backend
```bash
cd backend
npm install
cp .env.example .env
# Edit .env with your database credentials
npx prisma migrate dev
npm run dev
```
Backend will run on `http://localhost:3000`.
### 3. Set Up Frontend
In a new terminal:
```bash
cd frontend
npm install
cp .env.example .env
# Edit .env with your API URL (http://localhost:3000/api)
npm run dev
```
Frontend will run on `http://localhost:5173`.
---
## Project Structure
```
ca-grow-ops-manager/
├── backend/ # Fastify + Prisma backend
│ ├── src/
│ │ ├── modules/ # Feature modules
│ │ ├── shared/ # Shared utilities
│ │ └── server.ts # Entry point
│ ├── prisma/
│ │ └── schema.prisma # Database schema
│ └── package.json
├── frontend/ # Vite + React frontend
│ ├── src/
│ │ ├── pages/ # Page components
│ │ ├── components/ # Reusable components
│ │ └── main.tsx # Entry point
│ └── package.json
├── specs/ # Feature specifications
├── plans/ # Implementation plans
├── docs/ # Documentation
└── docker-compose.yml # Docker Compose config
```
---
## Common Commands
### Backend
```bash
cd backend
# Development
npm run dev # Start dev server with hot reload
npm run build # Build for production
npm start # Start production server
# Database
npx prisma migrate dev # Create and apply migration
npx prisma studio # Open Prisma Studio (DB GUI)
npx prisma generate # Generate Prisma Client
# Testing
npm test # Run tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Generate coverage report
# Code Quality
npm run lint # Run ESLint
npm run format # Format with Prettier
```
### Frontend
```bash
cd frontend
# Development
npm run dev # Start dev server with hot reload
npm run build # Build for production
npm run preview # Preview production build
# Testing
npm test # Run tests
npm run test:ui # Run tests with UI
npm run test:coverage # Generate coverage report
# Code Quality
npm run lint # Run ESLint
npm run format # Format with Prettier
```
### Docker
```bash
# Start all services
docker-compose up
# Start in background
docker-compose up -d
# Stop all services
docker-compose down
# Rebuild containers
docker-compose up --build
# View logs
docker-compose logs -f
# View logs for specific service
docker-compose logs -f backend
```
---
## Environment Variables
### Backend (.env)
```bash
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/ca_grow_ops_dev
# Redis
REDIS_URL=redis://localhost:6379
# JWT
JWT_SECRET=your-secret-key-change-in-production
JWT_ACCESS_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d
# Server
PORT=3000
NODE_ENV=development
# Email (optional for v1)
EMAIL_SERVICE=sendgrid
EMAIL_API_KEY=your-api-key
EMAIL_FROM=noreply@example.com
```
### Frontend (.env)
```bash
# API
VITE_API_URL=http://localhost:3000/api
# Features
VITE_AUTH_ENABLED=true
VITE_METRC_ENABLED=false
```
---
## VS Code Setup
### Recommended Extensions
Install these extensions for the best development experience:
- **ESLint** (`dbaeumer.vscode-eslint`)
- **Prettier** (`esbenp.prettier-vscode`)
- **Prisma** (`Prisma.prisma`)
- **Tailwind CSS IntelliSense** (`bradlc.vscode-tailwindcss`)
- **TypeScript** (built-in)
### Workspace Settings
Create `.vscode/settings.json`:
```json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib",
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
}
}
```
---
## Troubleshooting
### Backend won't start
**Error**: `Cannot connect to database`
**Solution**:
1. Ensure PostgreSQL is running
2. Check `DATABASE_URL` in `.env`
3. Run `npx prisma migrate dev` to apply migrations
---
### Frontend won't start
**Error**: `Cannot connect to API`
**Solution**:
1. Ensure backend is running on `http://localhost:3000`
2. Check `VITE_API_URL` in `.env`
3. Check CORS settings in backend
---
### Docker issues
**Error**: `Port already in use`
**Solution**:
1. Stop conflicting services: `docker-compose down`
2. Check for other processes using ports 3000, 5173, 5432, 6379
3. Kill processes: `lsof -ti:3000 | xargs kill -9`
---
### Prisma issues
**Error**: `Prisma Client not generated`
**Solution**:
```bash
cd backend
npx prisma generate
```
**Error**: `Migration failed`
**Solution**:
1. Check database connection
2. Reset database: `npx prisma migrate reset` (⚠️ deletes all data)
3. Reapply migrations: `npx prisma migrate dev`
---
## Next Steps
### For New Developers
1. **Read the docs**:
- [Constitution](constitution.md) — Project principles
- [Architecture](docs/architecture.md) — System design
- [Compliance Notes](docs/compliance-notes-ca.md) — California regulations
2. **Review the specs**:
- [Tasks and Scheduling](specs/tasks-and-scheduling.md)
- [Batches and Rooms](specs/batches-and-rooms.md)
- [Labor and Hours](specs/labor-and-hours.md)
3. **Check the plan**:
- [Phase 1 Plan](plans/phase-1-foundation.md)
- [Week 1 Tasks](plans/tasks-week-1-infrastructure.md)
4. **Start coding**:
- Pick a task from [Week 1 Tasks](plans/tasks-week-1-infrastructure.md)
- Create a feature branch: `git checkout -b feature/task-001`
- Implement the task
- Write tests
- Submit a PR
### For Project Managers
1. **Review project status**: [STATUS.md](STATUS.md)
2. **Set up project tracking** (GitHub Projects, Linear, etc.)
3. **Assign tasks** to team members
4. **Schedule kickoff meeting**
---
## Getting Help
### Documentation
- [README](README.md) — Project overview
- [Backend README](backend/README.md) — Backend details
- [Frontend README](frontend/README.md) — Frontend details
- [STATUS](STATUS.md) — Current project status
### External Resources
- [Fastify Docs](https://www.fastify.io/docs/latest/)
- [Prisma Docs](https://www.prisma.io/docs)
- [React Docs](https://react.dev)
- [Tailwind Docs](https://tailwindcss.com/docs)
- [shadcn/ui Docs](https://ui.shadcn.com)
---
## License
**Proprietary** — All rights reserved.
---
**Happy Coding!** 🚀

310
README.md Normal file
View file

@ -0,0 +1,310 @@
# CA Grow Ops Manager
> A production-grade web + mobile application for managing licensed California cannabis cultivation facilities.
**Version**: 0.1.0
**Status**: Initialized (Spec Kit ready)
**Last Updated**: 2025-12-08
---
## Overview
**CA Grow Ops Manager** 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
- **Compliance**: Document storage, audit packets, and METRC alignment
- **Inventory**: Materials, nutrients, and supplies with lot tracking
- **Integrations**: Environmental monitoring and hardware dashboards
- **Communications**: Task comments, announcements, and notifications
The platform is **opinionated, simple to use on the floor, and safe for regulated environments**.
---
## Quick Links
- **Constitution**: [constitution.md](constitution.md) — Non-negotiable principles
- **Project Spec**: [spec.yml](spec.yml) — High-level overview
- **Architecture**: [docs/architecture.md](docs/architecture.md) — System design
- **Compliance Notes**: [docs/compliance-notes-ca.md](docs/compliance-notes-ca.md) — California DCC guidance
---
## Tech Stack
### Backend
- **Language**: TypeScript
- **Runtime**: Node.js 20.x
- **Framework**: Express or Fastify
- **Database**: PostgreSQL 15.x
- **ORM**: Prisma 5.x
### Frontend
- **Language**: TypeScript
- **Framework**: React 18.x
- **Build Tool**: Vite or Next.js
- **Components**: Radix UI or shadcn-style
- **Styling**: Tailwind CSS
### Mobile
- **Approach**: Web-first (tablet-optimized)
- **Stretch Goal**: React Native or Capacitor PWA
---
## Project Structure
```
ca-grow-ops-manager/
├── .specify/
│ └── memory/
│ └── constitution.md # Full constitution (Spec Kit memory)
├── specs/ # Feature specifications
│ ├── tasks-and-scheduling.md
│ ├── batches-and-rooms.md
│ ├── labor-and-hours.md
│ ├── compliance-and-docs.md
│ ├── inventory-and-materials.md
│ ├── integrations-and-hardware.md
│ └── communications-and-notifications.md
├── backend/ # Backend application
│ └── README.md
├── frontend/ # Frontend application
│ └── README.md
├── docs/ # Documentation
│ ├── architecture.md
│ └── compliance-notes-ca.md
├── constitution.md # Constitution summary
├── spec.yml # Project specification
└── README.md # This file
```
---
## Feature Specs
All feature specs are located in `specs/` and follow the Spec Kit template:
1. **[Tasks and Scheduling](specs/tasks-and-scheduling.md)**: Room-based task templates, calendar views, and "Today" view for on-shift workers
2. **[Batches and Rooms](specs/batches-and-rooms.md)**: Batch lifecycle management, METRC mapping, weight logging, and yield tracking
3. **[Labor and Hours](specs/labor-and-hours.md)**: Timeclock, wage rates, labor cost per batch, and payroll exports
4. **[Compliance and Documentation](specs/compliance-and-docs.md)**: Document storage, audit packets, and DCC-aligned checklists
5. **[Inventory and Materials](specs/inventory-and-materials.md)**: Materials tracking, lot/serial, restock alerts, and recall support
6. **[Integrations and Hardware](specs/integrations-and-hardware.md)**: Environmental dashboards, METRC connector (Phase 2), and hardware adapters
7. **[Communications and Notifications](specs/communications-and-notifications.md)**: Task comments, @mentions, daily digests, and announcements
---
## Spec Kit Workflow
This project follows the **GitHub Spec Kit** workflow:
1. **Spec** → Write feature specs in `specs/`
2. **Plan** → Create implementation plans
3. **Tasks** → Define concrete, actionable tasks
4. **Implement** → Build, test, and deploy
### Spec Kit Commands (Placeholder)
```bash
# Generate implementation plan from spec
/speckit.plan specs/tasks-and-scheduling.md
# Generate tasks from plan
/speckit.tasks plans/tasks-and-scheduling-plan.md
# Implement tasks
/speckit.implement tasks/tasks-and-scheduling-tasks.md
```
---
## Core Principles
### 1. Opinionated & Simple
- Every critical workflow completable in **≤ 3 screens**
- No feature bloat; focus on daily operations
### 2. Floor-Optimized
- **Big tap targets** (minimum 44×44px)
- **Dark mode** as default
- **Offline-friendly** patterns where feasible
### 3. API-First
- All features exposed via **typed HTTP/JSON APIs**
- No hidden business logic in the UI
### 4. Security & Compliance
- **Strict auth** (JWT-based)
- **RBAC** with least privilege
- **Audit logs** on all critical changes
- **METRC as system of record** (read-only in v1)
### 5. Spec Kit Governance
- Every feature starts as a spec
- Changes must not violate the constitution
- If they need to, update the constitution explicitly
---
## Actors & Roles
- **Owner**: Full access to all features
- **Compliance Manager**: Full compliance, read-only operations
- **Head Grower**: Full cultivation ops, read-only compliance
- **Staff / Trimmers**: Limited access to tasks and timeclock
- **Accountant**: Read-only reports
---
## Domains
1. **CultivationOps**: Tasks, batches, rooms, cultivation workflows
2. **Compliance**: Document storage, audit packets, METRC mapping
3. **Labor**: Timeclock, hours, labor cost analysis
4. **Inventory**: Materials, lot/serial, restock alerts
5. **Integrations**: METRC, environmental monitoring, hardware
6. **Communications**: Task comments, announcements, notifications
---
## Development Phases
### Phase 1 — Foundation (v0.1.0)
- Authentication and RBAC
- Task templates and scheduling
- Basic batch and room management
- Timeclock and labor tracking
- Compliance document storage
### Phase 2 — Operations (v0.2.0)
- Advanced batch lifecycle
- Weight logging and yield analytics
- Inventory management
- Environmental dashboards
- Notification system
### Phase 3 — Integrations (v0.3.0)
- METRC connector (read/write)
- Hardware integrations
- Advanced reporting
- Mobile app (if not PWA)
- Multi-facility support
---
## Out of Scope (v1)
- Direct METRC write integration (read-only mapping only)
- Payroll processing (exports only)
- Financial accounting beyond labor cost tracking
- Customer-facing features (B2C)
- Automated environmental control (read-only dashboards only)
---
## Getting Started
### Prerequisites
- Node.js 20.x LTS
- PostgreSQL 15.x
- npm or yarn
### Backend Setup
```bash
cd backend
npm install
cp .env.example .env
# Edit .env with your database credentials
npx prisma migrate dev
npm run dev
```
See [backend/README.md](backend/README.md) for details.
### Frontend Setup
```bash
cd frontend
npm install
cp .env.example .env
# Edit .env with your API URL
npm run dev
```
See [frontend/README.md](frontend/README.md) for details.
---
## Compliance Philosophy
**METRC is the system of record** for California cannabis track-and-trace. CA Grow Ops Manager supports compliance-adjacent workflows but does not replace METRC.
- **v1**: Read-only METRC tag mapping
- **Phase 2**: METRC connector with explicit user confirmation for writes
See [docs/compliance-notes-ca.md](docs/compliance-notes-ca.md) for details.
---
## Contributing
This project follows the **Spec Kit workflow**:
1. **Spec**: Propose a feature by writing a spec in `specs/`
2. **Review**: Discuss the spec with the team
3. **Plan**: Create an implementation plan
4. **Tasks**: Break down the plan into tasks
5. **Implement**: Build, test, and deploy
All changes must align with the [constitution](constitution.md).
---
## License
**Proprietary** — All rights reserved.
---
## Resources
### Official Documentation
- [California DCC](https://cannabis.ca.gov)
- [METRC California](https://www.metrc.com/california)
- [DCC Regulations](https://cannabis.ca.gov/cannabis-laws/dcc-regulations/)
### Tech Stack
- [Prisma](https://www.prisma.io/docs)
- [React](https://react.dev)
- [PostgreSQL](https://www.postgresql.org/docs)
- [TypeScript](https://www.typescriptlang.org/docs)
---
## Contact
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

265
STATUS.md Normal file
View file

@ -0,0 +1,265 @@
# CA Grow Ops Manager — Project Status
**Last Updated**: 2025-12-08
**Current Phase**: Planning
**Version**: 0.1.0 (Foundation)
---
## Project Overview
**CA Grow Ops Manager** is a production-grade web + mobile application for managing licensed California cannabis cultivation facilities. The platform centralizes grow operations, labor tracking, compliance recordkeeping, scheduling, and team communication.
---
## Current Status: ✅ READY TO BUILD
### Completed Milestones
- ✅ **Project Initialization** (2025-12-08)
- Constitution defined
- Project spec created
- 7 feature specs written
- Architecture documented
- Compliance notes documented
- ✅ **Phase 1 Planning** (2025-12-08)
- Implementation plan created
- Week 1 tasks defined
- Architecture decisions made
- Timeline established (6 weeks)
### Next Milestone
- ⏭️ **Week 1: Infrastructure Setup** (Starting Soon)
- 15 tasks defined
- Estimated: 15.5 hours (2 days for 1 dev, 1 day for 2 devs)
- Deliverable: Working dev environment with Docker Compose
---
## Phase 1 Progress
**Target**: Foundation (v0.1.0)
**Duration**: 6 weeks
**Status**: Planning Complete, Ready to Implement
### Week-by-Week Breakdown
| Week | Focus | Status | Tasks | Estimated Hours |
|------|-------|--------|-------|-----------------|
| 1 | Infrastructure Setup | 📋 Planned | 15 | 15.5 |
| 2 | Authentication & RBAC | 📋 Planned | TBD | ~20 |
| 3 | Core Data Models | 📋 Planned | TBD | ~25 |
| 4 | Frontend UI (Part 1) | 📋 Planned | TBD | ~30 |
| 5 | Frontend UI (Part 2) | 📋 Planned | TBD | ~30 |
| 6 | Testing & Polish | 📋 Planned | TBD | ~25 |
**Total Estimated**: ~145 hours (4-6 weeks for 1 developer, 2-3 weeks for 2 developers)
---
## Architecture Decisions
### Backend
- ✅ **Framework**: Fastify (chosen over Express for performance)
- ✅ **Database**: PostgreSQL 15
- ✅ **ORM**: Prisma
- ✅ **Auth**: JWT (access + refresh tokens)
- ✅ **Testing**: Jest + Supertest
### Frontend
- ✅ **Framework**: Vite + React (chosen over Next.js for simplicity in v1)
- ✅ **Components**: shadcn/ui (Radix + Tailwind)
- ✅ **Routing**: React Router
- ✅ **Testing**: Vitest + React Testing Library
### Infrastructure
- ✅ **Containerization**: Docker + Docker Compose
- ✅ **Development**: Hot reload for backend and frontend
- ✅ **Caching**: Redis (for sessions)
---
## Feature Specs Status
| Feature | Spec Status | Plan Status | Implementation Status |
|---------|-------------|-------------|----------------------|
| Tasks and Scheduling | ✅ Complete | ⏭️ Week 3 | ⬜ Not Started |
| Batches and Rooms | ✅ Complete | ⏭️ Week 3 | ⬜ Not Started |
| Labor and Hours | ✅ Complete | ⏭️ Week 3 | ⬜ Not Started |
| Compliance and Docs | ✅ Complete | ⏭️ Week 3 | ⬜ Not Started |
| Inventory and Materials | ✅ Complete | 📋 Phase 2 | ⬜ Not Started |
| Integrations and Hardware | ✅ Complete | 📋 Phase 2 | ⬜ Not Started |
| Communications and Notifications | ✅ Complete | 📋 Phase 2 | ⬜ Not Started |
---
## Documentation Status
| Document | Status | Location |
|----------|--------|----------|
| Constitution | ✅ Complete | `.specify/memory/constitution.md` |
| Project Spec | ✅ Complete | `spec.yml` |
| Architecture | ✅ Complete | `docs/architecture.md` |
| Compliance Notes | ✅ Complete | `docs/compliance-notes-ca.md` |
| Backend README | ✅ Complete | `backend/README.md` |
| Frontend README | ✅ Complete | `frontend/README.md` |
| Phase 1 Plan | ✅ Complete | `plans/phase-1-foundation.md` |
| Week 1 Tasks | ✅ Complete | `plans/tasks-week-1-infrastructure.md` |
| API Documentation | ⬜ Not Started | TBD (OpenAPI/Swagger) |
| User Guide | ⬜ Not Started | TBD |
| Deployment Guide | ⬜ Not Started | TBD |
---
## Risk Register
| Risk | Severity | Probability | Mitigation | Status |
|------|----------|-------------|------------|--------|
| Scope creep in Phase 1 | High | Medium | Strict adherence to spec; defer to Phase 2 | 🟢 Mitigated |
| Database schema changes | Medium | High | Use Prisma migrations; test thoroughly | 🟢 Mitigated |
| Mobile UX issues | High | Medium | Test on real devices early | 🟡 Monitor |
| Auth vulnerabilities | Critical | Low | Security audit; use established libraries | 🟢 Mitigated |
| Performance with large datasets | Medium | Medium | Pagination + indexes from start | 🟢 Mitigated |
| Team capacity | Medium | Medium | Clear task breakdown; realistic timeline | 🟢 Mitigated |
---
## Success Metrics
### Phase 1 Targets
**Functionality**:
- [ ] All Phase 1 features implemented
- [ ] All acceptance criteria met
- [ ] Zero critical bugs
**Quality**:
- [ ] 80%+ test coverage (backend and frontend)
- [ ] WCAG 2.1 AA compliance
- [ ] Zero security vulnerabilities (critical/high)
**Performance**:
- [ ] API response time < 200ms (p95)
- [ ] Page load time < 2s on 3G
- [ ] Lighthouse score > 90
**Documentation**:
- [ ] API documentation complete
- [ ] User guide complete
- [ ] Deployment guide complete
---
## Team & Roles
**Recommended Team Composition**:
- **1x Backend Developer**: Fastify, Prisma, PostgreSQL, Auth
- **1x Frontend Developer**: React, Tailwind, shadcn/ui, Mobile UX
- **1x Full-Stack Developer** (optional): Can support both sides
- **1x Product Manager** (part-time): Spec review, stakeholder communication
- **1x QA/Tester** (part-time): Testing, bug reporting
**Minimum Viable Team**:
- **1x Full-Stack Developer**: Can complete Phase 1 in 6 weeks solo
---
## Communication & Tracking
**Recommended Tools**:
- **Project Management**: GitHub Projects, Linear, or Jira
- **Communication**: Slack or Discord
- **Documentation**: Notion or Confluence
- **Code Repository**: GitHub or GitLab
- **CI/CD**: GitHub Actions or GitLab CI
**Meeting Cadence** (if team):
- **Daily Standup**: 15 min (async or sync)
- **Weekly Planning**: 1 hour (review tasks, plan next week)
- **Bi-Weekly Demo**: 30 min (show progress to stakeholders)
- **Retrospective**: 1 hour (end of each phase)
---
## Next Actions
### Immediate (This Week)
1. ✅ Review Phase 1 plan with team/stakeholders
2. ✅ Review Week 1 tasks
3. ⏭️ **Start TASK-001**: Initialize Backend Project
4. ⏭️ **Start TASK-006**: Initialize Frontend Project
5. ⏭️ **Start TASK-013**: Create Git Repository
### Short-Term (Next 2 Weeks)
1. Complete Week 1: Infrastructure Setup
2. Complete Week 2: Authentication & RBAC
3. Create Week 2 task breakdown
4. Set up project tracking (GitHub Projects)
### Medium-Term (Next 6 Weeks)
1. Complete Phase 1: Foundation
2. Deploy to staging environment
3. Conduct stakeholder demo
4. Plan Phase 2: Operations
---
## Resources
### Documentation
- [Constitution](.specify/memory/constitution.md)
- [Project Spec](spec.yml)
- [Architecture](docs/architecture.md)
- [Compliance Notes](docs/compliance-notes-ca.md)
### Plans
- [Phase 1 Plan](plans/phase-1-foundation.md)
- [Week 1 Tasks](plans/tasks-week-1-infrastructure.md)
### Specs
- [Tasks and Scheduling](specs/tasks-and-scheduling.md)
- [Batches and Rooms](specs/batches-and-rooms.md)
- [Labor and Hours](specs/labor-and-hours.md)
- [Compliance and Docs](specs/compliance-and-docs.md)
- [Inventory and Materials](specs/inventory-and-materials.md)
- [Integrations and Hardware](specs/integrations-and-hardware.md)
- [Communications and Notifications](specs/communications-and-notifications.md)
---
## Changelog
### 2025-12-08
- ✅ Project initialized with Spec Kit
- ✅ Constitution created
- ✅ 7 feature specs written
- ✅ Architecture documented
- ✅ Phase 1 plan created
- ✅ Week 1 tasks defined
- ✅ Architecture decisions made (Fastify, Vite, shadcn/ui)
---
**Status**: 🟢 ON TRACK
**Next Milestone**: Week 1 Complete (TBD)
**Phase 1 Target**: 6 weeks from start

397
backend/README.md Normal file
View file

@ -0,0 +1,397 @@
# CA Grow Ops Manager — Backend
**Version**: 0.1.0
**Stack**: TypeScript, Node.js, Express/Fastify, PostgreSQL, Prisma
---
## Overview
The backend is a **feature-first, domain-driven** Node.js application that provides typed HTTP/JSON APIs for all platform features. It uses Prisma ORM for type-safe database access and follows strict security and testing practices.
---
## Tech Stack
- **Language**: TypeScript 5.x
- **Runtime**: Node.js 20.x LTS
- **Framework**: Express or Fastify (to be decided during implementation)
- **Database**: PostgreSQL 15.x
- **ORM**: Prisma 5.x
- **Authentication**: JWT (access + refresh tokens)
- **Testing**: Jest + Supertest
- **Validation**: Zod or Joi
- **Logging**: Winston or Pino
- **Email**: SendGrid or Mailgun
---
## Project Structure
```
backend/
├── src/
│ ├── modules/ # Feature-first modules
│ │ ├── cultivation-ops/ # Tasks, batches, rooms
│ │ │ ├── tasks/
│ │ │ │ ├── tasks.controller.ts
│ │ │ │ ├── tasks.service.ts
│ │ │ │ ├── tasks.schema.ts
│ │ │ │ └── tasks.test.ts
│ │ │ ├── batches/
│ │ │ └── rooms/
│ │ ├── compliance/ # Documents, audit packets
│ │ ├── labor/ # Timeclock, hours, reports
│ │ ├── inventory/ # Materials, lots, transactions
│ │ ├── integrations/ # METRC, environmental, hardware
│ │ ├── communications/ # Comments, announcements, notifications
│ │ └── auth/ # Authentication, authorization
│ ├── shared/ # Shared utilities
│ │ ├── middleware/ # Auth, validation, error handling
│ │ ├── utils/ # Helpers, formatters
│ │ └── types/ # Shared TypeScript types
│ ├── prisma/ # Prisma schema and migrations
│ │ ├── schema.prisma
│ │ └── migrations/
│ ├── config/ # Configuration
│ │ ├── database.ts
│ │ ├── auth.ts
│ │ └── email.ts
│ ├── app.ts # Express/Fastify app setup
│ └── server.ts # Server entry point
├── tests/ # Integration tests
│ ├── setup.ts
│ └── integration/
├── .env.example # Environment variables template
├── package.json
├── tsconfig.json
└── README.md
```
---
## Domain Modules
Each module follows this structure:
```
module-name/
├── entity.controller.ts # HTTP route handlers
├── entity.service.ts # Business logic
├── entity.schema.ts # Validation schemas (Zod/Joi)
├── entity.test.ts # Unit tests
└── index.ts # Module exports
```
### Example: Tasks Module
```typescript
// tasks.controller.ts
export const getTasks = async (req, res) => {
const tasks = await tasksService.findAll(req.query);
res.json(tasks);
};
// tasks.service.ts
export const findAll = async (filters) => {
return prisma.task.findMany({ where: filters });
};
// tasks.schema.ts
export const createTaskSchema = z.object({
name: z.string().min(1),
dueDate: z.string().datetime(),
assigneeId: z.string().optional(),
});
```
---
## API Design
### RESTful Conventions
- `GET /api/tasks` - List tasks
- `GET /api/tasks/:id` - Get task detail
- `POST /api/tasks` - Create task
- `PATCH /api/tasks/:id` - Update task
- `DELETE /api/tasks/:id` - Delete task
### Response Format
```json
{
"success": true,
"data": { ... },
"meta": {
"page": 1,
"pageSize": 20,
"total": 100
}
}
```
### Error Format
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input",
"details": [
{ "field": "dueDate", "message": "Required" }
]
}
}
```
---
## Authentication & Authorization
### JWT-Based Auth
- **Access Token**: 15-minute expiry, stored in httpOnly cookie
- **Refresh Token**: 7-day expiry, stored in localStorage
- **Token Payload**: `{ userId, roleId, iat, exp }`
### RBAC (Role-Based Access Control)
Roles:
- `Owner`: Full access
- `Compliance Manager`: Full compliance, read-only operations
- `Head Grower`: Full cultivation ops, read-only compliance
- `Staff`: Limited access to tasks and timeclock
- `Accountant`: Read-only reports
Middleware:
```typescript
export const requireRole = (roles: string[]) => {
return (req, res, next) => {
if (!roles.includes(req.user.role)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
};
```
---
## Database (Prisma)
### Schema Example
```prisma
model Task {
id String @id @default(cuid())
name String
description String?
status TaskStatus @default(PENDING)
dueDate DateTime
assigneeId String?
assignee User? @relation(fields: [assigneeId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum TaskStatus {
PENDING
IN_PROGRESS
COMPLETE
OVERDUE
}
```
### Migrations
```bash
# Create migration
npx prisma migrate dev --name add_tasks_table
# Apply migrations
npx prisma migrate deploy
# Generate Prisma Client
npx prisma generate
```
---
## Testing
### Unit Tests (Jest)
```typescript
describe('TasksService', () => {
it('should create a task', async () => {
const task = await tasksService.create({
name: 'Water plants',
dueDate: new Date(),
});
expect(task.name).toBe('Water plants');
});
});
```
### Integration Tests (Supertest)
```typescript
describe('POST /api/tasks', () => {
it('should create a task', async () => {
const res = await request(app)
.post('/api/tasks')
.send({ name: 'Water plants', dueDate: '2025-12-10' })
.expect(201);
expect(res.body.data.name).toBe('Water plants');
});
});
```
---
## Environment Variables
```bash
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/ca_grow_ops
# Auth
JWT_SECRET=your-secret-key
JWT_ACCESS_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d
# Email
EMAIL_SERVICE=sendgrid
EMAIL_API_KEY=your-api-key
EMAIL_FROM=noreply@example.com
# Integrations
METRC_API_KEY=your-metrc-key
METRC_API_URL=https://api-ca.metrc.com
# Server
PORT=3000
NODE_ENV=development
```
---
## Development Workflow
### Setup
```bash
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Run database migrations
npx prisma migrate dev
# Seed database (optional)
npx prisma db seed
# Start dev server
npm run dev
```
### Scripts
```json
{
"scripts": {
"dev": "tsx watch src/server.ts",
"build": "tsc",
"start": "node dist/server.js",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint src --ext .ts",
"format": "prettier --write src",
"migrate": "prisma migrate dev",
"migrate:deploy": "prisma migrate deploy",
"prisma:generate": "prisma generate"
}
}
```
---
## Security Best Practices
- **Input Validation**: Validate all inputs with Zod/Joi
- **SQL Injection**: Use Prisma parameterized queries
- **XSS**: Sanitize user inputs; use Content Security Policy
- **CSRF**: Use CSRF tokens for state-changing operations
- **Rate Limiting**: Limit API requests per user/IP
- **Audit Logging**: Log all critical operations
---
## Deployment
### Docker
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npx prisma generate
RUN npm run build
CMD ["npm", "start"]
```
### Docker Compose
```yaml
version: '3.8'
services:
backend:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://user:password@db:5432/ca_grow_ops
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: ca_grow_ops
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
```
---
## Next Steps
1. **Choose Framework**: Decide between Express and Fastify
2. **Set Up Project**: Initialize Node.js project with TypeScript
3. **Configure Prisma**: Set up Prisma schema and migrations
4. **Implement Auth**: Build authentication and RBAC
5. **Build Modules**: Implement feature modules per spec
6. **Write Tests**: Unit and integration tests for all modules
7. **Deploy**: Set up CI/CD and deploy to staging
---
## Resources
- [Prisma Documentation](https://www.prisma.io/docs)
- [Express Documentation](https://expressjs.com)
- [Fastify Documentation](https://www.fastify.io)
- [Jest Documentation](https://jestjs.io)
- [TypeScript Documentation](https://www.typescriptlang.org/docs)

41
constitution.md Normal file
View file

@ -0,0 +1,41 @@
# CA Grow Ops Manager — Constitution
> **This is a summary of the full constitution located at `.specify/memory/constitution.md`**
---
## Mission
Reduce cognitive load for teams managing licensed California cannabis cultivation facilities by centralizing operations, labor tracking, compliance recordkeeping, scheduling, and team communication.
## Core Principles
1. **Opinionated & Simple**: Every critical workflow completable in ≤ 3 screens
2. **Floor-Optimized**: Big tap targets, dark mode, offline-friendly
3. **API-First**: All features exposed via typed HTTP/JSON APIs
4. **Security & Compliance**: Strict auth, RBAC, audit logs, METRC as system of record
5. **Spec Kit Workflow**: Every feature starts as spec → plan → tasks → implementation
## Stack
- **Backend**: TypeScript, Node.js, Express/Fastify, PostgreSQL, Prisma
- **Frontend**: TypeScript, React, Vite/Next.js, Radix/shadcn components
- **Mobile**: Web-first (tablet-optimized), React Native as stretch goal
## Domains
- CultivationOps (tasks, batches, rooms)
- Compliance (recordkeeping, audit packets)
- Labor (timeclock, hours, cost tracking)
- Inventory (materials, nutrients, supplies)
- Integrations (METRC, environmental monitoring)
- Communications (notifications, announcements)
## Governance
- Changes must not violate the constitution; if they need to, update the constitution explicitly
- All features follow the Spec Kit loop: spec → plan → tasks → implement
---
**For full details, see** [`.specify/memory/constitution.md`](.specify/memory/constitution.md)

310
docs/architecture.md Normal file
View file

@ -0,0 +1,310 @@
# CA Grow Ops Manager — Architecture
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
CA Grow Ops Manager is a web + mobile application designed to reduce cognitive load for teams managing licensed California cannabis cultivation facilities. The platform centralizes grow operations, labor tracking, compliance recordkeeping, scheduling, and team communication.
---
## System Architecture
### High-Level Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Clients │
├─────────────────────────────────────────────────────────────┤
│ Web App (React + Vite) │ Mobile App (React Native/PWA) │
└─────────────────┬───────────────────────────────────────────┘
│ HTTPS / JSON
┌─────────────────▼───────────────────────────────────────────┐
│ API Gateway / Load Balancer │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────▼───────────────────────────────────────────┐
│ Backend (Node.js + Express/Fastify) │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ CultivationOps│ │ Compliance │ │ Labor │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Inventory │ │ Integrations │ │ Comms │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Auth │ │ Audit Log │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────┬───────────────────────────────────────────┘
│ Prisma ORM
┌─────────────────▼───────────────────────────────────────────┐
│ PostgreSQL Database │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ External Integrations │
├─────────────────────────────────────────────────────────────┤
│ METRC API │ Environmental Monitors │ Email Service │
└─────────────────────────────────────────────────────────────┘
```
---
## Domain Architecture
The backend is organized into **feature-first modules** with clear domain boundaries:
### 1. CultivationOps
- **Responsibilities**: Tasks, batches, rooms, cultivation workflows
- **Key Entities**: `Task`, `TaskTemplate`, `Batch`, `Room`, `WeightLog`
- **APIs**: `/api/tasks`, `/api/batches`, `/api/rooms`
### 2. Compliance
- **Responsibilities**: Document storage, audit packets, METRC mapping
- **Key Entities**: `ComplianceDocument`, `AuditLog`, `MetrcSync`
- **APIs**: `/api/compliance/documents`, `/api/compliance/audit-packet`
### 3. Labor
- **Responsibilities**: Timeclock, hours tracking, labor cost analysis
- **Key Entities**: `TimeEntry`, `Role`, `WageRate`
- **APIs**: `/api/labor/clock-in`, `/api/labor/reports`
### 4. Inventory
- **Responsibilities**: Materials tracking, lot/serial, restock alerts
- **Key Entities**: `InventoryItem`, `InventoryLot`, `InventoryTransaction`
- **APIs**: `/api/inventory/items`, `/api/inventory/transactions`
### 5. Integrations
- **Responsibilities**: External system connections, environmental monitoring
- **Key Entities**: `IntegrationConfig`, `EnvironmentalReading`, `MetrcSync`
- **APIs**: `/api/integrations/environmental`, `/api/integrations/metrc`
### 6. Communications
- **Responsibilities**: Task comments, announcements, notifications
- **Key Entities**: `TaskComment`, `Announcement`, `Notification`
- **APIs**: `/api/communications/comments`, `/api/communications/announcements`
### 7. Auth
- **Responsibilities**: Authentication, authorization, RBAC
- **Key Entities**: `User`, `Role`, `Permission`, `Session`
- **APIs**: `/api/auth/login`, `/api/auth/register`
---
## Data Flow
### Example: Clock In Workflow
```
1. User opens mobile app
2. User taps "Clock In" button
3. Frontend sends POST /api/labor/clock-in with { roomId, notes }
4. Backend validates user session (Auth module)
5. Backend creates TimeEntry record (Labor module)
6. Backend returns TimeEntry with timestamp
7. Frontend displays confirmation and current shift duration
```
### Example: Complete Task Workflow
```
1. User views task in "Today" view
2. User taps "Complete" and adds notes + photo
3. Frontend sends POST /api/tasks/:id/complete with { notes, photo }
4. Backend validates user is assignee (Auth + Tasks modules)
5. Backend updates task status to COMPLETE (Tasks module)
6. Backend creates audit log entry (Audit module)
7. Backend triggers notification to Head Grower (Comms module)
8. Frontend displays success and removes task from "Today" view
```
---
## Trust Boundaries
### Authentication & Authorization
- **Authentication**: JWT-based with refresh tokens
- **Authorization**: Role-Based Access Control (RBAC)
- **Roles**:
- `Owner`: Full access to all features
- `Compliance Manager`: Full access to compliance, read-only for operations
- `Head Grower`: Full access to cultivation ops, read-only for compliance
- `Staff`: Limited access to tasks, timeclock, and assigned batches
- `Accountant`: Read-only access to labor and compliance reports
### Data Access Patterns
| Role | CultivationOps | Compliance | Labor | Inventory | Integrations | Comms |
|------|----------------|------------|-------|-----------|--------------|-------|
| Owner | Full | Full | Full | Full | Full | Full |
| Compliance Manager | Read | Full | Read | Read | Read | Full |
| Head Grower | Full | Read | Read | Full | Read | Full |
| Staff | Limited | None | Limited | Read | Read | Limited |
| Accountant | Read | Read | Read | Read | None | Read |
### External Integrations
- **METRC**: Read-only in v1; write operations (Phase 2) require explicit user confirmation
- **Environmental Monitoring**: Read-only; no write operations
- **Email Service**: Outbound only (notifications, digests)
---
## Security Architecture
### Authentication Flow
```
1. User submits credentials (email + password)
2. Backend validates credentials against hashed password
3. Backend generates JWT access token (15 min expiry) and refresh token (7 day expiry)
4. Frontend stores tokens in httpOnly cookies (access) and localStorage (refresh)
5. Frontend includes access token in Authorization header for all API requests
6. Backend validates token on each request
7. On access token expiry, frontend uses refresh token to get new access token
```
### Data Encryption
- **At Rest**: Database encryption enabled (PostgreSQL TDE)
- **In Transit**: HTTPS/TLS 1.3 for all API communication
- **Sensitive Fields**: API keys, passwords hashed with bcrypt (cost factor 12)
### Audit Logging
All critical operations are logged:
- User authentication (login, logout, failed attempts)
- Batch lifecycle transitions
- Weight logging
- Compliance document uploads/deletions
- Time entry edits
- METRC sync operations
Audit logs are **immutable** and include:
- User ID
- Timestamp
- Action (create, update, delete)
- Entity type and ID
- Metadata (before/after state for updates)
---
## Scalability Considerations
### Database
- **Connection Pooling**: Prisma connection pool (max 10 connections initially)
- **Indexing**: Indexes on frequently queried fields (userId, batchId, roomId, date ranges)
- **Partitioning**: Time-series data (environmental readings, audit logs) partitioned by month
### Caching
- **Application-Level**: Redis for session storage and frequently accessed data
- **CDN**: Static assets (images, CSS, JS) served via CDN
- **API Response Caching**: Cache GET requests for 5 minutes where appropriate
### Horizontal Scaling
- **Stateless Backend**: All session state in Redis; backend can scale horizontally
- **Load Balancer**: Nginx or cloud load balancer for traffic distribution
- **Database Replication**: Read replicas for reporting queries
---
## Deployment Architecture
### Environments
- **Local**: Docker Compose for development
- **Staging**: Cloud-hosted (AWS, GCP, or Azure) with production-like config
- **Production**: Cloud-hosted with auto-scaling, monitoring, and backups
### Infrastructure
```
┌─────────────────────────────────────────────────────────────┐
│ CDN (CloudFlare) │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────▼───────────────────────────────────────────┐
│ Load Balancer (Nginx) │
└─────────────────┬───────────────────────────────────────────┘
┌─────────┴─────────┐
│ │
┌───────▼────────┐ ┌───────▼────────┐
│ Backend (1) │ │ Backend (2) │ (Auto-scaling)
└───────┬────────┘ └───────┬────────┘
│ │
└─────────┬─────────┘
┌─────────┴─────────┐
│ │
┌───────▼────────┐ ┌───────▼────────┐
│ PostgreSQL │ │ Redis │
│ (Primary) │ │ (Sessions) │
└────────────────┘ └────────────────┘
```
---
## Technology Choices
### Backend
- **TypeScript**: Type safety, better tooling, easier refactoring
- **Node.js**: JavaScript ecosystem, async I/O, large community
- **Express/Fastify**: Lightweight, flexible, well-documented
- **Prisma**: Type-safe ORM, migrations, great DX
- **PostgreSQL**: ACID compliance, JSON support, mature ecosystem
### Frontend
- **TypeScript**: Type safety across frontend and backend
- **React**: Component-based, large ecosystem, mobile support (React Native)
- **Vite/Next.js**: Fast builds, SSR support (Next.js), great DX
- **Radix UI/shadcn**: Accessible primitives, customizable, modern design
### Infrastructure
- **Docker**: Consistent environments, easy deployment
- **Nginx**: Reverse proxy, load balancing, static file serving
- **Redis**: Session storage, caching
- **S3-compatible storage**: Document and photo storage
---
## Future Enhancements
- **Multi-Tenancy**: Support multiple facilities per account
- **Real-Time Updates**: WebSockets for live task updates and environmental data
- **Advanced Analytics**: Predictive yield modeling, labor optimization
- **Mobile App**: Native React Native app for iOS/Android
- **Offline Support**: Service workers for offline task completion
---
## References
- [Prisma Documentation](https://www.prisma.io/docs)
- [React Documentation](https://react.dev)
- [PostgreSQL Documentation](https://www.postgresql.org/docs)
- [OWASP Security Guidelines](https://owasp.org)

234
docs/compliance-notes-ca.md Normal file
View file

@ -0,0 +1,234 @@
# California Cannabis Compliance Notes
**Last Updated**: 2025-12-08
**Applies To**: CA Grow Ops Manager v0.1.0
---
## Overview
This document summarizes how CA Grow Ops Manager supports California cannabis cultivation operations while deferring to **METRC as the system of record** for track-and-trace compliance. It provides context on California DCC (Department of Cannabis Control) requirements and how this platform fits into the compliance landscape.
---
## Regulatory Context
### California Department of Cannabis Control (DCC)
The DCC regulates all commercial cannabis activity in California, including cultivation, manufacturing, distribution, testing, and retail. Licensed cultivators must comply with:
- **Track-and-Trace**: METRC (Marijuana Enforcement Tracking Reporting Compliance) is the state-mandated system for tracking cannabis from seed to sale
- **Recordkeeping**: Financial, inventory, labor, and operational records must be maintained and available for inspection
- **Inspections**: DCC and local agencies conduct announced and unannounced inspections
- **Reporting**: Quarterly and annual reports required for license renewal
### METRC (System of Record)
**METRC is the authoritative system** for California cannabis track-and-trace. All licensed cultivators must:
- Tag all plants and batches with METRC-issued RFID tags
- Log all lifecycle events (planting, vegetative, flowering, harvest, destruction) in METRC
- Record all transfers (sales, donations, destruction) in METRC
- Maintain accurate inventory in METRC at all times
**CA Grow Ops Manager does NOT replace METRC.** It supports internal operations and compliance-adjacent recordkeeping while maintaining alignment with METRC data.
---
## How CA Grow Ops Manager Supports Compliance
### 1. Internal Batch Tracking with METRC Mapping
- **Internal Batch IDs**: CA Grow Ops Manager uses internal batch IDs for operational tracking (tasks, weights, labor, photos)
- **METRC Tag Mapping**: Internal batches are mapped to METRC plant/batch tags for cross-reference
- **Read-Only in v1**: METRC tags are stored but not synced; users manually enter tags from METRC
- **Phase 2 (Future)**: METRC connector will sync tags and allow writes with explicit user confirmation
**Compliance Benefit**: Facilities can use intuitive internal IDs (e.g., "Batch #123 - Blue Dream") while maintaining METRC compliance.
### 2. Compliance Document Storage
CA Grow Ops Manager provides a centralized repository for compliance-adjacent records:
- **Monthly Taxes**: Excise, sales, and cultivation tax filings
- **Utility Bills**: SMUD, PG&E, water, gas (required for energy usage reporting)
- **Rent/Lease**: Facility lease agreements
- **Invoices**: CO₂, nutrients, materials, packaging
- **Bills of Sale**: Sales records
- **Payroll Summaries**: Labor cost references (not full payroll data)
- **Hours Tracking**: Exports from the Labor module
- **Licenses and Permits**: Current and historical
- **Inspection Reports**: DCC and local agency inspections
- **SOPs**: Standard Operating Procedures
**Compliance Benefit**: All records organized by month/quarter with DCC-aligned checklists; audit packet generation for inspections.
### 3. Labor and Hours Tracking
California labor laws require detailed recordkeeping:
- **Hours Worked**: Clock in/out timestamps for all employees
- **Wage Rates**: Historical wage rates for each role
- **Labor Costs**: Hours × wage rate for cost analysis
- **Payroll Exports**: CSV exports compatible with payroll systems
**Compliance Benefit**: Meets California labor recordkeeping requirements (4 years minimum); supports cost-per-batch analysis.
### 4. Audit Readiness
CA Grow Ops Manager supports audit preparation:
- **Audit Packet**: ZIP export with all documents and indexes (CSV, JSON) for a date range
- **Compliance Checklists**: Monthly/quarterly checklists based on DCC guidance
- **Immutable Audit Logs**: All critical operations logged with user and timestamp
**Compliance Benefit**: Facilities can generate audit packets in minutes; proactive checklists reduce missing records.
---
## What CA Grow Ops Manager Does NOT Do
### 1. Replace METRC
- **METRC is the system of record** for track-and-trace
- CA Grow Ops Manager does not sync with METRC in v1 (read-only mapping only)
- Phase 2 will add METRC connector with explicit user confirmation for writes
### 2. Process Payroll
- CA Grow Ops Manager tracks hours and wage rates but does not process payroll (taxes, deductions, direct deposit)
- Exports are provided for external payroll systems (ADP, Gusto, QuickBooks)
### 3. File Taxes
- CA Grow Ops Manager stores tax records but does not file taxes
- Facilities must use external accounting systems or CPAs for tax filing
### 4. Guarantee Compliance
- CA Grow Ops Manager is a tool to support compliance workflows
- Facilities are responsible for ensuring all data is accurate and complete
- Consult with legal and compliance professionals for regulatory guidance
---
## DCC Recordkeeping Requirements
Per California Code of Regulations, Title 4, Division 19, licensed cultivators must maintain:
### Financial Records (7 years)
- Bank statements
- Sales invoices and receipts
- Purchase invoices and receipts
- Tax filings (excise, sales, cultivation)
- Payroll records
### Inventory Records (7 years)
- METRC reconciliation reports
- Internal inventory logs
- Transfer manifests
- Destruction records
### Labor Records (4 years minimum)
- Employee hours worked
- Wage rates and payroll summaries
- Workers' compensation records
### Operational Records (7 years)
- Licenses and permits
- Inspection reports
- Standard Operating Procedures (SOPs)
- Pest management logs
- Waste disposal records
---
## DCC Inspection Preparation
### Quarterly Self-Audits (Recommended)
1. **Review METRC Data**: Ensure all plants, batches, and transfers are logged
2. **Check Compliance Documents**: Verify all required documents are uploaded and categorized
3. **Reconcile Inventory**: Physical count vs. METRC vs. internal records
4. **Review Labor Records**: Ensure all hours and wage rates are accurate
5. **Update SOPs**: Ensure SOPs reflect current practices
### Audit Packet Contents
For a DCC inspection, prepare an audit packet with:
- **METRC Reconciliation Report**: Exported from METRC
- **Financial Records**: Invoices, receipts, tax filings for the period
- **Labor Records**: Hours, wage rates, payroll summaries
- **Licenses and Permits**: Current and historical
- **Inspection Reports**: All DCC and local inspections
- **SOPs**: Current versions with change history
- **Inventory Logs**: Internal records aligned with METRC
CA Grow Ops Manager can generate this packet (minus METRC data) in minutes.
---
## METRC Integration Strategy (Phase 2)
### Read Operations (No User Confirmation Required)
- Sync METRC plant/batch tags to internal batches
- Sync inventory data for reconciliation
- Sync transfer data for cross-reference
### Write Operations (User Confirmation Required)
- Create plant tags in METRC
- Update plant stages (vegetative, flowering, harvest)
- Log harvests and weights
- Create packages for transfer
- Log destructions
### Safety Measures
- **Explicit User Confirmation**: Preview changes before writing to METRC
- **Audit Trail**: Log all METRC operations with user and timestamp
- **Rollback**: Attempt rollback on failure; flag for manual review if rollback fails
- **Rate Limiting**: Respect METRC API rate limits; exponential backoff on errors
---
## Official Resources
### California DCC
- **Website**: [cannabis.ca.gov](https://cannabis.ca.gov)
- **Regulations**: [DCC Regulations (Title 4, Division 19)](https://cannabis.ca.gov/cannabis-laws/dcc-regulations/)
- **Compliance Hub**: [DCC Compliance Hub](https://cannabis.ca.gov/licensees/compliance-hub/)
- **Cultivation License**: [Cultivation License Requirements](https://cannabis.ca.gov/applicants/license-types/#cultivation)
### METRC
- **Website**: [metrc.com](https://www.metrc.com)
- **California Guide**: [METRC California User Guide](https://www.metrc.com/california)
- **API Documentation**: [METRC API Docs](https://api-ca.metrc.com/Documentation)
- **Support**: [METRC Support](https://www.metrc.com/support)
### California Labor Laws
- **DIR (Department of Industrial Relations)**: [dir.ca.gov](https://www.dir.ca.gov)
- **Wage and Hour Laws**: [Labor Code Division 2](https://leginfo.legislature.ca.gov/faces/codes_displayexpandedbranch.xhtml?tocCode=LAB&division=2)
---
## Disclaimer
**This document is for informational purposes only and does not constitute legal or compliance advice.** Cannabis regulations are complex and subject to change. Facilities should consult with legal counsel, compliance professionals, and the California DCC for authoritative guidance.
**CA Grow Ops Manager is a tool to support compliance workflows but does not guarantee compliance.** Facilities are responsible for ensuring all data is accurate, complete, and aligned with METRC and DCC requirements.
---
## Changelog
- **2025-12-08**: Initial version for v0.1.0

442
frontend/README.md Normal file
View file

@ -0,0 +1,442 @@
# CA Grow Ops Manager — Frontend
**Version**: 0.1.0
**Stack**: TypeScript, React, Vite/Next.js, Radix UI/shadcn
---
## Overview
The frontend is a **mobile-first, accessible** web application optimized for low-friction daily use in cultivation facilities. It provides intuitive interfaces for tasks, batches, labor tracking, compliance, and team communication.
---
## Tech Stack
- **Language**: TypeScript 5.x
- **Framework**: React 18.x
- **Build Tool**: Vite or Next.js (to be decided during implementation)
- **Component Library**: Radix UI or shadcn-style accessible primitives
- **Styling**: Tailwind CSS or modern CSS-in-JS
- **State Management**: React Context + hooks (Zustand or Redux Toolkit for complex state)
- **Routing**: React Router (Vite) or Next.js App Router
- **Forms**: React Hook Form + Zod validation
- **API Client**: Axios or Fetch with TypeScript types
- **Testing**: Vitest + React Testing Library
---
## Project Structure
### Vite Option
```
frontend/
├── src/
│ ├── app/ # App shell
│ │ ├── App.tsx
│ │ ├── Router.tsx
│ │ └── Layout.tsx
│ ├── pages/ # Page components
│ │ ├── Dashboard.tsx
│ │ ├── Tasks/
│ │ │ ├── TasksPage.tsx
│ │ │ ├── TaskDetail.tsx
│ │ │ └── TodayView.tsx
│ │ ├── Batches/
│ │ ├── Labor/
│ │ ├── Compliance/
│ │ └── Settings/
│ ├── components/ # Reusable components
│ │ ├── ui/ # Base UI components (buttons, inputs, etc.)
│ │ ├── tasks/ # Task-specific components
│ │ ├── batches/
│ │ └── shared/ # Shared components (nav, header, etc.)
│ ├── hooks/ # Custom React hooks
│ │ ├── useAuth.ts
│ │ ├── useTasks.ts
│ │ └── useApi.ts
│ ├── lib/ # Utilities and helpers
│ │ ├── api.ts # API client
│ │ ├── auth.ts # Auth helpers
│ │ └── utils.ts
│ ├── types/ # TypeScript types
│ │ ├── api.ts
│ │ └── models.ts
│ ├── styles/ # Global styles
│ │ ├── index.css
│ │ └── tailwind.css
│ └── main.tsx # Entry point
├── public/ # Static assets
├── .env.example
├── package.json
├── tsconfig.json
├── vite.config.ts
└── README.md
```
### Next.js Option
```
frontend/
├── app/ # Next.js App Router
│ ├── layout.tsx
│ ├── page.tsx # Dashboard
│ ├── tasks/
│ │ ├── page.tsx
│ │ └── [id]/page.tsx
│ ├── batches/
│ ├── labor/
│ └── api/ # API routes (if needed)
├── components/ # Same as Vite
├── hooks/
├── lib/
├── types/
├── styles/
└── public/
```
---
## Design System
### Component Library (Radix UI / shadcn)
Use accessible primitives for:
- **Buttons**: Primary, secondary, destructive
- **Inputs**: Text, number, date, select
- **Dialogs**: Modals, drawers, alerts
- **Dropdowns**: Menus, selects, comboboxes
- **Tabs**: Navigation, content switching
- **Cards**: Content containers
- **Badges**: Status indicators
### Styling (Tailwind CSS)
```css
/* Design tokens */
:root {
--color-primary: #10b981; /* Green for cultivation */
--color-secondary: #3b82f6; /* Blue for actions */
--color-danger: #ef4444; /* Red for alerts */
--color-warning: #f59e0b; /* Orange for warnings */
--color-success: #10b981; /* Green for success */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'Fira Code', monospace;
}
```
### Mobile-First Design
- **Big Tap Targets**: Minimum 44×44px for all interactive elements
- **Dark Mode**: Default dark theme with light mode option
- **Responsive Breakpoints**:
- Mobile: < 640px
- Tablet: 640px - 1024px
- Desktop: > 1024px
---
## Key Features
### 1. Today View (Mobile-Optimized)
```tsx
// TodayView.tsx
export const TodayView = () => {
const { tasks, loading } = useTasks({ dueToday: true });
return (
<div className="p-4 space-y-4">
<h1 className="text-2xl font-bold">Today's Tasks</h1>
{tasks.map(task => (
<TaskCard key={task.id} task={task} />
))}
</div>
);
};
```
### 2. Timeclock Widget
```tsx
// TimeclockWidget.tsx
export const TimeclockWidget = () => {
const { currentShift, clockIn, clockOut } = useTimeclock();
return (
<Card className="p-6">
{currentShift ? (
<div>
<p>Clocked in: {formatTime(currentShift.clockIn)}</p>
<Button onClick={clockOut} size="lg">Clock Out</Button>
</div>
) : (
<Button onClick={clockIn} size="lg">Clock In</Button>
)}
</Card>
);
};
```
### 3. Batch Timeline
```tsx
// BatchTimeline.tsx
export const BatchTimeline = ({ batchId }: { batchId: string }) => {
const { events } = useBatchTimeline(batchId);
return (
<div className="space-y-4">
{events.map(event => (
<TimelineEvent key={event.id} event={event} />
))}
</div>
);
};
```
---
## API Integration
### API Client
```typescript
// lib/api.ts
import axios from 'axios';
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
headers: {
'Content-Type': 'application/json',
},
});
// Add auth token to requests
api.interceptors.request.use(config => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Handle token refresh
api.interceptors.response.use(
response => response,
async error => {
if (error.response?.status === 401) {
// Attempt token refresh
const refreshToken = localStorage.getItem('refreshToken');
if (refreshToken) {
const { data } = await axios.post('/api/auth/refresh', { refreshToken });
localStorage.setItem('accessToken', data.accessToken);
error.config.headers.Authorization = `Bearer ${data.accessToken}`;
return axios(error.config);
}
}
return Promise.reject(error);
}
);
export default api;
```
### Custom Hooks
```typescript
// hooks/useTasks.ts
export const useTasks = (filters?: TaskFilters) => {
const [tasks, setTasks] = useState<Task[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchTasks = async () => {
const { data } = await api.get('/api/tasks', { params: filters });
setTasks(data.data);
setLoading(false);
};
fetchTasks();
}, [filters]);
return { tasks, loading };
};
```
---
## Authentication
### Auth Context
```typescript
// hooks/useAuth.ts
const AuthContext = createContext<AuthContextType | null>(null);
export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [user, setUser] = useState<User | null>(null);
const login = async (email: string, password: string) => {
const { data } = await api.post('/api/auth/login', { email, password });
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
setUser(data.user);
};
const logout = () => {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) throw new Error('useAuth must be used within AuthProvider');
return context;
};
```
---
## Testing
### Component Tests (Vitest + React Testing Library)
```typescript
// TaskCard.test.tsx
import { render, screen } from '@testing-library/react';
import { TaskCard } from './TaskCard';
describe('TaskCard', () => {
it('renders task name', () => {
const task = { id: '1', name: 'Water plants', status: 'PENDING' };
render(<TaskCard task={task} />);
expect(screen.getByText('Water plants')).toBeInTheDocument();
});
});
```
---
## Environment Variables
```bash
# API
VITE_API_URL=http://localhost:3000/api
# Auth
VITE_AUTH_ENABLED=true
# Features
VITE_METRC_ENABLED=false
```
---
## Development Workflow
### Setup
```bash
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Start dev server
npm run dev
```
### Scripts
```json
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"lint": "eslint src --ext .ts,.tsx",
"format": "prettier --write src"
}
}
```
---
## Accessibility
- **WCAG 2.1 AA Compliance**: All components meet accessibility standards
- **Keyboard Navigation**: All interactive elements keyboard-accessible
- **Screen Reader Support**: Proper ARIA labels and roles
- **Focus Management**: Clear focus indicators and logical tab order
- **Color Contrast**: Minimum 4.5:1 contrast ratio for text
---
## Mobile & PWA
### Progressive Web App (Stretch Goal)
```typescript
// vite.config.ts
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
VitePWA({
registerType: 'autoUpdate',
manifest: {
name: 'CA Grow Ops Manager',
short_name: 'Grow Ops',
theme_color: '#10b981',
icons: [
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
],
},
}),
],
});
```
---
## Next Steps
1. **Choose Build Tool**: Decide between Vite and Next.js
2. **Set Up Project**: Initialize React project with TypeScript
3. **Configure Tailwind**: Set up Tailwind CSS and design tokens
4. **Build Design System**: Implement base UI components
5. **Implement Pages**: Build page components per spec
6. **Write Tests**: Component and integration tests
7. **Deploy**: Set up CI/CD and deploy to staging
---
## Resources
- [React Documentation](https://react.dev)
- [Vite Documentation](https://vitejs.dev)
- [Next.js Documentation](https://nextjs.org/docs)
- [Radix UI Documentation](https://www.radix-ui.com)
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
- [React Testing Library](https://testing-library.com/react)

530
plans/phase-1-foundation.md Normal file
View file

@ -0,0 +1,530 @@
# Implementation Plan: Phase 1 — Foundation
**Version**: 0.1.0
**Status**: Planning
**Created**: 2025-12-08
**Target Completion**: TBD
---
## Overview
Phase 1 establishes the foundational infrastructure and core features for CA Grow Ops Manager. This phase focuses on:
1. Project setup and infrastructure
2. Authentication and RBAC
3. Core data models (Users, Roles, Batches, Rooms, Tasks)
4. Basic CRUD operations for each domain
5. Minimal viable UI for each feature
**Success Criteria**: A working application where users can authenticate, create batches/rooms, schedule tasks, clock in/out, and upload compliance documents.
---
## Architecture Decisions
### Backend Framework: **Fastify**
**Rationale**:
- 2-3x faster than Express
- Built-in TypeScript support
- Better schema validation (JSON Schema)
- Modern async/await patterns
- Still lightweight and flexible
### Frontend Framework: **Vite + React**
**Rationale**:
- Faster dev server and builds than Next.js
- Simpler for v1 (no SSR needed yet)
- Better HMR experience
- Easier to migrate to Next.js later if needed
### Component Library: **shadcn/ui (Radix + Tailwind)**
**Rationale**:
- Copy-paste components (no npm bloat)
- Built on Radix (accessible primitives)
- Tailwind for styling (mobile-first)
- Highly customizable
### Database: **PostgreSQL 15 + Prisma**
**Rationale**:
- ACID compliance for compliance data
- JSON support for flexible metadata
- Prisma provides type-safe queries
- Easy migrations
---
## Implementation Phases
### Phase 1A: Infrastructure Setup (Week 1)
**Goal**: Set up development environment and CI/CD
#### Tasks
1. **Backend Setup**
- [ ] Initialize Node.js project with TypeScript
- [ ] Configure Fastify with TypeScript
- [ ] Set up Prisma with PostgreSQL
- [ ] Configure ESLint + Prettier
- [ ] Set up Jest for testing
- [ ] Create Docker Compose for local dev
- [ ] Configure environment variables
2. **Frontend Setup**
- [ ] Initialize Vite + React + TypeScript
- [ ] Install and configure Tailwind CSS
- [ ] Set up shadcn/ui components
- [ ] Configure React Router
- [ ] Set up Vitest + React Testing Library
- [ ] Configure ESLint + Prettier
3. **Infrastructure**
- [ ] Create Git repository
- [ ] Set up .gitignore files
- [ ] Create README files
- [ ] Set up Docker Compose (backend, frontend, db, redis)
- [ ] Configure VS Code workspace settings
**Deliverables**:
- Working dev environment with hot reload
- Docker Compose setup for local development
- Basic project structure for backend and frontend
---
### Phase 1B: Authentication & RBAC (Week 2)
**Goal**: Implement secure authentication and role-based access control
#### Tasks
1. **Database Schema**
- [ ] Create User model (Prisma schema)
- [ ] Create Role model
- [ ] Create Session model (optional, if not using Redis)
- [ ] Run migrations
2. **Backend Auth**
- [ ] Implement password hashing (bcrypt)
- [ ] Implement JWT generation (access + refresh tokens)
- [ ] Create auth routes (`/api/auth/register`, `/api/auth/login`, `/api/auth/refresh`, `/api/auth/logout`)
- [ ] Create auth middleware (verify JWT)
- [ ] Create RBAC middleware (check roles/permissions)
- [ ] Write unit tests for auth service
- [ ] Write integration tests for auth endpoints
3. **Frontend Auth**
- [ ] Create AuthContext and useAuth hook
- [ ] Create Login page
- [ ] Create Register page (admin-only for v1)
- [ ] Implement token storage (httpOnly cookies + localStorage)
- [ ] Implement token refresh logic
- [ ] Create ProtectedRoute component
- [ ] Create role-based UI rendering
4. **Seed Data**
- [ ] Create seed script for default roles (Owner, Compliance Manager, Head Grower, Staff, Accountant)
- [ ] Create seed script for test users
**Deliverables**:
- Working login/logout flow
- JWT-based authentication
- RBAC middleware protecting routes
- Seed data for testing
**API Endpoints**:
- `POST /api/auth/register` - Register new user (admin-only)
- `POST /api/auth/login` - Login with email/password
- `POST /api/auth/refresh` - Refresh access token
- `POST /api/auth/logout` - Logout and invalidate tokens
- `GET /api/auth/me` - Get current user
---
### Phase 1C: Core Data Models (Week 3)
**Goal**: Implement core domain models and CRUD operations
#### Tasks
1. **Batches & Rooms Module**
- [ ] Create Prisma schemas (Batch, Room, BatchNote, BatchPhoto, WeightLog)
- [ ] Run migrations
- [ ] Implement batch service (CRUD operations)
- [ ] Implement room service (CRUD operations)
- [ ] Create batch routes (`/api/batches`)
- [ ] Create room routes (`/api/rooms`)
- [ ] Write unit tests
- [ ] Write integration tests
2. **Tasks Module**
- [ ] Create Prisma schemas (Task, TaskTemplate)
- [ ] Run migrations
- [ ] Implement task service (CRUD operations)
- [ ] Implement task template service
- [ ] Create task routes (`/api/tasks`, `/api/tasks/templates`)
- [ ] Write unit tests
- [ ] Write integration tests
3. **Labor Module**
- [ ] Create Prisma schemas (TimeEntry, WageRate)
- [ ] Run migrations
- [ ] Implement timeclock service (clock in/out logic)
- [ ] Create labor routes (`/api/labor/clock-in`, `/api/labor/clock-out`, `/api/labor/time-entries`)
- [ ] Write unit tests
- [ ] Write integration tests
4. **Compliance Module**
- [ ] Create Prisma schema (ComplianceDocument, AuditLog)
- [ ] Run migrations
- [ ] Implement document storage (local filesystem or S3-compatible)
- [ ] Implement document service (upload, download, delete)
- [ ] Create compliance routes (`/api/compliance/documents`)
- [ ] Write unit tests
- [ ] Write integration tests
**Deliverables**:
- Working CRUD APIs for all core entities
- Database migrations applied
- Unit and integration tests passing
- Postman/Insomnia collection for testing
**API Endpoints Summary**:
- Batches: `GET/POST/PATCH/DELETE /api/batches`, `POST /api/batches/:id/weights`
- Rooms: `GET/POST/PATCH/DELETE /api/rooms`
- Tasks: `GET/POST/PATCH/DELETE /api/tasks`, `POST /api/tasks/:id/complete`
- Labor: `POST /api/labor/clock-in`, `POST /api/labor/clock-out`, `GET /api/labor/time-entries`
- Compliance: `GET/POST/PATCH/DELETE /api/compliance/documents`, `GET /api/compliance/documents/:id/download`
---
### Phase 1D: Frontend UI (Week 4-5)
**Goal**: Build minimal viable UI for each feature
#### Tasks
1. **Design System**
- [ ] Set up Tailwind config with design tokens (colors, spacing, fonts)
- [ ] Create base UI components (Button, Input, Card, Badge, Dialog, Dropdown)
- [ ] Create layout components (Header, Sidebar, Footer)
- [ ] Implement dark mode toggle
- [ ] Create responsive breakpoints
2. **Dashboard & Navigation**
- [ ] Create Dashboard page (overview widgets)
- [ ] Create Sidebar navigation
- [ ] Create Header with user menu
- [ ] Implement routing (React Router)
3. **Batches & Rooms UI**
- [ ] Create BatchList page
- [ ] Create BatchDetail page
- [ ] Create BatchForm (create/edit)
- [ ] Create RoomList page
- [ ] Create RoomDetail page
- [ ] Create RoomForm (create/edit)
- [ ] Create WeightLogForm component
4. **Tasks UI**
- [ ] Create TaskList page (with filters)
- [ ] Create TodayView page (mobile-optimized)
- [ ] Create TaskDetail page
- [ ] Create TaskForm (create/edit)
- [ ] Create TaskTemplateForm
5. **Labor UI**
- [ ] Create TimeclockWidget component
- [ ] Create TimeEntryList page
- [ ] Create LaborReports page (basic hours report)
6. **Compliance UI**
- [ ] Create DocumentList page
- [ ] Create DocumentUploader component
- [ ] Create DocumentPreview component (PDF/image viewer)
7. **Settings UI**
- [ ] Create SettingsPage (user preferences, notification settings)
- [ ] Create UserManagement page (admin-only)
**Deliverables**:
- Fully functional UI for all Phase 1 features
- Mobile-responsive design
- Dark mode support
- Accessible components (WCAG 2.1 AA)
---
### Phase 1E: Testing & Polish (Week 6)
**Goal**: Comprehensive testing and UX polish
#### Tasks
1. **Backend Testing**
- [ ] Achieve 80%+ code coverage for services
- [ ] Write integration tests for all API endpoints
- [ ] Test RBAC permissions for all routes
- [ ] Test error handling and edge cases
2. **Frontend Testing**
- [ ] Write component tests for all UI components
- [ ] Write integration tests for key workflows (login, create batch, clock in)
- [ ] Test responsive design on mobile/tablet/desktop
- [ ] Test dark mode
3. **UX Polish**
- [ ] Optimize mobile tap targets (44×44px minimum)
- [ ] Add loading states and skeletons
- [ ] Add error states and retry logic
- [ ] Add success toasts and confirmations
- [ ] Optimize form validation and error messages
- [ ] Add keyboard shortcuts for power users
4. **Performance**
- [ ] Optimize API response times (< 200ms p95)
- [ ] Optimize frontend bundle size
- [ ] Add pagination for large lists
- [ ] Add caching for frequently accessed data
5. **Documentation**
- [ ] Write API documentation (OpenAPI/Swagger)
- [ ] Write user guide for each feature
- [ ] Write deployment guide
- [ ] Update README files
**Deliverables**:
- 80%+ test coverage
- Polished UX with loading/error states
- API documentation
- User guide
---
## Technical Specifications
### Database Schema (Prisma)
```prisma
// User & Auth
model User {
id String @id @default(cuid())
email String @unique
password String // bcrypt hashed
name String
roleId String
role Role @relation(fields: [roleId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Role {
id String @id @default(cuid())
name String @unique
description String?
users User[]
wageRates WageRate[]
}
// Batches & Rooms
model Batch {
id String @id @default(cuid())
batchNumber String @unique
strain String
stage BatchStage @default(CLONE_IN)
plantCount Int
startDate DateTime
roomId String?
room Room? @relation(fields: [roomId], references: [id])
metrcTags String[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Room {
id String @id @default(cuid())
name String
type RoomType
capacity Int?
status RoomStatus @default(ACTIVE)
batches Batch[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Tasks
model Task {
id String @id @default(cuid())
name String
status TaskStatus @default(PENDING)
dueDate DateTime
assigneeId String?
assignee User? @relation(fields: [assigneeId], references: [id])
roomId String?
room Room? @relation(fields: [roomId], references: [id])
batchId String?
batch Batch? @relation(fields: [batchId], references: [id])
completedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Labor
model TimeEntry {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])
clockIn DateTime
clockOut DateTime?
duration Int?
roomId String?
room Room? @relation(fields: [roomId], references: [id])
createdAt DateTime @default(now())
}
model WageRate {
id String @id @default(cuid())
roleId String
role Role @relation(fields: [roleId], references: [id])
hourlyRate Float
effectiveDate DateTime
createdAt DateTime @default(now())
}
// Compliance
model ComplianceDocument {
id String @id @default(cuid())
type DocumentType
filename String
url String
date DateTime
uploadedBy String
user User @relation(fields: [uploadedBy], references: [id])
createdAt DateTime @default(now())
}
// Enums
enum BatchStage {
CLONE_IN
VEGETATIVE
FLOWERING
HARVEST
DRYING
CURING
FINISHED
}
enum RoomType {
VEG
FLOWER
DRY
FACILITY
}
enum RoomStatus {
ACTIVE
CLEANING
MAINTENANCE
}
enum TaskStatus {
PENDING
IN_PROGRESS
COMPLETE
OVERDUE
}
enum DocumentType {
TAX_MONTHLY
UTILITY_BILL
RENT_LEASE
INVOICE
LICENSE_PERMIT
OTHER
}
```
---
## Risk Management
| Risk | Impact | Mitigation | Owner |
|------|--------|------------|-------|
| Scope creep in Phase 1 | High | Strict adherence to Phase 1 spec; defer enhancements to Phase 2 | PM |
| Database schema changes | Medium | Use Prisma migrations; test migrations thoroughly | Backend Lead |
| Mobile UX issues | High | Test on real devices early; prioritize tablet testing | Frontend Lead |
| Authentication vulnerabilities | Critical | Security audit of auth code; use established libraries (bcrypt, jsonwebtoken) | Backend Lead |
| Performance issues with large datasets | Medium | Implement pagination early; add database indexes | Backend Lead |
---
## Success Metrics
### Phase 1 Completion Criteria
- [ ] All Phase 1 features implemented and tested
- [ ] 80%+ test coverage (backend and frontend)
- [ ] All API endpoints documented
- [ ] User guide written
- [ ] Deployment guide written
- [ ] Application deployed to staging environment
- [ ] Demo completed with stakeholders
### Performance Targets
- [ ] API response time < 200ms (p95)
- [ ] Page load time < 2s on 3G
- [ ] Time to interactive < 3s on 3G
- [ ] Lighthouse score > 90 (Performance, Accessibility)
### Quality Targets
- [ ] Zero critical security vulnerabilities
- [ ] Zero high-priority bugs
- [ ] WCAG 2.1 AA compliance
- [ ] Mobile-responsive on all pages
---
## Timeline
**Total Duration**: 6 weeks
- **Week 1**: Infrastructure Setup
- **Week 2**: Authentication & RBAC
- **Week 3**: Core Data Models
- **Week 4-5**: Frontend UI
- **Week 6**: Testing & Polish
**Milestones**:
- End of Week 2: Working auth system
- End of Week 3: All APIs functional
- End of Week 5: All UI complete
- End of Week 6: Phase 1 complete and deployed
---
## Next Steps
1. **Review this plan** with the team
2. **Break down into tasks** using `/speckit.tasks`
3. **Assign tasks** to team members
4. **Set up project tracking** (GitHub Projects, Linear, etc.)
5. **Begin Week 1**: Infrastructure Setup

View file

@ -0,0 +1,720 @@
# Tasks: Week 1 — Infrastructure Setup
**Plan**: Phase 1 Foundation
**Week**: 1 of 6
**Status**: Ready
**Created**: 2025-12-08
---
## Overview
Week 1 focuses on setting up the development environment, project structure, and foundational tooling for both backend and frontend. By the end of this week, developers should be able to run the full stack locally with hot reload.
**Success Criteria**:
- ✅ Backend runs on `http://localhost:3000` with hot reload
- ✅ Frontend runs on `http://localhost:5173` with hot reload
- ✅ PostgreSQL database accessible
- ✅ Docker Compose brings up entire stack
- ✅ Linting and formatting configured
- ✅ Testing frameworks configured
---
## Task List
### Backend Setup
#### TASK-001: Initialize Backend Project
**Priority**: P0 (Blocker)
**Estimated Time**: 1 hour
**Assignee**: Backend Lead
**Description**: Create Node.js project with TypeScript and Fastify
**Steps**:
```bash
cd ca-grow-ops-manager
mkdir backend
cd backend
npm init -y
npm install fastify @fastify/cors @fastify/helmet @fastify/jwt
npm install -D typescript @types/node tsx nodemon
npm install -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint prettier
npx tsc --init
```
**Acceptance Criteria**:
- [ ] `package.json` created with correct dependencies
- [ ] `tsconfig.json` configured for Node.js
- [ ] TypeScript compiles without errors
- [ ] Basic Fastify server runs on port 3000
**Files to Create**:
- `backend/package.json`
- `backend/tsconfig.json`
- `backend/src/server.ts` (basic Fastify server)
- `backend/src/app.ts` (Fastify app configuration)
---
#### TASK-002: Configure Prisma with PostgreSQL
**Priority**: P0 (Blocker)
**Estimated Time**: 1.5 hours
**Assignee**: Backend Lead
**Depends On**: TASK-001
**Description**: Set up Prisma ORM with PostgreSQL connection
**Steps**:
```bash
cd backend
npm install prisma @prisma/client
npm install -D prisma
npx prisma init
```
**Acceptance Criteria**:
- [ ] Prisma schema file created (`prisma/schema.prisma`)
- [ ] Database connection string configured in `.env`
- [ ] Prisma Client generated
- [ ] Can connect to PostgreSQL database
**Files to Create**:
- `backend/prisma/schema.prisma`
- `backend/.env.example`
- `backend/.env` (gitignored)
**Prisma Schema (Initial)**:
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
---
#### TASK-003: Configure ESLint and Prettier (Backend)
**Priority**: P1
**Estimated Time**: 30 minutes
**Assignee**: Backend Lead
**Depends On**: TASK-001
**Description**: Set up code quality tools for backend
**Acceptance Criteria**:
- [ ] ESLint configured for TypeScript
- [ ] Prettier configured
- [ ] `npm run lint` works
- [ ] `npm run format` works
- [ ] VS Code auto-formats on save
**Files to Create**:
- `backend/.eslintrc.json`
- `backend/.prettierrc`
- `backend/.prettierignore`
**ESLint Config**:
```json
{
"parser": "@typescript-eslint/parser",
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "warn"
}
}
```
---
#### TASK-004: Configure Jest for Backend Testing
**Priority**: P1
**Estimated Time**: 1 hour
**Assignee**: Backend Lead
**Depends On**: TASK-001
**Description**: Set up Jest for unit and integration testing
**Steps**:
```bash
cd backend
npm install -D jest @types/jest ts-jest supertest @types/supertest
npx ts-jest config:init
```
**Acceptance Criteria**:
- [ ] Jest configured for TypeScript
- [ ] `npm test` runs tests
- [ ] Sample test passes
- [ ] Test coverage report generated
**Files to Create**:
- `backend/jest.config.js`
- `backend/src/__tests__/example.test.ts`
**Sample Test**:
```typescript
describe('Example Test', () => {
it('should pass', () => {
expect(1 + 1).toBe(2);
});
});
```
---
#### TASK-005: Create Backend Docker Configuration
**Priority**: P1
**Estimated Time**: 1 hour
**Assignee**: Backend Lead
**Depends On**: TASK-001, TASK-002
**Description**: Create Dockerfile and Docker Compose for backend
**Acceptance Criteria**:
- [ ] Dockerfile builds successfully
- [ ] Backend runs in Docker container
- [ ] Hot reload works in Docker
- [ ] Environment variables passed correctly
**Files to Create**:
- `backend/Dockerfile`
- `backend/Dockerfile.dev`
- `backend/.dockerignore`
**Dockerfile.dev**:
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
```
---
### Frontend Setup
#### TASK-006: Initialize Frontend Project with Vite
**Priority**: P0 (Blocker)
**Estimated Time**: 1 hour
**Assignee**: Frontend Lead
**Description**: Create Vite + React + TypeScript project
**Steps**:
```bash
cd ca-grow-ops-manager
npm create vite@latest frontend -- --template react-ts
cd frontend
npm install
npm install react-router-dom
npm install -D @types/react-router-dom
```
**Acceptance Criteria**:
- [ ] Vite project created
- [ ] React + TypeScript configured
- [ ] Dev server runs on port 5173
- [ ] Hot reload works
**Files Created** (by Vite):
- `frontend/package.json`
- `frontend/tsconfig.json`
- `frontend/vite.config.ts`
- `frontend/src/main.tsx`
- `frontend/src/App.tsx`
---
#### TASK-007: Install and Configure Tailwind CSS
**Priority**: P0 (Blocker)
**Estimated Time**: 1 hour
**Assignee**: Frontend Lead
**Depends On**: TASK-006
**Description**: Set up Tailwind CSS with custom design tokens
**Steps**:
```bash
cd frontend
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
**Acceptance Criteria**:
- [ ] Tailwind CSS configured
- [ ] Custom design tokens defined (colors, spacing, fonts)
- [ ] Dark mode configured
- [ ] Tailwind classes work in components
**Files to Create/Modify**:
- `frontend/tailwind.config.js`
- `frontend/postcss.config.js`
- `frontend/src/index.css`
**Tailwind Config**:
```javascript
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: '#10b981',
secondary: '#3b82f6',
danger: '#ef4444',
warning: '#f59e0b',
success: '#10b981',
},
},
},
plugins: [],
};
```
---
#### TASK-008: Set Up shadcn/ui Components
**Priority**: P1
**Estimated Time**: 1.5 hours
**Assignee**: Frontend Lead
**Depends On**: TASK-007
**Description**: Install shadcn/ui and create base components
**Steps**:
```bash
cd frontend
npx shadcn-ui@latest init
npx shadcn-ui@latest add button
npx shadcn-ui@latest add input
npx shadcn-ui@latest add card
npx shadcn-ui@latest add dialog
npx shadcn-ui@latest add dropdown-menu
```
**Acceptance Criteria**:
- [ ] shadcn/ui configured
- [ ] Base components installed (Button, Input, Card, Dialog, Dropdown)
- [ ] Components render correctly
- [ ] Dark mode works with components
**Files Created**:
- `frontend/components.json`
- `frontend/src/components/ui/button.tsx`
- `frontend/src/components/ui/input.tsx`
- `frontend/src/components/ui/card.tsx`
- etc.
---
#### TASK-009: Configure React Router
**Priority**: P1
**Estimated Time**: 1 hour
**Assignee**: Frontend Lead
**Depends On**: TASK-006
**Description**: Set up React Router with basic routes
**Acceptance Criteria**:
- [ ] React Router configured
- [ ] Basic routes created (/, /login, /dashboard)
- [ ] Navigation works
- [ ] 404 page created
**Files to Create**:
- `frontend/src/router.tsx`
- `frontend/src/pages/HomePage.tsx`
- `frontend/src/pages/LoginPage.tsx`
- `frontend/src/pages/DashboardPage.tsx`
- `frontend/src/pages/NotFoundPage.tsx`
**Router Setup**:
```typescript
import { createBrowserRouter } from 'react-router-dom';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import DashboardPage from './pages/DashboardPage';
export const router = createBrowserRouter([
{ path: '/', element: <HomePage /> },
{ path: '/login', element: <LoginPage /> },
{ path: '/dashboard', element: <DashboardPage /> },
{ path: '*', element: <NotFoundPage /> },
]);
```
---
#### TASK-010: Configure ESLint and Prettier (Frontend)
**Priority**: P1
**Estimated Time**: 30 minutes
**Assignee**: Frontend Lead
**Depends On**: TASK-006
**Description**: Set up code quality tools for frontend
**Acceptance Criteria**:
- [ ] ESLint configured for React + TypeScript
- [ ] Prettier configured
- [ ] `npm run lint` works
- [ ] `npm run format` works
- [ ] VS Code auto-formats on save
**Files to Create**:
- `frontend/.eslintrc.json`
- `frontend/.prettierrc`
- `frontend/.prettierignore`
---
#### TASK-011: Configure Vitest for Frontend Testing
**Priority**: P1
**Estimated Time**: 1 hour
**Assignee**: Frontend Lead
**Depends On**: TASK-006
**Description**: Set up Vitest and React Testing Library
**Steps**:
```bash
cd frontend
npm install -D vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom
```
**Acceptance Criteria**:
- [ ] Vitest configured
- [ ] React Testing Library configured
- [ ] `npm test` runs tests
- [ ] Sample component test passes
**Files to Create**:
- `frontend/vite.config.ts` (add test config)
- `frontend/src/setupTests.ts`
- `frontend/src/components/__tests__/Button.test.tsx`
---
### Infrastructure & DevOps
#### TASK-012: Create Docker Compose Configuration
**Priority**: P0 (Blocker)
**Estimated Time**: 2 hours
**Assignee**: DevOps/Backend Lead
**Depends On**: TASK-005, TASK-006
**Description**: Create Docker Compose for full stack (backend, frontend, db, redis)
**Acceptance Criteria**:
- [ ] `docker-compose up` starts all services
- [ ] Backend accessible at `http://localhost:3000`
- [ ] Frontend accessible at `http://localhost:5173`
- [ ] PostgreSQL accessible at `localhost:5432`
- [ ] Redis accessible at `localhost:6379`
- [ ] Hot reload works for backend and frontend
**Files to Create**:
- `docker-compose.yml`
- `docker-compose.dev.yml`
**Docker Compose**:
```yaml
version: '3.8'
services:
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: ca_grow_ops
POSTGRES_PASSWORD: dev_password
POSTGRES_DB: ca_grow_ops_dev
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
backend:
build:
context: ./backend
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://ca_grow_ops:dev_password@db:5432/ca_grow_ops_dev
REDIS_URL: redis://redis:6379
NODE_ENV: development
volumes:
- ./backend:/app
- /app/node_modules
depends_on:
- db
- redis
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
ports:
- "5173:5173"
environment:
VITE_API_URL: http://localhost:3000/api
volumes:
- ./frontend:/app
- /app/node_modules
depends_on:
- backend
volumes:
postgres_data:
```
---
#### TASK-013: Create Git Repository and .gitignore
**Priority**: P0 (Blocker)
**Estimated Time**: 30 minutes
**Assignee**: Any Developer
**Description**: Initialize Git repository with proper .gitignore files
**Acceptance Criteria**:
- [ ] Git repository initialized
- [ ] `.gitignore` files created for root, backend, frontend
- [ ] Initial commit made
- [ ] Remote repository created (GitHub/GitLab)
**Files to Create**:
- `.gitignore` (root)
- `backend/.gitignore`
- `frontend/.gitignore`
**Root .gitignore**:
```
node_modules/
.env
.env.local
*.log
.DS_Store
dist/
build/
coverage/
```
---
#### TASK-014: Create VS Code Workspace Settings
**Priority**: P2
**Estimated Time**: 30 minutes
**Assignee**: Any Developer
**Description**: Configure VS Code for optimal DX
**Acceptance Criteria**:
- [ ] Workspace settings configured
- [ ] Recommended extensions listed
- [ ] Auto-format on save enabled
- [ ] ESLint integration working
**Files to Create**:
- `.vscode/settings.json`
- `.vscode/extensions.json`
**VS Code Settings**:
```json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}
```
---
#### TASK-015: Create README Files
**Priority**: P2
**Estimated Time**: 1 hour
**Assignee**: Any Developer
**Description**: Update README files with setup instructions
**Acceptance Criteria**:
- [ ] Root README updated with quick start
- [ ] Backend README updated
- [ ] Frontend README updated
- [ ] Docker Compose instructions included
**Files to Update**:
- `README.md` (root)
- `backend/README.md`
- `frontend/README.md`
---
## Task Dependencies
```
TASK-001 (Backend Init)
├─> TASK-002 (Prisma)
├─> TASK-003 (ESLint/Prettier)
├─> TASK-004 (Jest)
└─> TASK-005 (Docker)
TASK-006 (Frontend Init)
├─> TASK-007 (Tailwind)
│ └─> TASK-008 (shadcn/ui)
├─> TASK-009 (React Router)
├─> TASK-010 (ESLint/Prettier)
└─> TASK-011 (Vitest)
TASK-005 + TASK-006
└─> TASK-012 (Docker Compose)
TASK-013 (Git) - No dependencies
TASK-014 (VS Code) - No dependencies
TASK-015 (READMEs) - After all setup tasks
```
---
## Verification Checklist
At the end of Week 1, verify:
### Backend
- [ ] `cd backend && npm install` works
- [ ] `npm run dev` starts server on port 3000
- [ ] `npm run lint` passes
- [ ] `npm test` passes
- [ ] Prisma Client generated
- [ ] Can connect to PostgreSQL
### Frontend
- [ ] `cd frontend && npm install` works
- [ ] `npm run dev` starts server on port 5173
- [ ] `npm run lint` passes
- [ ] `npm test` passes
- [ ] Tailwind classes work
- [ ] shadcn/ui components render
### Docker
- [ ] `docker-compose up` starts all services
- [ ] Backend accessible at <http://localhost:3000>
- [ ] Frontend accessible at <http://localhost:5173>
- [ ] Hot reload works for both
### Git
- [ ] Repository initialized
- [ ] Initial commit made
- [ ] Remote repository connected
---
## Estimated Total Time
**Backend**: 6 hours
**Frontend**: 6.5 hours
**Infrastructure**: 3 hours
**Total**: ~15.5 hours (2 days for 1 developer, or 1 day for 2 developers)
---
## Next Steps
After completing Week 1 tasks:
1. **Review** all setup with the team
2. **Test** full stack locally
3. **Proceed to Week 2**: Authentication & RBAC

150
spec.yml Normal file
View file

@ -0,0 +1,150 @@
project:
name: CA Grow Ops Manager
version: 0.1.0
description: |
A web + mobile application that reduces cognitive load for managing licensed
California cannabis cultivation facilities. Centralizes grow operations, labor
tracking, compliance recordkeeping, scheduling, and team communication.
objectives:
- Centralize and templatize cultivation tasks by room and batch (veg, flower, dry, facility)
- Track labor hours and associate time to rooms/batches for cost visibility
- Support compliance-adjacent recordkeeping required by California regulators (METRC remains system of record)
- Provide a shared schedule and communication layer for facility staff
- Integrate with environmental monitoring and control systems (read-only dashboards initially)
actors:
- name: Owner
description: Facility owner with full access to all features, financial reports, and compliance exports
- name: Compliance Manager
description: Manages compliance records, audit packets, and regulatory documentation
- name: Head Grower
description: Oversees cultivation operations, creates task templates, manages batches and rooms
- name: Staff / Trimmers
description: Floor workers who complete tasks, clock in/out, and log batch data
- name: Accountant
description: Reviews labor cost reports, exports payroll data, and analyzes batch profitability
domains:
- name: CultivationOps
description: Tasks, batches, rooms, and cultivation workflows
features:
- Task templates and scheduling
- Batch lifecycle management
- Room management and transitions
- Weight logging and yield tracking
- Photo and note attachments
- name: Compliance
description: Recordkeeping and audit readiness for California DCC regulations
features:
- Document storage (PDFs, images) with structured metadata
- Monthly/quarterly compliance views
- Audit packet generation (ZIP exports)
- METRC tag mapping (read-only in v1)
- name: Labor
description: Time tracking and labor cost analysis
features:
- Web/mobile timeclock
- Role and wage rate management
- Hours reporting (per user, per period)
- Labor cost per room/batch
- CSV exports for payroll systems
- name: Inventory
description: Materials, nutrients, and supplies tracking
features:
- Item catalog (nutrients, pots, IPM, PPE, CO₂, media, packaging)
- Quantity, location, and supplier tracking
- Min/max thresholds and restock alerts
- Lot/serial tracking for recall support
- name: Integrations
description: External system connections and hardware monitoring
features:
- Environmental dashboards (temperature, humidity, VPD)
- Lighting schedule status widgets
- METRC connector (future phase)
- Hardware adapter framework
- name: Communications
description: Team collaboration and notifications
features:
- Task comments and @mentions
- Daily digest emails/notifications
- Announcements channel
- Role-based notification preferences
tech_stack:
backend:
language: TypeScript
runtime: Node.js
framework: Express or Fastify
database: PostgreSQL
orm: Prisma
testing: Jest + Supertest
frontend:
language: TypeScript
framework: React
build_tool: Vite or Next.js
components: Radix UI or shadcn-style
styling: Tailwind CSS or modern CSS-in-JS
testing: Vitest + React Testing Library
mobile:
approach: Web-first (tablet-optimized)
stretch_goal: React Native or Capacitor PWA
phases:
- name: Phase 1 - Foundation
version: 0.1.0
features:
- Authentication and RBAC
- Task templates and scheduling
- Basic batch and room management
- Timeclock and labor tracking
- Compliance document storage
- name: Phase 2 - Operations
version: 0.2.0
features:
- Advanced batch lifecycle
- Weight logging and yield analytics
- Inventory management
- Environmental dashboards
- Notification system
- name: Phase 3 - Integrations
version: 0.3.0
features:
- METRC connector (read/write)
- Hardware integrations
- Advanced reporting
- Mobile app (if not PWA)
- Multi-facility support
out_of_scope_v1:
- Direct METRC write integration (read-only mapping only)
- Payroll processing (exports only)
- Financial accounting beyond labor cost tracking
- Customer-facing features (B2C)
- Automated environmental control (read-only dashboards only)
compliance_notes:
- METRC is the authoritative system of record for California cannabis track-and-trace
- This platform supports compliance-adjacent workflows but does not replace METRC
- All compliance features align with California DCC guidance
- Audit logs are immutable and exportable
repository:
url: https://github.com/your-org/ca-grow-ops-manager
structure:
- .specify/memory/constitution.md
- constitution.md
- spec.yml
- specs/
- backend/
- frontend/
- docs/

339
specs/batches-and-rooms.md Normal file
View file

@ -0,0 +1,339 @@
# Feature Spec: Batches and Rooms
**Domain**: CultivationOps
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Batches and Rooms module manages the lifecycle of cannabis batches from clone to finished product, and tracks the physical rooms where cultivation occurs. It provides internal batch IDs with METRC tag mapping, room lifecycle management, weight logging with automatic yield calculations, and rich batch history with photos and notes.
---
## User Stories
### As a Head Grower
- I want to create batches and track them through each growth stage so I can monitor progress
- I want to map internal batch IDs to METRC tags so I can maintain compliance without duplicating data entry
- I want to log weights at each stage (wet, bucked, final, trim, waste) so I can calculate yields and moisture loss
- I want to attach photos and notes to batches so I can document issues and successes
- I want to see batch history and task completion so I can review what worked
### As a Staff Member
- I want to see which batches are in which rooms so I know where to focus my work
- I want to log harvest weights quickly on a tablet so I don't slow down the workflow
- I want to add photos of issues (pests, deficiencies) so the Head Grower can review
### As a Compliance Manager
- I want to see METRC tag mappings for each batch so I can cross-reference with the state system
- I want to export batch data with weights and dates for audit purposes
### As an Owner
- I want to see yield reports per batch so I can identify top-performing genetics and methods
- I want to see labor costs per batch so I can calculate profitability
---
## Requirements
### Functional Requirements
#### Batch Management
- **Create batches** with:
- Internal batch ID (auto-generated or custom)
- Strain/genetics
- Source (clone, seed)
- Start date
- Initial plant count
- METRC tag(s) (stored, not synced in v1)
- **Batch lifecycle stages**:
- Clone In
- Vegetative
- Flowering
- Harvest
- Drying
- Curing
- Finished
- **Batch transitions**:
- Move batch between stages
- Move batch between rooms
- Split batch (e.g., cull underperformers)
- Merge batches (if allowed by compliance)
#### Room Management
- **Room types**: Veg, Flower, Dry, Facility
- **Room properties**:
- Name/number
- Type
- Capacity (plant count or sq ft)
- Current batches
- Environmental setpoints (target temp, humidity, VPD)
- **Room lifecycle**:
- Active (in use)
- Cleaning (between batches)
- Maintenance (offline)
#### Weight Logging
- **Weight types**:
- Wet weight (at harvest)
- Bucked weight (after initial trim)
- Final dry weight
- Trim weight
- Waste weight
- **Automatic calculations**:
- Moisture loss % (wet → dry)
- Yield per plant
- Trim ratio
- Total yield per batch
- **Weight entry**:
- Quick entry form (mobile-optimized)
- Bulk entry (CSV upload)
- Photo attachment for verification
#### Batch History & Documentation
- **Attach to batches**:
- Photos (timestamped)
- Notes (markdown-supported)
- Task completion history
- Weight logs
- Room transitions
- **Timeline view** of all batch events
- **Export** batch report (PDF or CSV)
### Non-Functional Requirements
- **Performance**: Batch list loads in < 500ms
- **Data integrity**: Weight logs are immutable once saved
- **Accessibility**: WCAG 2.1 AA compliant
- **Mobile-first**: Weight logging optimized for tablet use
---
## Out of Scope (v1)
- Direct METRC sync (read/write)
- Automated batch transitions based on environmental data
- Predictive yield modeling
- Genetic lineage tracking (family trees)
---
## Acceptance Criteria
### Batch Lifecycle
- [ ] Head Grower can create a new batch with all required fields
- [ ] Batches can be transitioned through lifecycle stages
- [ ] Batch transitions are logged with timestamp and user
- [ ] Batches can be moved between rooms
- [ ] Batch history displays all events in chronological order
### METRC Mapping
- [ ] METRC tags can be associated with batches
- [ ] Multiple METRC tags can be linked to a single internal batch
- [ ] METRC tags are stored but not synced in v1
### Weight Logging
- [ ] Staff can log weights for each weight type
- [ ] Weight logs are timestamped and attributed to user
- [ ] Automatic calculations (moisture loss, yield) are displayed
- [ ] Photos can be attached to weight logs
- [ ] Weight logs are immutable after save
### Room Management
- [ ] Rooms can be created with type and capacity
- [ ] Current batches in each room are displayed
- [ ] Room status (active, cleaning, maintenance) can be updated
- [ ] Room capacity warnings when exceeded
### Batch Documentation
- [ ] Photos can be attached to batches with timestamps
- [ ] Notes can be added to batches (markdown-supported)
- [ ] Batch timeline displays all events
- [ ] Batch report can be exported (PDF or CSV)
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model Batch {
id String @id @default(cuid())
batchNumber String @unique
strain String
source BatchSource
stage BatchStage @default(CLONE_IN)
plantCount Int
startDate DateTime
harvestDate DateTime?
finishDate DateTime?
roomId String?
room Room? @relation(fields: [roomId], references: [id])
metrcTags String[] // array of METRC tag IDs
notes BatchNote[]
photos BatchPhoto[]
weights WeightLog[]
tasks Task[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Room {
id String @id @default(cuid())
name String
type RoomType
capacity Int? // plant count or sq ft
status RoomStatus @default(ACTIVE)
targetTemp Float?
targetHumidity Float?
targetVPD Float?
batches Batch[]
tasks Task[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model WeightLog {
id String @id @default(cuid())
batchId String
batch Batch @relation(fields: [batchId], references: [id])
weightType WeightType
weight Float // grams
unit String @default("g")
notes String?
photos String[] // URLs
loggedBy String
user User @relation(fields: [loggedBy], references: [id])
createdAt DateTime @default(now())
}
model BatchNote {
id String @id @default(cuid())
batchId String
batch Batch @relation(fields: [batchId], references: [id])
content String // markdown
authorId String
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
}
model BatchPhoto {
id String @id @default(cuid())
batchId String
batch Batch @relation(fields: [batchId], references: [id])
url String
caption String?
uploadedBy String
user User @relation(fields: [uploadedBy], references: [id])
createdAt DateTime @default(now())
}
enum BatchSource {
CLONE
SEED
}
enum BatchStage {
CLONE_IN
VEGETATIVE
FLOWERING
HARVEST
DRYING
CURING
FINISHED
}
enum RoomType {
VEG
FLOWER
DRY
FACILITY
}
enum RoomStatus {
ACTIVE
CLEANING
MAINTENANCE
}
enum WeightType {
WET
BUCKED
FINAL_DRY
TRIM
WASTE
}
```
### API Endpoints
- `GET /api/batches` - List batches with filters
- `GET /api/batches/:id` - Get batch detail
- `POST /api/batches` - Create batch
- `PATCH /api/batches/:id` - Update batch
- `POST /api/batches/:id/transition` - Transition batch stage
- `POST /api/batches/:id/weights` - Log weight
- `POST /api/batches/:id/notes` - Add note
- `POST /api/batches/:id/photos` - Upload photo
- `GET /api/batches/:id/timeline` - Get batch timeline
- `GET /api/batches/:id/export` - Export batch report
- `GET /api/rooms` - List rooms
- `POST /api/rooms` - Create room
- `PATCH /api/rooms/:id` - Update room
### UI Components
- `BatchList` - Filterable batch list
- `BatchCard` - Batch summary card
- `BatchDetail` - Full batch view with timeline
- `BatchForm` - Batch creation/editing
- `WeightLogForm` - Quick weight entry (mobile-optimized)
- `RoomBoard` - Kanban-style room view with batches
- `RoomDetail` - Room view with current batches and environmental data
- `BatchTimeline` - Chronological event history
---
## Dependencies
- **Tasks** module (for task history)
- **Labor** module (for cost per batch)
- **Integrations** module (for environmental data)
- **Authentication** (for user attribution)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| METRC tag mapping errors | High | Clear UI for tag entry; validation; read-only in v1 |
| Weight logging errors (typos) | Medium | Confirmation step; edit window; audit trail |
| Photo storage costs | Medium | Image compression; configurable retention policy |
---
## Future Enhancements (Post-v1)
- METRC sync (read/write)
- Automated batch transitions based on environmental triggers
- Predictive yield modeling based on historical data
- Genetic lineage tracking
- QR code batch labels for quick lookup

View file

@ -0,0 +1,360 @@
# Feature Spec: Communications and Notifications
**Domain**: Communications
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Communications and Notifications module provides team collaboration tools and notification channels to keep facility staff aligned. It includes task comments with @mentions, daily digest emails/notifications, an announcements channel for SOP changes and inspection dates, and role-based notification preferences.
---
## User Stories
### As a Staff Member
- I want to comment on tasks and @mention teammates so we can collaborate
- I want to receive a daily digest of my tasks so I know what's due today
- I want to see facility announcements so I'm aware of SOP changes and inspection dates
### As a Head Grower
- I want to post announcements about SOP changes so the team stays informed
- I want to @mention staff in task comments so they're notified of important updates
- I want to see which tasks have unresolved comments so I can follow up
### As a Compliance Manager
- I want to announce upcoming inspections so the team can prepare
- I want to ensure all staff acknowledge critical announcements
### As an Owner
- I want to configure notification preferences per role so users aren't overwhelmed
- I want to see communication history for audit purposes
---
## Requirements
### Functional Requirements
#### Task Comments and @Mentions
- **Comment on tasks**:
- Markdown-supported text
- @mention users (autocomplete)
- Attach photos (optional)
- Edit/delete own comments
- **Notifications**:
- @mentioned users receive notification
- Task assignee notified of new comments
- Notification channels: in-app, email, mobile push (optional)
- **Comment history**:
- Chronological display
- User attribution and timestamp
- Immutable after 5 minutes (edit window)
#### Daily Digest
- **Content**:
- Tasks due today
- Overdue tasks
- Upcoming key events (e.g., day-21 defoliation, harvest dates)
- Unread announcements
- **Delivery**:
- Email (default)
- In-app notification
- Mobile push (optional)
- **Timing**:
- Configurable per user (default: 7 AM)
- Skip if no tasks/events
#### Announcements Channel
- **Post announcements**:
- Title and body (markdown-supported)
- Priority (normal, important, critical)
- Target audience (all, specific roles)
- Expiration date (optional)
- **Acknowledgment**:
- Critical announcements require acknowledgment
- Track who has acknowledged
- Reminder notifications for unacknowledged
- **Display**:
- Announcement feed (chronological)
- Unread badge
- Pin important announcements
#### Notification Preferences
- **Per user**:
- Enable/disable daily digest
- Digest delivery time
- Enable/disable @mention notifications
- Enable/disable announcement notifications
- Preferred channels (email, in-app, mobile push)
- **Per role** (admin-configured defaults):
- Default notification settings for new users
### Non-Functional Requirements
- **Performance**: Notifications delivered within 1 minute
- **Reliability**: Email delivery with retry logic
- **Accessibility**: WCAG 2.1 AA compliant
- **Privacy**: Users can opt out of non-critical notifications
---
## Out of Scope (v1)
- Real-time chat (Slack/Discord-style)
- Video calls or screen sharing
- File sharing beyond task attachments
- Integration with external communication tools (Slack, Teams)
---
## Acceptance Criteria
### Task Comments
- [ ] Users can comment on tasks with markdown
- [ ] Users can @mention teammates with autocomplete
- [ ] @mentioned users receive notifications
- [ ] Comments can be edited within 5 minutes
- [ ] Comment history is chronological with timestamps
### Daily Digest
- [ ] Users receive daily digest at configured time
- [ ] Digest includes tasks due today and overdue
- [ ] Digest includes upcoming key events
- [ ] Digest includes unread announcements
- [ ] Users can configure digest time or disable
### Announcements
- [ ] Admins can post announcements with priority
- [ ] Critical announcements require acknowledgment
- [ ] Unacknowledged users receive reminders
- [ ] Announcements can be pinned
- [ ] Announcements can expire automatically
### Notification Preferences
- [ ] Users can configure notification preferences
- [ ] Admins can set default preferences per role
- [ ] Users can opt out of non-critical notifications
- [ ] Notification channels (email, in-app, push) are configurable
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model TaskComment {
id String @id @default(cuid())
taskId String
task Task @relation(fields: [taskId], references: [id])
content String // markdown
authorId String
author User @relation(fields: [authorId], references: [id])
mentions String[] // user IDs
photos String[] // URLs
editedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Announcement {
id String @id @default(cuid())
title String
content String // markdown
priority AnnouncementPriority @default(NORMAL)
targetRoles String[] // role IDs, empty = all
requiresAck Boolean @default(false)
expiresAt DateTime?
pinned Boolean @default(false)
authorId String
author User @relation(fields: [authorId], references: [id])
acknowledgments AnnouncementAck[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model AnnouncementAck {
id String @id @default(cuid())
announcementId String
announcement Announcement @relation(fields: [announcementId], references: [id])
userId String
user User @relation(fields: [userId], references: [id])
acknowledgedAt DateTime @default(now())
}
model NotificationPreference {
id String @id @default(cuid())
userId String @unique
user User @relation(fields: [userId], references: [id])
dailyDigest Boolean @default(true)
digestTime String @default("07:00") // HH:MM
mentions Boolean @default(true)
announcements Boolean @default(true)
channels Json // { email: true, inApp: true, push: false }
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Notification {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])
type NotificationType
title String
content String
link String? // deep link to related entity
read Boolean @default(false)
readAt DateTime?
createdAt DateTime @default(now())
}
enum AnnouncementPriority {
NORMAL
IMPORTANT
CRITICAL
}
enum NotificationType {
TASK_ASSIGNED
TASK_DUE
TASK_OVERDUE
TASK_COMMENT
MENTION
ANNOUNCEMENT
DIGEST
ALERT
}
```
### API Endpoints
- `GET /api/communications/comments/:taskId` - Get comments for task
- `POST /api/communications/comments` - Post comment
- `PATCH /api/communications/comments/:id` - Edit comment
- `DELETE /api/communications/comments/:id` - Delete comment
- `GET /api/communications/announcements` - List announcements
- `POST /api/communications/announcements` - Post announcement
- `POST /api/communications/announcements/:id/acknowledge` - Acknowledge announcement
- `GET /api/communications/notifications` - Get user notifications
- `PATCH /api/communications/notifications/:id/read` - Mark notification as read
- `GET /api/communications/preferences` - Get user notification preferences
- `PATCH /api/communications/preferences` - Update notification preferences
- `POST /api/communications/digest/send` - Trigger daily digest (cron job)
### UI Components
- `TaskCommentThread` - Comment thread for tasks
- `CommentForm` - Comment input with @mention autocomplete
- `AnnouncementFeed` - Announcement list with filters
- `AnnouncementCard` - Announcement display with acknowledgment
- `AnnouncementForm` - Announcement creation/editing
- `NotificationBell` - In-app notification dropdown
- `NotificationPreferences` - User notification settings
- `DigestPreview` - Preview of daily digest
---
## Dependencies
- **Tasks** module (for task comments)
- **Authentication** (for user mentions and RBAC)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| Notification fatigue | High | Configurable preferences; smart batching; daily digest |
| Email deliverability | Medium | Use reputable email service (SendGrid, Mailgun); retry logic |
| Spam/abuse of @mentions | Medium | Rate limiting; admin moderation tools |
| Missed critical announcements | High | Require acknowledgment; reminder notifications |
---
## Email Templates
### Daily Digest
```
Subject: Your tasks for [Date]
Hi [Name],
Here's your daily summary:
**Tasks Due Today** (3)
- [Task 1] - [Room/Batch]
- [Task 2] - [Room/Batch]
- [Task 3] - [Room/Batch]
**Overdue Tasks** (1)
- [Task 4] - [Room/Batch] (due [Date])
**Upcoming Events**
- Day-21 defoliation for Batch #123 (tomorrow)
- Harvest for Batch #456 (in 3 days)
**Unread Announcements** (1)
- [Announcement Title] (posted [Date])
[View Full Dashboard]
```
### @Mention Notification
```
Subject: [User] mentioned you in a task comment
Hi [Name],
[User] mentioned you in a comment on "[Task Name]":
"[Comment excerpt...]"
[View Task]
```
### Critical Announcement
```
Subject: [IMPORTANT] [Announcement Title]
Hi [Name],
A critical announcement has been posted:
[Announcement content]
Please acknowledge this announcement by [Date].
[Acknowledge Now]
```
---
## Future Enhancements (Post-v1)
- Real-time chat (Slack/Discord-style)
- Video calls or screen sharing
- File sharing beyond task attachments
- Integration with external communication tools (Slack, Teams, Discord)
- Mobile app with push notifications
- Voice-to-text for comments
- Translation for multilingual teams

View file

@ -0,0 +1,295 @@
# Feature Spec: Compliance and Documentation
**Domain**: Compliance
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Compliance and Documentation module helps California cannabis cultivation facilities maintain audit-ready records for DCC (Department of Cannabis Control) compliance. It tracks key compliance-adjacent records (taxes, utilities, invoices, payroll references), provides compliance views by month/quarter, and generates "audit packet" exports. **METRC remains the system of record for track-and-trace; this module supports adjacent recordkeeping.**
---
## User Stories
### As a Compliance Manager
- I want to upload and categorize compliance documents (PDFs, images) so they're organized and searchable
- I want to see a monthly/quarterly compliance checklist so I know what's missing
- I want to generate an audit packet (ZIP with all docs and indexes) so I'm ready for inspections
- I want to track METRC tag mappings for batches so I can cross-reference with the state system
### As an Owner
- I want to see compliance status at a glance so I know we're audit-ready
- I want to delegate compliance tasks to the Compliance Manager
- I want to ensure all financial records (taxes, invoices, payroll) are properly documented
### As an Accountant
- I want to upload invoices and bills with structured metadata so they're easy to find
- I want to export compliance records for tax preparation
---
## Requirements
### Functional Requirements
#### Document Management
- **Document types**:
- Monthly taxes (excise, sales, cultivation)
- Utility bills (SMUD, PG&E, water, gas)
- Rent/lease agreements
- CO₂ and greenhouse supply invoices
- Nutrient and material invoices
- Bills of sale
- Payroll summaries (references only, not full payroll data)
- Hours tracking exports (from Labor module)
- Licenses and permits
- Inspection reports
- SOPs (Standard Operating Procedures)
- **Document upload**:
- Drag-and-drop or file picker
- PDF, image (JPG, PNG), and CSV supported
- Automatic OCR for searchability (future enhancement)
- **Structured metadata**:
- Document type
- Date (invoice date, bill date, etc.)
- Vendor/supplier
- Amount (if applicable)
- Period covered (month/quarter)
- Tags (custom labels)
- Notes
#### Compliance Views
- **Monthly view**:
- Checklist of required documents for the month
- Status: complete, missing, pending
- Quick upload for missing items
- **Quarterly view**:
- Aggregated checklist for the quarter
- DCC-aligned categories
- **Annual view**:
- Year-end compliance summary
- License renewal reminders
#### Audit Packet Generation
- **Export format**: ZIP file containing:
- All documents for the selected period
- CSV index with metadata (filename, type, date, vendor, amount)
- JSON index for programmatic access
- README with export details
- **Filters**:
- By date range
- By document type
- By vendor
- **Encryption** (optional): Password-protected ZIP
#### METRC Tag Mapping
- **Batch-to-METRC mapping**:
- Store METRC tag IDs for each batch
- Display mapping in batch detail view
- Export mapping as CSV
- **Read-only in v1**: No direct METRC sync
### Non-Functional Requirements
- **Security**: Documents encrypted at rest
- **Access control**: Only Compliance Manager and Owner can view/edit
- **Audit trail**: All document uploads and deletions logged
- **Performance**: Document list loads in < 1 second
- **Storage**: Configurable retention policy (e.g., 7 years for tax records)
---
## Out of Scope (v1)
- Direct METRC integration (read/write)
- Automated compliance alerts based on METRC data
- OCR and automatic metadata extraction
- E-signature for documents
- Integration with accounting systems (QuickBooks, Xero)
---
## Acceptance Criteria
### Document Management
- [ ] Compliance Manager can upload documents with metadata
- [ ] Documents are categorized by type
- [ ] Documents can be searched by metadata (type, date, vendor)
- [ ] Documents can be previewed in-app (PDF, images)
- [ ] Documents can be downloaded individually
### Compliance Views
- [ ] Monthly view displays checklist of required documents
- [ ] Missing documents are highlighted
- [ ] Quick upload button for missing documents
- [ ] Quarterly and annual views aggregate monthly data
### Audit Packet
- [ ] Audit packet can be generated for a date range
- [ ] ZIP contains all documents and indexes (CSV, JSON)
- [ ] Export includes README with metadata
- [ ] Password protection is optional
### METRC Mapping
- [ ] METRC tags can be associated with batches
- [ ] Mapping is displayed in batch detail view
- [ ] Mapping can be exported as CSV
### Audit Trail
- [ ] All document uploads are logged with user and timestamp
- [ ] All document deletions are logged (soft delete)
- [ ] Audit log is exportable
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model ComplianceDocument {
id String @id @default(cuid())
type DocumentType
filename String
url String // S3 or local storage
date DateTime // invoice date, bill date, etc.
vendor String?
amount Float?
period String? // "2025-01" for January 2025
tags String[] // custom labels
notes String?
uploadedBy String
user User @relation(fields: [uploadedBy], references: [id])
deletedAt DateTime? // soft delete
deletedBy String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum DocumentType {
TAX_MONTHLY
UTILITY_BILL
RENT_LEASE
CO2_INVOICE
NUTRIENT_INVOICE
BILL_OF_SALE
PAYROLL_SUMMARY
HOURS_EXPORT
LICENSE_PERMIT
INSPECTION_REPORT
SOP
OTHER
}
model AuditLog {
id String @id @default(cuid())
action String // "upload", "delete", "edit"
entityType String // "ComplianceDocument", "Batch", etc.
entityId String
userId String
user User @relation(fields: [userId], references: [id])
metadata Json? // additional context
createdAt DateTime @default(now())
}
```
### API Endpoints
- `GET /api/compliance/documents` - List documents with filters
- `GET /api/compliance/documents/:id` - Get document detail
- `POST /api/compliance/documents` - Upload document
- `PATCH /api/compliance/documents/:id` - Update document metadata
- `DELETE /api/compliance/documents/:id` - Soft delete document
- `GET /api/compliance/documents/:id/download` - Download document
- `GET /api/compliance/checklist/:period` - Get compliance checklist for period
- `POST /api/compliance/audit-packet` - Generate audit packet
- `GET /api/compliance/metrc-mapping` - Get METRC tag mappings
- `GET /api/compliance/audit-log` - Get audit log
### UI Components
- `DocumentUploader` - Drag-and-drop upload with metadata form
- `DocumentList` - Filterable list of documents
- `DocumentPreview` - In-app PDF/image viewer
- `ComplianceChecklist` - Monthly/quarterly checklist view
- `AuditPacketGenerator` - Export interface with filters
- `MetrcMappingTable` - Batch-to-METRC tag mapping
- `AuditLogViewer` - Audit trail display
---
## Dependencies
- **Batches and Rooms** module (for METRC mapping)
- **Labor** module (for payroll/hours exports)
- **Authentication** (for RBAC and audit trail)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| Document storage costs | Medium | Configurable retention policy; compression |
| Missing documents at audit time | High | Proactive checklists; monthly reminders |
| METRC mapping errors | High | Clear UI; validation; read-only in v1 |
| Data breach (sensitive financial docs) | High | Encryption at rest; strict access control; audit trail |
---
## Compliance Notes (California DCC)
### Key Recordkeeping Requirements
Per California DCC regulations, licensed cannabis businesses must maintain:
- **Financial records**: Invoices, receipts, bank statements, tax filings (7 years)
- **Inventory records**: METRC is the system of record; internal records must align
- **Labor records**: Hours, wages, payroll (4 years minimum)
- **Licenses and permits**: Current and historical
- **Inspection reports**: All DCC and local inspections
- **SOPs**: Current versions and change history
### Audit Preparation
- **Quarterly self-audits** recommended
- **Audit packet** should include:
- All financial records for the period
- METRC reconciliation reports
- Labor and payroll summaries
- Licenses and permits
- Inspection reports
- SOPs
### Resources
- [California DCC Regulations](https://cannabis.ca.gov/cannabis-laws/dcc-regulations/)
- [METRC California Guide](https://www.metrc.com/california)
- [DCC Compliance Checklist](https://cannabis.ca.gov/licensees/compliance-hub/)
---
## Future Enhancements (Post-v1)
- OCR and automatic metadata extraction
- METRC integration (read/write with user confirmation)
- Automated compliance alerts (e.g., "Missing utility bill for March")
- E-signature for SOPs and inspection reports
- Integration with accounting systems (QuickBooks, Xero)
- Automated tax filing reminders

View file

@ -0,0 +1,334 @@
# Feature Spec: Integrations and Hardware
**Domain**: Integrations
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Integrations and Hardware module connects CA Grow Ops Manager to external systems and environmental monitoring hardware. Phase 1 (v1) focuses on read-only environmental dashboards and manual status widgets. Phase 2 (future) adds METRC connector and advanced hardware integrations.
---
## User Stories
### As a Head Grower
- I want to see real-time environmental data (temp, humidity, VPD) for each room so I can identify issues quickly
- I want to see lighting schedule status so I know if lights are on/off as expected
- I want to receive alerts when environmental conditions go out of range
### As a Staff Member
- I want to see current room conditions on my tablet so I can verify everything is normal
### As a Compliance Manager
- I want to export environmental data for audit purposes
- I want to sync METRC data (future) so internal records align with the state system
### As an Owner
- I want to integrate with METRC (future) so we reduce duplicate data entry
- I want to see environmental trends over time so I can optimize growing conditions
---
## Requirements
### Functional Requirements (Phase 1 - v1)
#### Environmental Dashboards
- **Data sources**:
- CSV uploads (manual)
- API polling (if available from monitoring systems)
- Manual entry (fallback)
- **Metrics per room**:
- Temperature (°F or °C)
- Humidity (%)
- VPD (kPa)
- CO₂ (ppm) (optional)
- **Display**:
- Current values
- Target ranges (from room settings)
- Status indicators (in range, warning, critical)
- Historical charts (24h, 7d, 30d)
- **Alerts**:
- Out-of-range notifications
- Sensor offline alerts
#### Lighting Schedule Widgets
- **Data sources**:
- Manual entry (on/off times, photoperiod)
- API polling (if available from controllers like Trollmaster, Growers Choice)
- **Display**:
- Current status (on/off)
- Schedule (on/off times)
- Photoperiod (18/6, 12/12, etc.)
- Next state change countdown
### Functional Requirements (Phase 2 - Future)
#### METRC Connector
- **Configuration**:
- API key management
- Rate limiting settings
- Explicit user confirmation before writes
- **Read operations**:
- Sync METRC plant/batch tags
- Sync inventory data
- Sync transfer data
- **Write operations** (with user confirmation):
- Create plant tags
- Update plant stages
- Log harvests
- Create packages
- **Error handling**:
- Retry logic with exponential backoff
- Clear error messages
- Rollback on failure
#### Advanced Hardware Integrations
- **Adapter framework**:
- Plugin architecture for new hardware
- Standardized data models
- Polling intervals and caching
- **Supported systems** (examples):
- Trollmaster environmental controllers
- Growers Choice lighting systems
- Pulse environmental monitors
- Aroya crop steering systems
- **Graceful degradation**:
- Manual fallback for all automated inputs
- Clear offline/error states
### Non-Functional Requirements
- **Performance**: Environmental data updates every 5-15 minutes
- **Reliability**: Graceful degradation when integrations are unavailable
- **Security**: API keys encrypted at rest; least privilege access
- **Auditability**: All METRC writes logged with user confirmation
---
## Out of Scope (v1)
- METRC write integration (read-only mapping only)
- Automated environmental control (read-only dashboards only)
- Predictive analytics based on environmental data
- Integration with irrigation systems
---
## Acceptance Criteria (Phase 1 - v1)
### Environmental Dashboards
- [ ] Environmental data can be uploaded via CSV
- [ ] Environmental data can be polled from API (if available)
- [ ] Current temp, humidity, VPD displayed per room
- [ ] Status indicators show in-range, warning, critical
- [ ] Historical charts display 24h, 7d, 30d data
- [ ] Alerts generated when conditions go out of range
### Lighting Schedule Widgets
- [ ] Lighting schedules can be entered manually
- [ ] Current on/off status displayed
- [ ] Next state change countdown displayed
- [ ] Photoperiod displayed (18/6, 12/12, etc.)
### Integration Framework
- [ ] Adapter pattern supports multiple data sources
- [ ] Manual fallback available for all automated inputs
- [ ] Clear error handling and offline states
---
## Acceptance Criteria (Phase 2 - Future)
### METRC Connector
- [ ] API keys can be configured and encrypted
- [ ] METRC tags can be synced (read-only)
- [ ] User confirmation required before any write operation
- [ ] All METRC writes logged with user and timestamp
- [ ] Error handling with retry logic and clear messages
### Advanced Hardware
- [ ] Plugin architecture supports new hardware adapters
- [ ] Polling intervals configurable per adapter
- [ ] Data cached to reduce API calls
- [ ] Graceful degradation when hardware is offline
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model EnvironmentalReading {
id String @id @default(cuid())
roomId String
room Room @relation(fields: [roomId], references: [id])
temperature Float? // °F or °C
humidity Float? // %
vpd Float? // kPa
co2 Float? // ppm
timestamp DateTime
source String // "manual", "csv", "api:pulse", etc.
createdAt DateTime @default(now())
}
model IntegrationConfig {
id String @id @default(cuid())
type IntegrationType
name String
apiKey String? // encrypted
apiUrl String?
pollingInterval Int? // minutes
enabled Boolean @default(true)
settings Json? // integration-specific settings
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model MetrcSync {
id String @id @default(cuid())
batchId String?
batch Batch? @relation(fields: [batchId], references: [id])
metrcTag String
operation String // "read", "write"
action String // "sync_tags", "create_plant", "log_harvest", etc.
status SyncStatus
requestData Json?
responseData Json?
error String?
userId String?
user User? @relation(fields: [userId], references: [id])
confirmedAt DateTime?
createdAt DateTime @default(now())
}
enum IntegrationType {
METRC
ENVIRONMENTAL
LIGHTING
IRRIGATION
OTHER
}
enum SyncStatus {
PENDING
CONFIRMED
SUCCESS
FAILED
}
```
### API Endpoints (Phase 1)
- `GET /api/integrations/environmental/:roomId` - Get environmental data for room
- `POST /api/integrations/environmental/upload` - Upload CSV environmental data
- `GET /api/integrations/environmental/:roomId/chart` - Get historical chart data
- `GET /api/integrations/lighting/:roomId` - Get lighting schedule for room
- `POST /api/integrations/lighting/:roomId` - Update lighting schedule
- `GET /api/integrations/config` - List integration configs
- `POST /api/integrations/config` - Create integration config
- `PATCH /api/integrations/config/:id` - Update integration config
### API Endpoints (Phase 2)
- `POST /api/integrations/metrc/sync-tags` - Sync METRC tags (read-only)
- `POST /api/integrations/metrc/create-plant` - Create plant in METRC (with confirmation)
- `POST /api/integrations/metrc/log-harvest` - Log harvest in METRC (with confirmation)
- `GET /api/integrations/metrc/sync-history` - Get METRC sync history
### UI Components
- `EnvironmentalDashboard` - Room environmental data display
- `EnvironmentalChart` - Historical chart (24h, 7d, 30d)
- `LightingWidget` - Lighting schedule and status
- `IntegrationConfig` - Integration setup and management
- `MetrcConnector` - METRC sync interface (Phase 2)
- `MetrcConfirmation` - User confirmation dialog for METRC writes (Phase 2)
---
## Dependencies
- **Batches and Rooms** module (for room context)
- **Authentication** (for RBAC and audit trail)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| METRC API downtime | High | Graceful degradation; manual fallback; clear error messages |
| METRC write errors (data loss) | Critical | User confirmation; rollback on failure; audit trail |
| Hardware API changes | Medium | Adapter pattern; versioning; clear deprecation notices |
| API rate limits | Medium | Caching; configurable polling intervals; exponential backoff |
---
## Integration Strategy
### Adapter Pattern
Each integration implements a standard adapter interface:
```typescript
interface IntegrationAdapter {
name: string;
type: IntegrationType;
connect(config: IntegrationConfig): Promise<void>;
disconnect(): Promise<void>;
poll(): Promise<any>;
write?(data: any): Promise<any>;
healthCheck(): Promise<boolean>;
}
```
### Polling and Caching
- **Polling intervals**: Configurable per integration (default: 5-15 minutes)
- **Caching**: Cache data for 5 minutes to reduce API calls
- **Error handling**: Exponential backoff on failures; max 3 retries
### User Confirmation for Writes
- **METRC writes**: Require explicit user confirmation with preview of changes
- **Audit trail**: Log all write operations with user, timestamp, and result
- **Rollback**: Attempt rollback on failure; flag for manual review if rollback fails
---
## Compliance Notes (METRC)
- **METRC is the system of record** for California cannabis track-and-trace
- **Read-only in v1**: Internal batch IDs map to METRC tags but no writes
- **Phase 2 writes**: Require explicit user confirmation and robust error handling
- **Audit trail**: All METRC operations logged for compliance
---
## Future Enhancements (Post-v1)
- METRC connector with read/write (Phase 2)
- Advanced hardware integrations (Trollmaster, Aroya, etc.)
- Automated environmental control (set points, alerts)
- Predictive analytics based on environmental data
- Integration with irrigation systems
- Mobile app for environmental monitoring

View file

@ -0,0 +1,318 @@
# Feature Spec: Inventory and Materials
**Domain**: Inventory
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Inventory and Materials module tracks cultivation supplies (nutrients, pots, IPM products, PPE, CO₂ tanks, filters, soil/media, packaging) with quantity tracking, min/max thresholds, restock prompts, and optional lot/serial linkage to batches for recall support.
---
## User Stories
### As a Head Grower
- I want to track current inventory levels so I know what's in stock
- I want to set min/max thresholds so I'm alerted when supplies are low
- I want to link material lots to batches so I can trace issues back to specific inputs
- I want to see material usage trends so I can optimize ordering
### As a Staff Member
- I want to quickly check if we have enough nutrients for today's feed so I don't run out mid-task
- I want to log material usage so inventory stays accurate
### As an Owner
- I want to see material costs per batch so I can calculate profitability
- I want to track supplier performance (quality, delivery time)
### As a Compliance Manager
- I want to link material lots to batches so I can support recall investigations
---
## Requirements
### Functional Requirements
#### Item Catalog
- **Item types**:
- Nutrients (base, additives, supplements)
- Growing media (soil, coco, rockwool)
- Pots and containers
- IPM products (pesticides, beneficial insects)
- PPE (gloves, masks, suits)
- CO₂ tanks and regulators
- Filters (carbon, HEPA)
- Packaging (jars, bags, labels)
- Tools and equipment
- **Item properties**:
- Name and SKU
- Category
- Unit (gallon, pound, each, etc.)
- Current quantity
- Min/max thresholds
- Location (room, shelf)
- Supplier
- Lot/serial number (optional)
- Expiration date (optional)
- Cost per unit
- Notes
#### Inventory Tracking
- **Add stock**: Log new deliveries with quantity, lot, and cost
- **Use stock**: Log material usage with quantity, batch, and user
- **Adjust stock**: Manual adjustments with reason and approval
- **Transfer stock**: Move items between locations
- **Automatic updates**: Deduct stock when linked to task completion (future)
#### Restock Alerts
- **Min threshold alerts**: Notify when quantity falls below minimum
- **Expiration alerts**: Notify when items approach expiration
- **Restock suggestions**: Based on usage trends
#### Lot/Serial Tracking
- **Link lots to batches**: Associate material lots with batches for traceability
- **Recall support**: Query which batches used a specific lot
- **Supplier traceability**: Track materials back to supplier and purchase order
#### Reporting
- **Current inventory**: List of all items with quantities
- **Low stock report**: Items below min threshold
- **Usage report**: Material usage by item, batch, period
- **Cost report**: Material costs per batch
- **Expiration report**: Items expiring soon
### Non-Functional Requirements
- **Performance**: Inventory list loads in < 500ms
- **Data integrity**: Stock adjustments require reason and approval
- **Accessibility**: WCAG 2.1 AA compliant
- **Mobile-first**: Stock usage logging optimized for tablet
---
## Out of Scope (v1)
- Automated reordering (integration with suppliers)
- Barcode/QR code scanning
- Multi-location inventory (single facility only in v1)
- Integration with accounting systems for purchase orders
---
## Acceptance Criteria
### Item Catalog
- [ ] Items can be created with all required properties
- [ ] Items can be categorized by type
- [ ] Items can be searched and filtered
- [ ] Min/max thresholds can be set per item
### Inventory Tracking
- [ ] Stock can be added with lot and cost
- [ ] Stock can be used with batch linkage
- [ ] Stock adjustments require reason and approval
- [ ] Stock transfers are logged with user and timestamp
### Restock Alerts
- [ ] Alerts are generated when quantity falls below min threshold
- [ ] Alerts are generated for items expiring within 30 days
- [ ] Alerts can be dismissed or actioned
### Lot/Serial Tracking
- [ ] Lots can be linked to batches
- [ ] Recall query returns all batches using a specific lot
- [ ] Lot history is immutable
### Reporting
- [ ] Current inventory report displays all items with quantities
- [ ] Low stock report displays items below min threshold
- [ ] Usage report displays material usage by batch
- [ ] Cost report displays material costs per batch
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model InventoryItem {
id String @id @default(cuid())
name String
sku String? @unique
category ItemCategory
unit String // gallon, pound, each, etc.
quantity Float
minThreshold Float?
maxThreshold Float?
location String?
supplierId String?
supplier Supplier? @relation(fields: [supplierId], references: [id])
costPerUnit Float?
notes String?
lots InventoryLot[]
transactions InventoryTransaction[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model InventoryLot {
id String @id @default(cuid())
itemId String
item InventoryItem @relation(fields: [itemId], references: [id])
lotNumber String
serialNumber String?
quantity Float
expirationDate DateTime?
receivedDate DateTime
supplierId String?
supplier Supplier? @relation(fields: [supplierId], references: [id])
batchLinks BatchMaterialLink[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model InventoryTransaction {
id String @id @default(cuid())
itemId String
item InventoryItem @relation(fields: [itemId], references: [id])
type TransactionType
quantity Float
lotId String?
lot InventoryLot? @relation(fields: [lotId], references: [id])
batchId String?
batch Batch? @relation(fields: [batchId], references: [id])
userId String
user User @relation(fields: [userId], references: [id])
reason String?
approvedBy String?
approvedAt DateTime?
createdAt DateTime @default(now())
}
model BatchMaterialLink {
id String @id @default(cuid())
batchId String
batch Batch @relation(fields: [batchId], references: [id])
lotId String
lot InventoryLot @relation(fields: [lotId], references: [id])
quantityUsed Float
usedAt DateTime @default(now())
userId String
user User @relation(fields: [userId], references: [id])
}
model Supplier {
id String @id @default(cuid())
name String
contact String?
email String?
phone String?
address String?
notes String?
items InventoryItem[]
lots InventoryLot[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum ItemCategory {
NUTRIENT
MEDIA
POT
IPM
PPE
CO2
FILTER
PACKAGING
TOOL
OTHER
}
enum TransactionType {
ADD
USE
ADJUST
TRANSFER
}
```
### API Endpoints
- `GET /api/inventory/items` - List items with filters
- `GET /api/inventory/items/:id` - Get item detail
- `POST /api/inventory/items` - Create item
- `PATCH /api/inventory/items/:id` - Update item
- `DELETE /api/inventory/items/:id` - Delete item
- `POST /api/inventory/transactions` - Log transaction (add, use, adjust)
- `GET /api/inventory/transactions` - List transactions
- `GET /api/inventory/lots` - List lots
- `POST /api/inventory/lots` - Create lot
- `GET /api/inventory/lots/:id/batches` - Get batches using a lot (recall query)
- `GET /api/inventory/alerts` - Get restock and expiration alerts
- `GET /api/inventory/reports/current` - Current inventory report
- `GET /api/inventory/reports/low-stock` - Low stock report
- `GET /api/inventory/reports/usage` - Usage report
- `GET /api/inventory/reports/cost` - Cost report
- `GET /api/inventory/suppliers` - List suppliers
- `POST /api/inventory/suppliers` - Create supplier
### UI Components
- `InventoryList` - Filterable list of items
- `InventoryCard` - Item summary card with quantity gauge
- `InventoryDetail` - Full item view with transaction history
- `InventoryForm` - Item creation/editing
- `TransactionForm` - Add/use/adjust stock form
- `LotTracker` - Lot/serial tracking interface
- `RecallQuery` - Recall investigation tool
- `RestockAlerts` - Alert dashboard
- `InventoryReports` - Reporting interface
---
## Dependencies
- **Batches and Rooms** module (for batch linkage)
- **Tasks** module (for automatic stock deduction on task completion)
- **Authentication** (for user attribution and RBAC)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| Inventory drift (physical vs. system) | High | Regular physical counts; adjustment approval workflow |
| Lot tracking errors | Medium | Clear UI; validation; immutable lot history |
| Restock alert fatigue | Medium | Configurable thresholds; smart batching of alerts |
---
## Future Enhancements (Post-v1)
- Barcode/QR code scanning for quick stock updates
- Automated reordering based on usage trends
- Integration with supplier systems for purchase orders
- Multi-location inventory (multiple facilities)
- Predictive restock suggestions based on batch schedules
- Integration with accounting systems (QuickBooks, Xero)

272
specs/labor-and-hours.md Normal file
View file

@ -0,0 +1,272 @@
# Feature Spec: Labor and Hours
**Domain**: Labor
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Labor and Hours module provides a web/mobile timeclock for staff to track their hours, associate time to specific rooms and batches for cost visibility, and generate reports for payroll and batch profitability analysis. It does NOT process payroll but provides CSV exports suitable for external payroll systems.
---
## User Stories
### As a Staff Member
- I want to clock in and out quickly on a tablet so I can start working without friction
- I want to select which room or batch I'm working on so my time is attributed correctly
- I want to add notes about what I did during my shift so there's a record
### As a Head Grower
- I want to see which staff are currently clocked in and where they're working so I can coordinate tasks
- I want to see labor hours per batch so I can identify which batches are labor-intensive
### As an Owner
- I want to see labor costs per batch so I can calculate profitability
- I want to export hours data for payroll processing
- I want to see labor cost trends over time
### As an Accountant
- I want to export hours data in a format compatible with our payroll system (CSV)
- I want to see labor hours broken down by user, period, and cost center (room/batch)
---
## Requirements
### Functional Requirements
#### Timeclock
- **Clock in**:
- Select room or batch (optional but encouraged)
- Add start-of-shift notes (optional)
- Timestamp recorded
- **Clock out**:
- Add end-of-shift notes (optional)
- Timestamp recorded
- Duration calculated automatically
- **Break tracking** (optional for v1)
- **Edit time entries** (with audit trail, manager approval required)
- **Mobile-optimized**: Large buttons, minimal steps
#### Roles and Wage Rates
- **User roles**:
- Owner
- Compliance Manager
- Head Grower
- Grower
- Trimmer
- Maintenance
- **Wage rates**:
- Hourly rate per role
- Effective date for rate changes
- Historical rate tracking
- **Cost calculations**:
- Hours × wage rate = labor cost
- Aggregated by user, room, batch, period
#### Reporting
- **Hours per user, per period**:
- Daily, weekly, bi-weekly, monthly
- Total hours and estimated cost
- **Labor hours and cost per room/batch**:
- Breakdown by user
- Percentage of total labor
- **CSV exports**:
- User, date, clock in, clock out, duration, room, batch, notes
- Compatible with common payroll systems (ADP, Gusto, QuickBooks)
#### Who's Working Now
- **Live dashboard**:
- Currently clocked-in staff
- Room/batch assignment
- Duration of current shift
- **Manager view**: See all active shifts
### Non-Functional Requirements
- **Performance**: Clock in/out completes in < 1 second
- **Data integrity**: Time entries are immutable once saved (edits create new records with audit trail)
- **Accessibility**: WCAG 2.1 AA compliant
- **Mobile-first**: Timeclock optimized for tablet use
---
## Out of Scope (v1)
- Payroll processing (taxes, deductions, direct deposit)
- PTO/vacation tracking
- Shift scheduling (handled by Tasks module)
- Biometric clock-in (fingerprint, facial recognition)
- GPS-based clock-in verification
---
## Acceptance Criteria
### Timeclock
- [ ] Staff can clock in with room/batch selection in ≤ 3 taps
- [ ] Staff can clock out with notes in ≤ 2 taps
- [ ] Clock in/out timestamps are accurate to the second
- [ ] Duration is calculated automatically
- [ ] Time entries are immutable once saved
### Roles and Wage Rates
- [ ] Roles can be created and assigned to users
- [ ] Wage rates can be set per role with effective dates
- [ ] Historical wage rates are preserved
- [ ] Labor cost is calculated correctly (hours × rate)
### Reporting
- [ ] Hours per user report displays total hours and cost
- [ ] Labor cost per room/batch report displays breakdown by user
- [ ] CSV export includes all required fields for payroll
- [ ] Reports can be filtered by date range
### Who's Working Now
- [ ] Dashboard displays currently clocked-in staff
- [ ] Room/batch assignments are visible
- [ ] Shift duration updates in real-time
### Audit Trail
- [ ] Time entry edits create new records with original preserved
- [ ] Edits require manager approval
- [ ] Audit log displays all changes with user and timestamp
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model TimeEntry {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])
clockIn DateTime
clockOut DateTime?
duration Int? // minutes, calculated on clock out
roomId String?
room Room? @relation(fields: [roomId], references: [id])
batchId String?
batch Batch? @relation(fields: [batchId], references: [id])
notes String?
editedBy String?
editedAt DateTime?
originalId String? // if this is an edit, reference to original
original TimeEntry? @relation("TimeEntryEdits", fields: [originalId], references: [id])
edits TimeEntry[] @relation("TimeEntryEdits")
approved Boolean @default(false)
approvedBy String?
approvedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Role {
id String @id @default(cuid())
name String @unique
description String?
users User[]
wageRates WageRate[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model WageRate {
id String @id @default(cuid())
roleId String
role Role @relation(fields: [roleId], references: [id])
hourlyRate Float
effectiveDate DateTime
endDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model User {
id String @id @default(cuid())
email String @unique
name String
roleId String?
role Role? @relation(fields: [roleId], references: [id])
timeEntries TimeEntry[]
// ... other user fields
}
```
### API Endpoints
- `POST /api/labor/clock-in` - Clock in
- `POST /api/labor/clock-out` - Clock out
- `GET /api/labor/current-shift` - Get current shift for user
- `GET /api/labor/time-entries` - List time entries with filters
- `PATCH /api/labor/time-entries/:id` - Edit time entry (creates new record)
- `POST /api/labor/time-entries/:id/approve` - Approve time entry edit
- `GET /api/labor/whos-working` - Get currently clocked-in staff
- `GET /api/labor/reports/hours-per-user` - Hours per user report
- `GET /api/labor/reports/cost-per-batch` - Labor cost per batch
- `GET /api/labor/reports/cost-per-room` - Labor cost per room
- `GET /api/labor/export` - Export time entries to CSV
- `GET /api/labor/roles` - List roles
- `POST /api/labor/roles` - Create role
- `GET /api/labor/wage-rates` - List wage rates
- `POST /api/labor/wage-rates` - Create wage rate
### UI Components
- `TimeclockWidget` - Clock in/out interface (mobile-optimized)
- `WhosWorkingDashboard` - Live view of clocked-in staff
- `TimeEntryList` - List of time entries with filters
- `TimeEntryEditForm` - Edit time entry (manager only)
- `HoursReport` - Hours per user report
- `LaborCostReport` - Labor cost per batch/room
- `RoleManagement` - Role and wage rate management
- `PayrollExport` - CSV export interface
---
## Dependencies
- **Batches and Rooms** module (for time attribution)
- **Authentication** (for user identification and RBAC)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| Users forget to clock out | High | Auto-clock-out after configurable duration; daily reminders |
| Time entry fraud (buddy punching) | Medium | Audit trail; manager review; future: biometric verification |
| Wage rate errors | Medium | Historical rate tracking; approval workflow for changes |
| Export format incompatibility | Medium | Support multiple export formats; customizable field mapping |
---
## Future Enhancements (Post-v1)
- Break tracking
- Shift scheduling integration
- PTO/vacation tracking
- Biometric clock-in (fingerprint, facial recognition)
- GPS-based clock-in verification
- Overtime calculations and alerts
- Integration with payroll systems (ADP, Gusto, QuickBooks)

View file

@ -0,0 +1,246 @@
# Feature Spec: Tasks and Scheduling
**Domain**: CultivationOps
**Status**: Draft
**Version**: 0.1.0
**Last Updated**: 2025-12-08
---
## Overview
The Tasks and Scheduling module enables cultivation teams to create, assign, and track recurring and one-off tasks across different room types (veg, flower, dry, facility). It provides room-based task templates, calendar and list views, and a simplified "Today / This Week" view optimized for on-shift workers.
---
## User Stories
### As a Head Grower
- I want to create task templates for each room type (veg, flower, dry, facility) so that recurring operations are standardized
- I want to schedule tasks on a calendar so I can visualize the workload across the week
- I want to assign tasks to specific staff members so accountability is clear
- I want to see task completion status so I can track progress and identify blockers
### As a Staff Member
- I want to see my tasks for today in a simple list so I can complete them efficiently
- I want to mark tasks as complete with notes and photos so the team has a record
- I want to see upcoming tasks for the week so I can plan my time
- I want to filter tasks by room or batch so I can focus on specific areas
### As a Compliance Manager
- I want to see a history of completed tasks with timestamps and assignees so I can demonstrate SOP compliance
- I want to export task logs for audit purposes
---
## Requirements
### Functional Requirements
#### Task Templates
- **Room-based templates** for:
- **Veg Room**: clones, up-potting, watering schedule, IPM schedule, tagging, move-to-flower
- **Flower Room**: feed schedule, IPM plan, day-21 pruning, pre-harvest deleaf, harvest and weights
- **Dry/Cure**: hang, burp, transfer, packaging
- **Facility**: cleaning, maintenance, "fix it" items, materials checks
- Templates include:
- Task name and description
- Estimated duration
- Required materials/tools
- Instructions or SOP links
- Recurrence pattern (daily, weekly, custom)
#### Task Scheduling
- **Calendar view** (month, week, day)
- **List view** with filters:
- By room
- By batch
- By assignee
- By status (pending, in progress, complete, overdue)
- **Drag-and-drop** rescheduling (calendar view)
- **Bulk actions** (assign, reschedule, mark complete)
#### Task Execution
- **Today / This Week view** optimized for mobile/tablet:
- Large tap targets
- Minimal clutter
- Quick complete/defer actions
- **Task detail view**:
- Instructions and materials
- Batch/room context
- Add notes and photos
- Mark complete with timestamp
- **Notifications** for:
- Tasks due today
- Overdue tasks
- Newly assigned tasks
#### Task History & Audit Trail
- **Immutable log** of all task completions
- **Metadata**: assignee, completion time, notes, photos
- **Export** to CSV/JSON for compliance
### Non-Functional Requirements
- **Performance**: Task list loads in < 500ms
- **Offline support**: Tasks viewable offline; completion syncs when online
- **Accessibility**: WCAG 2.1 AA compliant
- **Mobile-first**: All workflows completable on tablet
---
## Out of Scope (v1)
- Advanced project management features (dependencies, Gantt charts)
- Time tracking per task (handled by Labor module)
- External calendar integrations (Google Calendar, Outlook)
- AI-powered task suggestions
---
## Acceptance Criteria
### Template Management
- [ ] Head Grower can create a task template for each room type
- [ ] Templates can be edited and versioned
- [ ] Templates can be duplicated for customization
### Task Scheduling
- [ ] Tasks can be created from templates or from scratch
- [ ] Tasks can be assigned to specific users or roles
- [ ] Calendar view displays all scheduled tasks
- [ ] List view supports filtering by room, batch, assignee, status
### Task Execution
- [ ] Staff can view their tasks for today in a simplified view
- [ ] Staff can mark tasks complete with notes and photos
- [ ] Completed tasks are logged with timestamp and assignee
- [ ] Overdue tasks are highlighted
### Notifications
- [ ] Users receive daily digest of tasks due today
- [ ] Users receive alerts for overdue tasks
- [ ] Notifications are configurable per user
### Audit & Export
- [ ] Task history is immutable and timestamped
- [ ] Task logs can be exported to CSV
- [ ] Export includes all metadata (assignee, notes, photos)
---
## Technical Notes
### Data Model (Prisma Schema)
```prisma
model TaskTemplate {
id String @id @default(cuid())
name String
description String?
roomType RoomType
estimatedDuration Int? // minutes
materials String[] // array of material names
instructions String?
recurrence Json? // cron-like pattern
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tasks Task[]
}
model Task {
id String @id @default(cuid())
templateId String?
template TaskTemplate? @relation(fields: [templateId], references: [id])
name String
description String?
roomId String?
room Room? @relation(fields: [roomId], references: [id])
batchId String?
batch Batch? @relation(fields: [batchId], references: [id])
assigneeId String?
assignee User? @relation(fields: [assigneeId], references: [id])
status TaskStatus @default(PENDING)
dueDate DateTime
completedAt DateTime?
notes String?
photos String[] // URLs
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum TaskStatus {
PENDING
IN_PROGRESS
COMPLETE
OVERDUE
}
enum RoomType {
VEG
FLOWER
DRY
FACILITY
}
```
### API Endpoints
- `GET /api/tasks` - List tasks with filters
- `GET /api/tasks/:id` - Get task detail
- `POST /api/tasks` - Create task
- `PATCH /api/tasks/:id` - Update task
- `DELETE /api/tasks/:id` - Delete task
- `POST /api/tasks/:id/complete` - Mark task complete
- `GET /api/tasks/templates` - List task templates
- `POST /api/tasks/templates` - Create task template
- `GET /api/tasks/export` - Export task history
### UI Components
- `TaskCalendar` - Calendar view with drag-and-drop
- `TaskList` - Filterable list view
- `TaskCard` - Task summary card
- `TaskDetail` - Full task view with completion form
- `TodayView` - Simplified mobile-optimized view
- `TaskTemplateForm` - Template creation/editing
---
## Dependencies
- **Batches and Rooms** module (for task context)
- **Labor** module (for assignee data)
- **Authentication** (for user assignment and audit trail)
---
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| Template complexity overwhelms users | High | Start with simple templates; iterate based on feedback |
| Offline sync conflicts | Medium | Use optimistic UI updates; clear conflict resolution UX |
| Notification fatigue | Medium | Make notifications configurable; use smart batching |
---
## Future Enhancements (Post-v1)
- Task dependencies and workflows
- Recurring task auto-generation
- Integration with external calendars
- Voice-to-text for task notes
- AI-powered task duration estimates