PRODUCTION CHECKLIST

Documentation management API with real-time MongoDB sync

๐Ÿš€ Production Deployment Checklist - backend-docs-api

โœ… Pre-Deployment Verification

1. Environment Configuration

Local Development (apps/docs-angular/src/environments/environment.ts)

export const environment = {
  production: false,
  // โŒ NO docsApiUrl โ†’ serves from /docs folder via admin proxy
  // โŒ NO MongoDB queries โ†’ perfect performance
  enableCloudSync: false,
  enableAnalytics: false,
};

Production (apps/docs-angular/src/environments/environment.prod.ts)

export const environment = {
  production: true,
  docsApiUrl: 'https://backend-docs-api-production.up.railway.app/docs-api',
  wsUrl: 'wss://backend-docs-api-production.up.railway.app',
  enableCloudSync: true,
  enableAnalytics: true,
};

2. Railway Environment Variables

Required Variables (set in Railway Dashboard):

# MongoDB Connection (test-modules cluster)
# ๐Ÿ”’ Get from: .env.local or MongoDB Atlas Dashboard
MONGODB_CONNECTION_STRING_TEST_MODULES="<YOUR_MONGODB_CONNECTION_STRING>"
MONGODB_TEST_MODULES_DATABASE="docs-database"

# Authentication (shared with gograb-space)
# ๐Ÿ”’ Get from: .env.local or generate secure random string
JWT_SECRET="<YOUR_JWT_SECRET>"
SYSTEM_TOKEN="<YOUR_SYSTEM_TOKEN>"

# Environment
NODE_ENV="production"
RAILWAY_ENVIRONMENT="true"

# CORS (optional - uses defaults if not set)
ALLOWED_ORIGINS="https://gograb.space,https://www.gograb.space"

3. MongoDB Collections Structure

Database: docs-database (in test-modules cluster)

Collections:

  1. doc-files - Documentation markdown files

    • Stores all .md and .mdc files
    • Indexed by: path, project, language, updatedAt
    • TTL: None (permanent storage)
  2. doc-projects - Project configurations

    • Stores project metadata and settings
    • Indexed by: name, language, isRoot
    • Includes: logo config, search config, UI settings
  3. doc-settings โญ NEW

    • Stores admin panel settings (flash-persistence sync)
    • Indexed by: key, namespace, updatedAt
    • Examples: docs-folders-config, logo-config, search-preferences
    • Segregated by namespace: docs-angular
  4. page-views - Analytics (7-day TTL)

  5. search-events - Search analytics (7-day TTL)

4. Data Segregation Strategy

Settings Segregation

// โœ… PROPER SEGREGATION
{
  key: 'docs-folders-config',
  namespace: 'docs-angular',  // โ† Isolated from other apps
  value: { /* folders config */ },
  metadata: {
    source: 'flash-persistence',
    environment: 'production'
  }
}

Project Segregation

// Each project has its own config
{
  name: 'GoGrab-Space',
  config: {
    search: { scopeToCurrentProject: true },
    navigation: { enableBreadcrumbs: true },
    ui: { theme: 'dark' },
    logo: { /* project-specific logo */ }
  }
}

๐Ÿ“‹ Deployment Steps

Step 1: Sync Files to MongoDB

Before deploying the frontend, sync all documentation files:

# From project root
yarn docs:sync:prod

This uploads all 2,160+ files to MongoDB (takes ~30 seconds with proper batch sizes).

Step 2: Deploy backend-docs-api

# Deploy API to Railway
yarn railway:deploy:docs

# Verify deployment
curl https://backend-docs-api-production.up.railway.app/docs-api/health

Expected Response:

{
  "status": "ok",
  "timestamp": "2025-12-24T...",
  "database": "connected"
}

Step 3: Test API Endpoints

# Test file retrieval
curl "https://backend-docs-api-production.up.railway.app/docs-api/sync/files/english/GoGrab-Space/platform/gograb-space-platform"

# Test manifest
curl "https://backend-docs-api-production.up.railway.app/docs-api/sync/manifest"

# Test settings (should return 404 initially - normal)
curl "https://backend-docs-api-production.up.railway.app/docs-api/sync/settings/docs-folders-config?namespace=docs-angular"

Step 4: Build docs-angular for Production

# Build with production environment
yarn nx build docs-angular --configuration=production

# Output location
ls -la dist/apps/docs-angular/browser/

Step 5: Deploy to gograb.space/docs

Upload the contents of dist/apps/docs-angular/browser/ to your web server at https://gograb.space/docs/.

Step 6: Verify Production

  1. Navigate to: https://gograb.space/docs/
  2. Check console for:
    ๐Ÿ“ก Using Docs API: https://backend-docs-api-production.up.railway.app/docs-api
    โœ… Successfully loaded from API: ...
    
  3. Test navigation across different projects
  4. Verify settings persist across sessions

๐Ÿ”„ Flash Persistence Integration

How Settings Sync Works

Local Development:

Admin Panel โ†’ localStorage โ†’ JSON files
                โ†“
        (No MongoDB sync)

Production:

Admin Panel โ†’ Flash Persistence โ†’ backend-docs-api โ†’ MongoDB
                โ†“
        Auto-sync every change

Implementing Flash Persistence Sync

To enable automatic settings sync in production, you'll need to:

  1. Create a Flash Persistence Backend in docs-angular:
// apps/docs-angular/src/app/services/docs-settings-backend.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';

@Injectable({ providedIn: 'root' })
export class DocsSettingsBackend {
  private readonly http = inject(HttpClient);
  private readonly apiUrl = (environment as any).docsApiUrl;

  async save(key: string, value: any): Promise<void> {
    if (!this.apiUrl) return; // Skip in local dev

    await this.http.post(`${this.apiUrl}/sync/settings`, {
      key,
      value,
      namespace: 'docs-angular',
      metadata: {
        source: 'flash-persistence',
        environment: environment.production ? 'production' : 'development'
      }
    }).toPromise();
  }

  async load(key: string): Promise<any> {
    if (!this.apiUrl) return null; // Skip in local dev

    try {
      const response = await this.http.get(
        `${this.apiUrl}/sync/settings/${key}?namespace=docs-angular`
      ).toPromise();
      return (response as any).value;
    } catch {
      return null;
    }
  }
}
  1. Register with Storage System (in app.config.ts or service):
// Use @autoFlashState decorator or manual registration
const settingsBackend = inject(DocsSettingsBackend);

// Register custom backend for specific keys
storageRegistry.registerBackend('docs-settings', {
  save: (key, value) => settingsBackend.save(key, value),
  load: (key) => settingsBackend.load(key),
  priority: 100 // Higher than localStorage
});

๐ŸŽฏ Production Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  gograb.space/docs (Static Angular Build)          โ”‚
โ”‚  โ”œโ”€ Loads from: backend-docs-api (MongoDB)          โ”‚
โ”‚  โ”œโ”€ Settings: Synced via flash-persistence          โ”‚
โ”‚  โ””โ”€ Offline-first: Pre-synced content               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                      โ†“ HTTP/WebSocket
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  backend-docs-api (Railway)                         โ”‚
โ”‚  โ”œโ”€ Port: 8080 (Railway dynamic)                    โ”‚
โ”‚  โ”œโ”€ Database: test-modules cluster                  โ”‚
โ”‚  โ”œโ”€ Collections: doc-files, doc-projects,           โ”‚
โ”‚  โ”‚               doc-settings, analytics            โ”‚
โ”‚  โ””โ”€ Auth: Shared JWT with gograb-space              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                      โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  MongoDB Atlas (test-modules cluster)               โ”‚
โ”‚  โ”œโ”€ Database: docs-database                         โ”‚
โ”‚  โ”œโ”€ Namespace: docs-angular (settings segregation)  โ”‚
โ”‚  โ””โ”€ Performance: Indexed queries, TTL for analytics โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”’ Security Checklist


๐Ÿงช Testing Production Setup

Test 1: File Loading

# Should return full markdown content
curl "https://backend-docs-api-production.up.railway.app/docs-api/sync/files/english/GoGrab-Space/platform/gograb-space-platform"

Test 2: Manifest

# Should return full manifest with 2160+ files
curl "https://backend-docs-api-production.up.railway.app/docs-api/sync/manifest" | jq '.structure | length'

Test 3: Settings (after sync)

# Should return docs-folders-config
curl "https://backend-docs-api-production.up.railway.app/docs-api/sync/settings/docs-folders-config?namespace=docs-angular"

Test 4: WebSocket Connection

// In browser console at gograb.space/docs
const ws = new WebSocket('wss://backend-docs-api-production.up.railway.app');
ws.onopen = () => console.log('โœ… WebSocket connected');
ws.onerror = (e) => console.error('โŒ WebSocket error:', e);

๐Ÿ“Š Performance Expectations

Local Development:

Production:


๐Ÿ› Troubleshooting

Issue: Files not loading in production

Cause: MongoDB database is empty
Fix: Run yarn docs:sync:prod before deploying

Issue: Settings not persisting

Cause: Flash persistence backend not configured
Fix: Implement DocsSettingsBackend service (see above)

Issue: CORS errors

Cause: ALLOWED_ORIGINS not set in Railway
Fix: Add https://gograb.space to Railway environment variables

Issue: 401 Unauthorized on settings

Cause: SYSTEM_TOKEN not set or incorrect
Fix: Copy SYSTEM_TOKEN from .env.local to Railway


๐Ÿ“ Post-Deployment

  1. โœ… Verify all pages load correctly
  2. โœ… Test project switching
  3. โœ… Verify settings persist across sessions
  4. โœ… Check analytics are being tracked
  5. โœ… Test search functionality
  6. โœ… Verify WebSocket real-time updates

๐Ÿ”„ Updating Documentation

In Production:

  1. Edit files locally in /docs folder
  2. Run yarn docs:sync:prod to upload changes
  3. Changes appear immediately (WebSocket broadcast)
  4. No frontend redeployment needed!

Automated Sync (Future):


Last Updated: 2025-12-24
Status: โœ… Ready for Production Deployment