HIGH PRIORITY: Fixes production 404 error on research inquiry form Research Inquiry API: - Add POST /api/research-inquiry endpoint for form submissions - Add admin endpoints for inquiry management (list, get, assign, respond, delete) - Create ResearchInquiry model with MongoDB integration - Add to moderation queue for human review (strategic quadrant) - Include rate limiting (5 req/min) and CSRF protection - Tested locally: endpoint responding, data saving to DB Umami Analytics (Privacy-First): - Add Docker Compose config for Umami + PostgreSQL - Create nginx reverse proxy config with SSL support - Implement privacy-first tracking script (DNT, opt-out, no cookies) - Integrate tracking across 26 public HTML pages - Exclude admin pages from tracking (privacy boundary) - Add comprehensive deployment guide (UMAMI_SETUP_GUIDE.md) - Environment variables added to .env.example Files Created (9): - src/models/ResearchInquiry.model.js - src/controllers/research.controller.js - src/routes/research.routes.js - public/js/components/umami-tracker.js - deployment-quickstart/nginx-analytics.conf - deployment-quickstart/UMAMI_SETUP_GUIDE.md - scripts/add-umami-tracking.sh - scripts/add-tracking-python.py - SESSION_SUMMARY_ANALYTICS_RESEARCH_INQUIRY.md Files Modified (29): - src/routes/index.js (research routes) - deployment-quickstart/docker-compose.yml (umami services) - deployment-quickstart/.env.example (umami config) - 26 public HTML pages (tracking script) Values Alignment: ✅ Privacy-First Design (cookie-free, DNT honored, opt-out available) ✅ Human Agency (research inquiries require human review) ✅ Data Sovereignty (self-hosted analytics, no third-party sharing) ✅ GDPR Compliance (no personal data in analytics) ✅ Transparency (open-source tools, documented setup) Testing Status: ✅ Research inquiry: Locally tested, data verified in MongoDB ⏳ Umami analytics: Pending production deployment Next Steps: 1. Deploy to production (./scripts/deploy.sh) 2. Test research form on live site 3. Deploy Umami following UMAMI_SETUP_GUIDE.md 4. Update umami-tracker.js with website ID after setup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
152 lines
4.4 KiB
YAML
152 lines
4.4 KiB
YAML
version: '3.8'
|
|
|
|
services:
|
|
# MongoDB Database
|
|
mongodb:
|
|
image: mongo:7.0
|
|
container_name: tractatus-mongodb
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${MONGODB_PORT:-27017}:27017"
|
|
environment:
|
|
MONGO_INITDB_ROOT_USERNAME: ${MONGODB_USERNAME:-tractatus}
|
|
MONGO_INITDB_ROOT_PASSWORD: ${MONGODB_PASSWORD:-changeme}
|
|
MONGO_INITDB_DATABASE: ${MONGODB_DATABASE:-tractatus_prod}
|
|
volumes:
|
|
- mongodb_data:/data/db
|
|
- mongodb_config:/data/configdb
|
|
networks:
|
|
- tractatus-network
|
|
healthcheck:
|
|
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Tractatus Application
|
|
tractatus-app:
|
|
build:
|
|
context: ..
|
|
dockerfile: deployment-quickstart/Dockerfile
|
|
container_name: tractatus-app
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${APP_PORT:-9000}:9000"
|
|
environment:
|
|
NODE_ENV: ${NODE_ENV:-production}
|
|
PORT: 9000
|
|
MONGODB_URI: mongodb://${MONGODB_USERNAME:-tractatus}:${MONGODB_PASSWORD:-changeme}@mongodb:27017/${MONGODB_DATABASE:-tractatus_prod}?authSource=admin
|
|
JWT_SECRET: ${JWT_SECRET}
|
|
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
|
|
ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@tractatus.local}
|
|
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
|
|
SESSION_SECRET: ${SESSION_SECRET}
|
|
BASE_URL: ${BASE_URL:-http://localhost:9000}
|
|
|
|
# Governance Service Configuration
|
|
BOUNDARY_ENFORCER_ENABLED: ${BOUNDARY_ENFORCER_ENABLED:-true}
|
|
CONTEXT_PRESSURE_ENABLED: ${CONTEXT_PRESSURE_ENABLED:-true}
|
|
CROSS_REF_VALIDATOR_ENABLED: ${CROSS_REF_VALIDATOR_ENABLED:-true}
|
|
PERSISTENCE_CLASSIFIER_ENABLED: ${PERSISTENCE_CLASSIFIER_ENABLED:-true}
|
|
METACOGNITIVE_VERIFIER_ENABLED: ${METACOGNITIVE_VERIFIER_ENABLED:-true}
|
|
|
|
# Performance & Limits
|
|
RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000}
|
|
RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-100}
|
|
MAX_FILE_SIZE: ${MAX_FILE_SIZE:-10485760}
|
|
|
|
# Feature Flags
|
|
BLOG_ENABLED: ${BLOG_ENABLED:-true}
|
|
KOHA_ENABLED: ${KOHA_ENABLED:-true}
|
|
DEMOS_ENABLED: ${DEMOS_ENABLED:-true}
|
|
ANALYTICS_ENABLED: ${ANALYTICS_ENABLED:-false}
|
|
|
|
volumes:
|
|
- app_logs:/app/logs
|
|
- app_uploads:/app/uploads
|
|
depends_on:
|
|
mongodb:
|
|
condition: service_healthy
|
|
networks:
|
|
- tractatus-network
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9000/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# Umami Analytics (Privacy-Preserving)
|
|
umami:
|
|
image: ghcr.io/umami-software/umami:postgresql-latest
|
|
container_name: tractatus-umami
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${UMAMI_PORT:-3000}:3000"
|
|
environment:
|
|
DATABASE_URL: postgresql://${UMAMI_DB_USER:-umami}:${UMAMI_DB_PASSWORD:-changeme}@umami-db:5432/${UMAMI_DB_NAME:-umami}
|
|
DATABASE_TYPE: postgresql
|
|
APP_SECRET: ${UMAMI_APP_SECRET}
|
|
TRACKER_SCRIPT_NAME: ${UMAMI_TRACKER_SCRIPT:-umami}
|
|
DISABLE_TELEMETRY: ${UMAMI_DISABLE_TELEMETRY:-1}
|
|
depends_on:
|
|
umami-db:
|
|
condition: service_healthy
|
|
networks:
|
|
- tractatus-network
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'curl -f http://localhost:3000/api/heartbeat || exit 1']
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# PostgreSQL for Umami
|
|
umami-db:
|
|
image: postgres:15-alpine
|
|
container_name: tractatus-umami-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_DB: ${UMAMI_DB_NAME:-umami}
|
|
POSTGRES_USER: ${UMAMI_DB_USER:-umami}
|
|
POSTGRES_PASSWORD: ${UMAMI_DB_PASSWORD:-changeme}
|
|
volumes:
|
|
- umami_db_data:/var/lib/postgresql/data
|
|
networks:
|
|
- tractatus-network
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}']
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
volumes:
|
|
mongodb_data:
|
|
driver: local
|
|
mongodb_config:
|
|
driver: local
|
|
app_logs:
|
|
driver: local
|
|
app_uploads:
|
|
driver: local
|
|
umami_db_data:
|
|
driver: local
|
|
|
|
networks:
|
|
tractatus-network:
|
|
driver: bridge
|
|
|
|
# Optional: Nginx reverse proxy (uncomment if needed)
|
|
# nginx:
|
|
# image: nginx:alpine
|
|
# container_name: tractatus-nginx
|
|
# restart: unless-stopped
|
|
# ports:
|
|
# - "80:80"
|
|
# - "443:443"
|
|
# volumes:
|
|
# - ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
# - ./ssl:/etc/nginx/ssl:ro
|
|
# depends_on:
|
|
# - tractatus-app
|
|
# networks:
|
|
# - tractatus-network
|