Skip to main content

auth.coditect.ai Deployment Plan

Executive Summary

Objective: Deploy complete authentication portal at auth.coditect.ai with:

  • User registration and login frontend
  • Backend API for authentication, license management
  • Secure HTTPS with Google-managed SSL
  • Single static IP with Ingress routing

Timeline: 3-5 days Status: Planning → Implementation


Current Infrastructure Status

✅ Existing Resources

GCP Project: coditect-cloud-infra
GKE Cluster: coditect-cluster
Location: us-central1
Nodes: 3 x n1-standard-2
Status: RUNNING

Backend Deployment:
Namespace: coditect-staging
Service: coditect-backend (LoadBalancer)
External IP: 136.114.0.156 (ephemeral)
Ports: 80, 443
Status: DEPLOYED (8 hours ago)

❌ Missing Components

  • Global static IP for auth.coditect.ai
  • Google-managed SSL certificate
  • Ingress controller configuration
  • DNS A record: auth.coditect.ai → static IP
  • Frontend React application
  • Frontend container image
  • Frontend Kubernetes deployment

Architecture

Target Architecture

                                    ┌──────────────────┐
│ auth.coditect.ai │
│ DNS A Record │
└────────┬─────────┘


┌────────────────────────┐
│ Static IP (Global) │
│ 34.x.x.x (new) │
└─────────┬──────────────┘


┌────────────────────────────────┐
│ GKE Ingress Controller │
│ (nginx or gce ingress) │
│ + Google-managed SSL Cert │
└─────┬────────────────┬─────────┘
│ │
┌──────────────┴────┐ ┌─────┴───────────────┐
│ Path: /api/v1/* │ │ Path: /* │
▼ ▼ ▼ ▼
┌──────────────┐ ┌──────────────┐
│ Backend │ │ Frontend │
│ Service │ │ Service │
│ (Django API) │ │ (React App) │
└──────────────┘ └──────────────┘
Port 8000 Port 80

Request Flow Examples

User visits: https://auth.coditect.ai/
→ Ingress routes to frontend service (port 80)
→ Returns React app HTML

User calls: https://auth.coditect.ai/api/v1/auth/register/
→ Ingress routes to backend service (port 8000)
→ Returns JSON response

CORS: Not needed (same origin)

Implementation Steps

Phase 1: GCP Infrastructure Setup (Day 1)

Step 1.1: Reserve Global Static IP

# Reserve the IP
gcloud compute addresses create coditect-auth-ip \
--global \
--ip-version IPV4 \
--project coditect-cloud-infra

# Get the IP address
export AUTH_IP=$(gcloud compute addresses describe coditect-auth-ip \
--global \
--format="value(address)")

echo "Reserved IP: $AUTH_IP"
# Output: Reserved IP: 34.120.45.67 (example)

Verification:

gcloud compute addresses list --global | grep coditect-auth-ip

Step 1.2: Create SSL Certificate

# Create Google-managed SSL certificate
gcloud compute ssl-certificates create coditect-auth-cert \
--domains=auth.coditect.ai \
--global \
--project coditect-cloud-infra

# Check provisioning status (takes 10-60 minutes after DNS configured)
gcloud compute ssl-certificates describe coditect-auth-cert \
--global \
--format="value(managed.status)"

Note: Certificate provisioning requires DNS to be configured first (Step 1.3)

Step 1.3: Configure DNS

Action Required: Update DNS at domain registrar

# DNS Configuration (at your domain registrar - e.g., Namecheap, GoDaddy)
Type: A
Host: auth
Domain: coditect.ai
Value: <AUTH_IP from Step 1.1>
TTL: 300 (5 minutes for testing, increase to 3600 after confirmed)

Verification:

# Wait 5-10 minutes for DNS propagation
dig auth.coditect.ai +short
# Should return: <AUTH_IP>

# Alternative check
nslookup auth.coditect.ai

Phase 2: Frontend Development (Day 2-3)

Step 2.1: Initialize React Project

Location: /Users/halcasteel/PROJECTS/coditect-rollout-master/submodules/cloud/coditect-cloud-frontend/

cd submodules/cloud/coditect-cloud-frontend

# Create Vite + React + TypeScript project
npm create vite@latest . -- --template react-ts

# Install dependencies
npm install

# Install additional libraries
npm install \
react-router-dom \
@tanstack/react-query \
axios \
react-hook-form \
zod \
@radix-ui/react-dialog \
@radix-ui/react-dropdown-menu \
tailwindcss postcss autoprefixer

# Initialize Tailwind
npx tailwindcss init -p

Step 2.2: Build Core Pages

Pages to Implement:

  1. Landing Page (/)

    • Hero section with value proposition
    • Pricing table (BASIC, PRO, ENTERPRISE)
    • Call-to-action: "Get Started"
    • Features overview
    • Time: 4-6 hours
  2. Registration Page (/register)

    • Email, password, full name, company fields
    • Email verification notice
    • Stripe checkout integration
    • Time: 6-8 hours
  3. Login Page (/login)

    • Email/password form
    • JWT token storage
    • Redirect to dashboard after login
    • "Forgot password" link
    • Time: 3-4 hours
  4. Dashboard Page (/dashboard)

    • Display license key
    • Show active sessions
    • Organization info
    • Download license file
    • Time: 6-8 hours
  5. Email Verification Page (/verify-email)

    • Handle email verification tokens
    • Success/failure messaging
    • Auto-redirect to login
    • Time: 2-3 hours

Total Frontend Time: 21-29 hours (2-3 days with 8-10 hour days)

Step 2.3: API Integration

Create API client:

// src/services/api.ts
import axios from 'axios';

const API_BASE_URL = import.meta.env.VITE_API_URL || '/api/v1';

export const api = axios.create({
baseURL: API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});

// Add JWT token to requests
api.interceptors.request.use((config) => {
const token = localStorage.getItem('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});

// Handle token refresh on 401
api.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
const refreshToken = localStorage.getItem('refresh_token');
if (refreshToken) {
// Attempt token refresh
try {
const response = await axios.post(`${API_BASE_URL}/auth/token/refresh/`, {
refresh: refreshToken,
});
localStorage.setItem('access_token', response.data.access);
// Retry original request
error.config.headers.Authorization = `Bearer ${response.data.access}`;
return axios(error.config);
} catch (refreshError) {
// Refresh failed, redirect to login
localStorage.clear();
window.location.href = '/login';
}
}
}
return Promise.reject(error);
}
);

API Services:

// src/services/authService.ts
export const authService = {
register: (data) => api.post('/auth/register/', data),
login: (credentials) => api.post('/auth/login/', credentials),
verifyEmail: (token) => api.post('/auth/verify-email/', { token }),
forgotPassword: (email) => api.post('/auth/forgot-password/', { email }),
resetPassword: (token, password) => api.post('/auth/reset-password/', { token, password }),
};

// src/services/licenseService.ts
export const licenseService = {
getMyLicenses: () => api.get('/licenses/'),
getLicenseDetail: (id) => api.get(`/licenses/${id}/`),
downloadLicense: (id) => api.get(`/licenses/${id}/download/`),
validateLicense: (key) => api.post('/licenses/validate/', { license_key: key }),
};

// src/services/subscriptionService.ts
export const subscriptionService = {
getPlans: () => api.get('/subscriptions/plans/'),
createCheckout: (plan_id) => api.post('/subscriptions/checkout/', { plan_id }),
getCurrentSubscription: () => api.get('/subscriptions/current/'),
};

Step 2.4: Environment Configuration

# .env.example
VITE_API_URL=/api/v1
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_...

# .env.development (local development)
VITE_API_URL=http://localhost:8000/api/v1
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_51K...

# .env.production (production - uses relative path)
VITE_API_URL=/api/v1
VITE_STRIPE_PUBLISHABLE_KEY=pk_live_51K...

Phase 3: Containerization (Day 3)

Step 3.1: Create Dockerfile for Frontend

# Dockerfile
FROM node:18-alpine AS builder

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy source code
COPY . .

# Build for production
RUN npm run build

# Production stage with Nginx
FROM nginx:alpine

# Copy built files
COPY --from=builder /app/dist /usr/share/nginx/html

# Custom Nginx config for React Router (SPA)
RUN echo 'server { \
listen 80; \
location / { \
root /usr/share/nginx/html; \
index index.html index.htm; \
try_files $uri $uri/ /index.html; \
} \
}' > /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Step 3.2: Build and Push Image

cd submodules/cloud/coditect-cloud-frontend

# Build image
docker build -t gcr.io/coditect-cloud-infra/coditect-frontend:v1.0.0 .

# Push to Google Container Registry
docker push gcr.io/coditect-cloud-infra/coditect-frontend:v1.0.0

# Tag as latest
docker tag gcr.io/coditect-cloud-infra/coditect-frontend:v1.0.0 \
gcr.io/coditect-cloud-infra/coditect-frontend:latest
docker push gcr.io/coditect-cloud-infra/coditect-frontend:latest

Phase 4: Kubernetes Deployment (Day 4)

Step 4.1: Create Frontend Deployment

# deployment/kubernetes/frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: coditect-frontend
namespace: coditect-staging
spec:
replicas: 2
selector:
matchLabels:
app: coditect-frontend
template:
metadata:
labels:
app: coditect-frontend
spec:
containers:
- name: frontend
image: gcr.io/coditect-cloud-infra/coditect-frontend:latest
ports:
- containerPort: 80
env:
- name: VITE_API_URL
value: "/api/v1"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: coditect-frontend
namespace: coditect-staging
spec:
selector:
app: coditect-frontend
ports:
- port: 80
targetPort: 80
type: ClusterIP

Step 4.2: Update Backend Service (Remove LoadBalancer)

# deployment/kubernetes/backend-deployment.yaml (UPDATE)
apiVersion: v1
kind: Service
metadata:
name: coditect-backend
namespace: coditect-staging
spec:
selector:
app: coditect-backend
ports:
- port: 8000
targetPort: 8000
type: ClusterIP # Changed from LoadBalancer to ClusterIP

Step 4.3: Create Ingress Configuration

# deployment/kubernetes/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: coditect-auth-ingress
namespace: coditect-staging
annotations:
kubernetes.io/ingress.global-static-ip-name: "coditect-auth-ip"
networking.gke.io/managed-certificates: "coditect-auth-cert"
kubernetes.io/ingress.class: "gce"
# Enable HTTPS redirect
networking.gke.io/v1beta1.FrontendConfig: "redirect-http-to-https"
spec:
rules:
- host: auth.coditect.ai
http:
paths:
# Backend API paths (must come first - more specific)
- path: /api/v1/*
pathType: ImplementationSpecific
backend:
service:
name: coditect-backend
port:
number: 8000
# Admin API paths
- path: /admin/*
pathType: ImplementationSpecific
backend:
service:
name: coditect-backend
port:
number: 8000
# Static files (Django admin CSS/JS)
- path: /static/*
pathType: ImplementationSpecific
backend:
service:
name: coditect-backend
port:
number: 8000
# Frontend (catch-all - must come last)
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: coditect-frontend
port:
number: 80
---
# HTTPS redirect configuration
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: redirect-http-to-https
namespace: coditect-staging
spec:
redirectToHttps:
enabled: true

Step 4.4: Deploy to GKE

# Apply configurations
kubectl apply -f deployment/kubernetes/frontend-deployment.yaml
kubectl apply -f deployment/kubernetes/backend-deployment.yaml # Updated ClusterIP
kubectl apply -f deployment/kubernetes/ingress.yaml

# Verify deployments
kubectl get deployments -n coditect-staging
kubectl get services -n coditect-staging
kubectl get ingress -n coditect-staging

# Check Ingress status (wait 5-10 minutes for provisioning)
kubectl describe ingress coditect-auth-ingress -n coditect-staging

# Monitor SSL certificate provisioning (can take 10-60 minutes)
gcloud compute ssl-certificates describe coditect-auth-cert \
--global \
--format="value(managed.status)"
# Expected: ACTIVE (after DNS propagates)

Phase 5: Testing & Validation (Day 4-5)

Step 5.1: Smoke Tests

# Test DNS resolution
dig auth.coditect.ai +short
# Should return: Static IP from Step 1.1

# Test HTTP → HTTPS redirect
curl -I http://auth.coditect.ai
# Should return: 301 Moved Permanently, Location: https://auth.coditect.ai

# Test HTTPS (frontend)
curl -I https://auth.coditect.ai
# Should return: 200 OK, Content-Type: text/html

# Test backend API
curl https://auth.coditect.ai/api/v1/health/
# Should return: {"status": "healthy"}

Step 5.2: End-to-End User Flow

Test Script:

  1. Visit Landing Page

  2. Register Account

    • Navigate to: https://auth.coditect.ai/register
    • Fill: Email, password, full name, company name
    • Click: "Create Account"
    • Verify: Success message, "Check your email" notice
  3. Verify Email

    • Check email inbox
    • Click: Verification link
    • Verify: Redirects to login with success message
  4. Complete Stripe Checkout

    • Login with verified account
    • Select: BASIC plan ($29/month)
    • Click: "Subscribe"
    • Verify: Redirects to Stripe checkout
    • Complete: Test payment (card: 4242 4242 4242 4242)
    • Verify: Redirects back to dashboard
  5. View License

    • Verify: License key displayed (CODITECT-YYYY-XXXX-XXXX)
    • Click: "Download License"
    • Verify: License file downloads
  6. Test License in CODITECT-CORE

    • Install: CODITECT-CORE CLI
    • Run: coditect license activate <LICENSE_KEY>
    • Verify: License accepted, session started
    • Check: Dashboard shows 1 active session

Step 5.3: Performance Testing

# Load test with Apache Bench
ab -n 1000 -c 10 https://auth.coditect.ai/

# Check response times
# Target: < 500ms for frontend, < 1000ms for API

Step 5.4: Security Testing

# SSL Labs test
# Visit: https://www.ssllabs.com/ssltest/analyze.html?d=auth.coditect.ai
# Target: A+ rating

# Security headers check
curl -I https://auth.coditect.ai | grep -i 'x-frame-options\|x-content-type-options\|strict-transport-security'

# CORS check
curl -H "Origin: https://evil.com" \
-H "Access-Control-Request-Method: POST" \
-X OPTIONS https://auth.coditect.ai/api/v1/auth/login/
# Should return: CORS headers restricting to auth.coditect.ai only

Cost Estimates

GCP Infrastructure Costs (Monthly)

ResourceQuantityUnit CostMonthly Cost
GKE Cluster (n1-standard-2)3 nodes$0.095/hr~$205
Global Static IP1 IP$0.010/hr~$7.20
Ingress Load Balancer1$18/month$18
Cloud SQL (PostgreSQL)db-n1-standard-1$0.0825/hr~$60
Redis Memorystore6 GB$0.017/GB/hr~$73
SSL Certificate1Free (Google-managed)$0
Egress (estimate)100 GB$0.12/GB$12
TOTAL~$375/month

Development Time (Hours)

PhaseTaskHours
1GCP Infrastructure Setup2-3
2Frontend Development21-29
3Containerization3-4
4Kubernetes Deployment4-6
5Testing & Validation6-8
TOTAL36-50 hours

Timeline: 3-5 days (assuming 8-10 hour workdays)


Rollback Plan

If issues occur during deployment:

Scenario 1: Ingress Not Working

# Quick rollback: Re-enable LoadBalancer on backend
kubectl patch service coditect-backend -n coditect-staging \
-p '{"spec":{"type":"LoadBalancer"}}'

# Update DNS to point to LoadBalancer IP temporarily
# This allows backend API to remain accessible while debugging Ingress

Scenario 2: SSL Certificate Provisioning Stuck

# Check DNS propagation
dig auth.coditect.ai +short

# Check certificate status
gcloud compute ssl-certificates describe coditect-auth-cert --global

# Common issues:
# - DNS not propagated (wait 5-60 minutes)
# - Domain verification failed (check CAA records)
# - Rate limit hit (wait 24 hours, use staging cert temporarily)

Scenario 3: Frontend Not Loading

# Check pod status
kubectl get pods -n coditect-staging | grep frontend

# Check logs
kubectl logs -l app=coditect-frontend -n coditect-staging --tail=100

# Common issues:
# - Image pull error (check GCR permissions)
# - Nginx config error (check Dockerfile)
# - React build error (check build logs)

Success Criteria

  • Static IP reserved and DNS configured
  • SSL certificate provisioned (ACTIVE status)
  • Frontend builds and deploys successfully
  • Ingress routes traffic correctly (/ → frontend, /api/v1/* → backend)
  • HTTPS working with A+ SSL Labs rating
  • User can complete full registration flow end-to-end
  • License activation works in CODITECT-CORE
  • Performance: Frontend < 500ms, API < 1000ms
  • Security: All headers configured, CORS enforced
  • Monitoring: GKE metrics showing healthy pods
  • Documentation: README updated with deployment instructions

Post-Deployment Tasks

  1. Monitor for 24 hours

    • Check GKE metrics for CPU/memory usage
    • Monitor SSL certificate renewal (automatic)
    • Review logs for errors
  2. Update Documentation

    • Add deployment guide to README
    • Document DNS configuration
    • Update architecture diagrams
  3. Set Up Alerts

    • Uptime monitoring (UptimeRobot, Pingdom)
    • Error rate alerts (Cloud Monitoring)
    • SSL expiration alerts (automatic with Google-managed)
  4. Backup & Disaster Recovery

    • Document rollback procedures
    • Test backup restoration
    • Set up automated database backups

Next Steps

Immediate Actions:

  1. Reserve static IP (5 minutes)
  2. Configure DNS at domain registrar (10 minutes)
  3. Create SSL certificate (1 minute - provisioning takes 10-60 min)
  4. Start frontend development (2-3 days)
  5. Deploy to GKE (4-6 hours)
  6. Test end-to-end (4-6 hours)

Decision Needed:

  • Proceed with full frontend implementation?
  • Simplified MVP first (landing + registration only)?
  • Timeline preference (fast MVP vs. complete implementation)?

Created: December 1, 2025 Owner: Hal Casteel Status: Ready for Implementation