# Digital Nagarik — Complete Migration Plan

> **Generated:** 2026-09-03 17:00 UTC  
> **Goal:** Clone the entire Digital Nagarik platform to `digitalnagarik.com`  
> **Strategy:** Copy-only — zero deletions, zero moves from current directory  
> **Result:** Both URLs run in parallel from separate directories  

---

## 📋 Table of Contents

1. [Current State Inventory](#1-current-state-inventory)
2. [Target Architecture](#2-target-architecture)
3. [Database Migration](#3-database-migration)
4. [File Migration — Complete File Map](#4-file-migration--complete-file-map)
5. [Configuration — What Changes](#5-configuration--what-changes)
6. [Apache Configuration](#6-apache-configuration)
7. [Git Strategy](#7-git-strategy)
8. [Execution Plan — Step by Step](#8-execution-plan--step-by-step)
9. [Parallel Operation Verification](#9-parallel-operation-verification)
10. [Rollback Plan](#10-rollback-plan)
11. [Checklist](#11-checklist)

---

## 1. Current State Inventory

### 1.1 Server Infrastructure

| Component | Detail |
|-----------|--------|
| **OS** | Ubuntu 24.04 (Noble) |
| **Public IP** | `20.198.178.24` (Azure VM) |
| **Web Server** | Apache 2.4.58 |
| **SSL** | Let's Encrypt (Certbot) |
| **Runtime** | Node.js 22 |
| **Process Manager** | PM2 (cluster mode, 2 instances) |
| **Database** | PostgreSQL 16 + PostGIS (Docker, port 5434) |
| **Cache** | Redis 7 (Docker, port 6380) |
| **Docker Network** | `dn-network` (bridge, 172.20.0.0/24) |

### 1.2 Current URLs

| URL | DocumentRoot | Status |
|-----|-------------|--------|
| `https://digital-nagarik.20.198.178.24.nip.io/` | `/home/digital-nagarik/public_html/` | 🟢 Running |
| `https://digitalnagarik.com/` | `/home/digital-nagarik/public_html/digitalnagarik.com/` | 🟢 Live (empty) |

### 1.3 Running Services

| Service | Container | Port | Status |
|---------|-----------|------|--------|
| PostgreSQL 16 + PostGIS | `dn-postgres` | 127.0.0.1:5434 | 🟢 Healthy (2 months uptime) |
| Redis 7 | `dn-redis` | 127.0.0.1:6380 | 🟢 Healthy (2 months uptime) |
| Node.js API (PM2) | `dn-api` (×2) | 127.0.0.1:3200 | 🟢 Online (cluster) |

### 1.4 Git

| Detail | Value |
|--------|-------|
| **Remote** | `https://github.com/sackitbd/digital-nagarik.git` |
| **Branch** | `main` |
| **HEAD** | `7a8d369` — "cleanup: remove unused top-unions fetch from analytics page" |

---

## 2. Target Architecture

```
┌──────────────────────────────────────────────────────────────────┐
│                    https://digitalnagarik.com                     │
│  Apache VirtualHost → DocumentRoot:                               │
│  /home/digital-nagarik/public_html/digitalnagarik.com/            │
│                                                                   │
│  ├── index.html              (landing page)                       │
│  ├── admin/index.html        (admin SPA, 467KB)                   │
│  ├── mobile/                 (PWA mobile app)                     │
│  ├── assets/                 (JS bundles, Leaflet, Dexie)         │
│  ├── fonts/                  (Hind Siliguri Bengali)              │
│  ├── icons/                  (PWA icons 192×192, 512×512)        │
│  ├── id-card/                (Next.js ID card system)             │
│  ├── .htaccess               (SPA rewrite rules)                  │
│  ├── sw.js / sw-dn.js        (Service Workers)                    │
│  ├── manifest.json           (PWA manifest)                       │
│  ├── favicon.svg / logo.jpg  (Brand assets)                       │
│  ├── offline.html            (Offline fallback)                   │
│  └── .well-known/            (for SSL verification if needed)     │
│                                                                   │
│  /api/*  → ProxyPass → http://127.0.0.1:3200/api/*               │
│  /ws     → ProxyPass → http://127.0.0.1:3200/ws                  │
│                                                                   │
│  ─── SHARED BACKEND (same DB, same API, same Redis) ───           │
└──────────────────────────────────────────────────────────────────┘
```

**Key principle:** Both domains share the SAME database, SAME API process, SAME Redis. Only the static frontend files are duplicated. This means zero data synchronization issues.

---

## 3. Database Migration

### 3.1 Decision: NO Database Migration Needed

Since both the nip.io URL and digitalnagarik.com will point to the **same** Node.js API (`127.0.0.1:3200`) which connects to the **same** PostgreSQL and Redis, **no database migration, duplication, or synchronization is required.**

Both domains will read/write the same data in real-time.

### 3.2 Database Schema — 36 Tables

| # | Table | Rows | Purpose |
|---|-------|------|---------|
| 1 | `_prisma_migrations` | ~7 | Prisma migration history |
| 2 | `admin_flags` | 0 | SLA/admin case flags |
| 3 | `advocacy_letters` | varies | Generated advocacy letters |
| 4 | `advocacy_package_cases` | varies | M2M: packages ↔ cases |
| 5 | `advocacy_packages` | varies | Advocacy package cover letters |
| 6 | `app_settings` | varies | Dynamic app configuration |
| 7 | `case_report_logs` | 0 | Case PDF audit trail |
| 8 | `case_timeline` | 0 | Status transition history |
| 9 | `certificates` | varies | Volunteer/student certificates |
| 10 | `civic_cases` | 0 | Grievance reports |
| 11 | `communication_logs` | varies | SMS/email delivery logs |
| 12 | `daily_attendance` | varies | Daily volunteer attendance |
| 13 | `districts` | 64 | Bangladesh districts |
| 14 | `general_settings` | varies | System settings |
| 15 | `id_card_audit_logs` | varies | ID card generation audit |
| 16 | `id_card_batches` | varies | Batch ID card generation |
| 17 | `id_card_template_revisions` | varies | Template versioning |
| 18 | `id_card_templates` | varies | ID card HTML templates |
| 19 | `identity_cards` | varies | Volunteer identity cards |
| 20 | `login_corrections` | varies | Stealth attendance corrections |
| 21 | `login_history` | varies | Auth audit trail |
| 22 | `media_attachments` | 0 | Case photos/documents |
| 23 | `notification_rules` | varies | Notification configuration |
| 24 | `offline_sync_events` | varies | Offline→online sync queue |
| 25 | `officer_notes` | 0 | Govt officer case notes |
| 26 | `profile_change_requests` | varies | Youth leader profile edit requests |
| 27 | `report_logs` | 0 | Grievance report PDF audit |
| 28 | `security_events` | varies | Security audit log |
| 29 | `sla_escalations` | 0 | SLA tier escalation tracking |
| 30 | `sms_campaigns` | varies | Bulk SMS campaigns |
| 31 | `sms_logs` | varies | Individual SMS delivery log |
| 32 | `student_applications` | varies | Student enrollment |
| 33 | `student_documents` | varies | Student uploaded docs |
| 34 | `token_revocations` | varies | JWT deny-list |
| 35 | `upazilas` | ~500 | Bangladesh upazilas |
| 36 | `users` | 119 | All platform users |

### 3.3 Database Credentials

```
Host:     localhost:5434
User:     digital_nagarik
Password: dN4g4r1k_2026_Secure
Database: digital_nagarik
```

---

## 4. File Migration — Complete File Map

### 4.1 Files to COPY (from `/home/digital-nagarik/public_html/` → `digitalnagarik.com/`)

#### Category A: Static Frontend (Root Level)

| Source | Destination | Size | Notes |
|--------|-------------|------|-------|
| `index.html` | `digitalnagarik.com/index.html` | 8KB | Landing page |
| `offline.html` | `digitalnagarik.com/offline.html` | 2KB | PWA offline fallback |
| `manifest.json` | `digitalnagarik.com/manifest.json` | 658B | PWA manifest |
| `favicon.svg` | `digitalnagarik.com/favicon.svg` | 281B | Site icon |
| `logo.jpg` | `digitalnagarik.com/logo.jpg` | 227KB | Brand logo |
| `icons.svg` | `digitalnagarik.com/icons.svg` | 5KB | SVG sprite sheet |
| `.htaccess` | `digitalnagarik.com/.htaccess` | 1KB | **MODIFIED** — see 5.1 |
| `sw.js` | `digitalnagarik.com/sw.js` | 3KB | Service Worker |
| `sw-dn.js` | `digitalnagarik.com/sw-dn.js` | 7KB | Digital Nagarik SW |
| `brochure-content.md` | `digitalnagarik.com/brochure-content.md` | 8KB | Marketing content |
| `USER-GUIDE.md` | `digitalnagarik.com/USER-GUIDE.md` | 55KB | User documentation |
| `SMS-SETUP.md` | `digitalnagarik.com/SMS-SETUP.md` | 18KB | SMS setup guide |
| `plan.md` | `digitalnagarik.com/plan.md` | 28KB | Project plan |
| `prompt.md` | `digitalnagarik.com/prompt.md` | 7KB | AI prompt reference |
| `dn-credentials.md` | `digitalnagarik.com/dn-credentials.md` | 5KB | Credential reference |

#### Category B: Admin SPA

| Source | Destination | Size | Notes |
|--------|-------------|------|-------|
| `admin/index.html` | `digitalnagarik.com/admin/index.html` | 467KB | Admin SPA (single file) |

#### Category C: Mobile PWA

| Source | Destination | Size |
|--------|-------------|------|
| `mobile/index.html` | `digitalnagarik.com/mobile/index.html` | 9KB |
| `mobile/verify.html` | `digitalnagarik.com/mobile/verify.html` | 8KB |
| `mobile/manifest.json` | `digitalnagarik.com/mobile/manifest.json` | 1KB |
| `mobile/css/reset.css` | `digitalnagarik.com/mobile/css/reset.css` | 1KB |
| `mobile/css/base.css` | `digitalnagarik.com/mobile/css/base.css` | 6KB |
| `mobile/css/components.css` | `digitalnagarik.com/mobile/css/components.css` | 14KB |
| `mobile/css/tokens.css` | `digitalnagarik.com/mobile/css/tokens.css` | 4KB |
| `mobile/css/responsive.css` | `digitalnagarik.com/mobile/css/responsive.css` | 4KB |
| `mobile/js/app.js` | `digitalnagarik.com/mobile/js/app.js` | — |
| `mobile/js/lib/compress.js` | `digitalnagarik.com/mobile/js/lib/compress.js` | — |
| `mobile/js/lib/db.js` | `digitalnagarik.com/mobile/js/lib/db.js` | — |
| `mobile/js/lib/sync.js` | `digitalnagarik.com/mobile/js/lib/sync.js` | — |
| `mobile/js/pages/forgot-password.js` | `digitalnagarik.com/mobile/js/pages/forgot-password.js` | — |
| `mobile/js/pages/home.js` | `digitalnagarik.com/mobile/js/pages/home.js` | — |
| `mobile/js/pages/login.js` | `digitalnagarik.com/mobile/js/pages/login.js` | — |
| `mobile/js/pages/pending.js` | `digitalnagarik.com/mobile/js/pages/pending.js` | — |
| `mobile/js/pages/register.js` | `digitalnagarik.com/mobile/js/pages/register.js` | — |
| `mobile/js/pages/report.js` | `digitalnagarik.com/mobile/js/pages/report.js` | — |
| `mobile/js/pages/reports.js` | `digitalnagarik.com/mobile/js/pages/reports.js` | — |
| `mobile/js/pages/reset-password.js` | `digitalnagarik.com/mobile/js/pages/reset-password.js` | — |
| `mobile/js/pages/toolkit.js` | `digitalnagarik.com/mobile/js/pages/toolkit.js` | — |

#### Category D: Assets (JS/CSS Bundles)

| Source | Destination | Size |
|--------|-------------|------|
| `assets/dexie-4.0.8.min.js` | `digitalnagarik.com/assets/dexie-4.0.8.min.js` | 261KB |
| `assets/dexie-Bnn2I2pB.js` | `digitalnagarik.com/assets/dexie-Bnn2I2pB.js` | 93KB |
| `assets/index-BcRKAJXg.js` | `digitalnagarik.com/assets/index-BcRKAJXg.js` | 176KB |
| `assets/index-DELZDxps.css` | `digitalnagarik.com/assets/index-DELZDxps.css` | 38KB |
| `assets/leaflet-CcbN9-BV.js` | `digitalnagarik.com/assets/leaflet-CcbN9-BV.js` | 166KB |
| `assets/leaflet-vh-t_kPv.css` | `digitalnagarik.com/assets/leaflet-vh-t_kPv.css` | 15KB |
| `assets/rolldown-runtime-QTnfLwEv.js` | `digitalnagarik.com/assets/rolldown-runtime-QTnfLwEv.js` | 1KB |
| `assets/vendor-v0gBP4dr.js` | `digitalnagarik.com/assets/vendor-v0gBP4dr.js` | 217KB |

#### Category E: Static Assets

| Source | Destination |
|--------|-------------|
| `fonts/hind-siliguri-regular-bengali-subset.woff2` | `digitalnagarik.com/fonts/` |
| `icons/icon-192x192.svg` | `digitalnagarik.com/icons/` |
| `icons/icon-512x512.svg` | `digitalnagarik.com/icons/` |

#### Category F: ID Card System (Next.js)

| Source | Destination |
|--------|-------------|
| `id-card/app/admin/id-cards/page.tsx` | `digitalnagarik.com/id-card/` |
| `id-card/app/api/hostel/id-cards/[id]/route.ts` | `digitalnagarik.com/id-card/` |
| `id-card/app/api/hostel/id-cards/route.ts` | `digitalnagarik.com/id-card/` |
| `id-card/app/api/id-cards/route.ts` | `digitalnagarik.com/id-card/` |
| `id-card/app/student/components/StudentIDCardView.tsx` | `digitalnagarik.com/id-card/` |
| `id-card/components/hostel/HostelIdCardsView.tsx` | `digitalnagarik.com/id-card/` |
| `id-card/components/layout/AdminLayout.tsx` | `digitalnagarik.com/id-card/` |
| `id-card/components/ui/ConfirmModal.tsx` | `digitalnagarik.com/id-card/` |
| `id-card/components/ui/DatePromptModal.tsx` | `digitalnagarik.com/id-card/` |
| `id-card/lib/class-utils.ts` | `digitalnagarik.com/id-card/` |
| `id-card/lib/document-qr.ts` | `digitalnagarik.com/id-card/` |
| `id-card/lib/document-status.ts` | `digitalnagarik.com/id-card/` |
| `id-card/prisma/bd-seed.ts` | `digitalnagarik.com/id-card/` |
| `id-card/prisma/schema.prisma` | `digitalnagarik.com/id-card/` |
| `id-card/prisma/seed.ts` | `digitalnagarik.com/id-card/` |

#### Category G: Documentation

| Source | Destination |
|--------|-------------|
| `docs/auth-system.md` | `digitalnagarik.com/docs/` |
| `docs/dn-credentials.md` | `digitalnagarik.com/docs/` |
| `docs/email-templates-plan.md` | `digitalnagarik.com/docs/` |
| `docs/registration-audit.md` | `digitalnagarik.com/docs/` |
| `plan-markdown-files/*.md` (16 files) | `digitalnagarik.com/plan-markdown-files/` |

#### Category H: Other

| Source | Destination | Notes |
|--------|-------------|-------|
| `public/index.html` | `digitalnagarik.com/public/index.html` | Public map app |
| `exports/` | `digitalnagarik.com/exports/` | Empty, placeholder |
| `.github/` | `digitalnagarik.com/.github/` | CI/CD workflows |

### 4.2 Files NOT to Copy

| File/Folder | Reason |
|-------------|--------|
| `server/` | Shared — both domains use the same API |
| `*.sql` | Database backups — not needed for live site |
| `*.zip` | Code backups — not needed for live site |
| `.git/` | Git repo — not needed in DocumentRoot |
| `.vscode/` | Editor settings — not needed |
| `digitalnagarik.com/` | Target directory — don't copy into itself |
| `node_modules/` | Not present at root level |

---

## 5. Configuration — What Changes

### 5.1 `.htaccess` — NO Changes Needed

The existing `.htaccess` rules are domain-agnostic. They use relative paths and `RewriteBase /`. No modification required.

### 5.2 `admin/index.html` — NO Changes Needed

The admin SPA uses relative API calls (`/api/v1/...`). Since both domains proxy `/api/` to the same backend, no CORS or URL changes needed.

### 5.3 `mobile/index.html` — NO Changes Needed

Same as admin — all API calls are relative.

### 5.4 Service Workers (`sw.js`, `sw-dn.js`) — REVIEW Required

Service Workers have **scope restrictions** tied to the origin. Since the origin changes from `digital-nagarik.20.198.178.24.nip.io` to `digitalnagarik.com`, the SW cache and scope will be independent per domain. This is actually desired behavior — each domain gets its own SW registration.

### 5.5 `manifest.json` — OPTIONAL Update

```json
{
  "start_url": "/",
  "scope": "/"
}
```

Both are relative, so no changes required unless you want to update the `name`/`short_name`.

---

## 6. Apache Configuration

### 6.1 Current VirtualHost (Already Deployed)

File: `/etc/apache2/sites-available/digitalnagarik.com-le-ssl.conf`

```apache
<VirtualHost *:443>
    ServerName digitalnagarik.com
    ServerAlias www.digitalnagarik.com
    DocumentRoot /home/digital-nagarik/public_html/digitalnagarik.com
    
    ProxyPreserveHost On
    ProxyPass /api/ http://127.0.0.1:3200/api/
    ProxyPassReverse /api/ http://127.0.0.1:3200/api/
    ProxyPass /ws http://127.0.0.1:3200/ws
    ProxyPassReverse /ws http://127.0.0.1:3200/ws
    
    SSLCertificateFile /etc/letsencrypt/live/digitalnagarik.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/digitalnagarik.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
```

**Status:** ✅ Already deployed and working. No changes needed after file copy.

### 6.2 nip.io VirtualHost — UNCHANGED

The existing nip.io Apache config remains untouched. Both VirtualHosts coexist independently.

---

## 7. Git Strategy

### 7.1 Current State

```
Remote: https://github.com/sackitbd/digital-nagarik.git
Branch: main
HEAD:   7a8d369 cleanup: remove unused top-unions fetch from analytics page
```

### 7.2 Strategy: Two Repositories (Recommended)

**Approach A — Separate `live` branch (Simplest)**

```
main          →  development / nip.io (current)
live          →  digitalnagarik.com (new branch, same repo)
```

- Create a `live` branch from `main`
- The `live` branch tracks the production deployment on `digitalnagarik.com`
- `main` continues as development
- No need for a second GitHub repo

**Approach B — Subtree split for the domain directory**

```
digitalnagarik.com/  →  its own git repo (optional, if you want
                         independent versioning for the live site)
```

### 7.3 Recommended Git Workflow

```bash
# 1. Create live branch
git checkout -b live
git push origin live

# 2. After copying files to digitalnagarik.com/, commit changes on live
git add digitalnagarik.com/
git commit -m "deploy: full platform migration to digitalnagarik.com"
git push origin live

# 3. Switch back to main for development
git checkout main
```

### 7.4 `.gitignore` Updates

Add to `.gitignore` (in the `live` branch if using separate branches):
```
digitalnagarik.com/exports/*
digitalnagarik.com/.well-known/*
```

### 7.5 What Gets Committed

| Files | Branch | Reason |
|-------|--------|--------|
| All files in `digitalnagarik.com/` | `live` | Production deployment tracking |
| `server/`, `admin/`, `mobile/`, etc. | `main` | Development — unchanged |

---

## 8. Execution Plan — Step by Step

### Phase 0: Pre-flight Checklist ✅ (Already Done)

- [x] Full database backup: `db_backup_full_2026-09-03_16-51-32.sql` (17MB)
- [x] Full code backup: `public_html_backup_2026-09-03_16-51-52.zip` (1.8MB)
- [x] Apache VirtualHost created and SSL deployed
- [x] DNS propagated: `digitalnagarik.com` → `20.198.178.24`
- [x] Empty target directory created: `digitalnagarik.com/`

### Phase 1: Copy Files (To Be Executed)

```bash
#!/bin/bash
# Copy all frontend files to digitalnagarik.com/
# Run from: /home/digital-nagarik/public_html/

SRC="/home/digital-nagarik/public_html"
DST="/home/digital-nagarik/public_html/digitalnagarik.com"

# Step 1: Copy root-level static files
cp "$SRC/index.html" "$DST/"
cp "$SRC/offline.html" "$DST/"
cp "$SRC/manifest.json" "$DST/"
cp "$SRC/favicon.svg" "$DST/"
cp "$SRC/logo.jpg" "$DST/"
cp "$SRC/icons.svg" "$DST/"
cp "$SRC/.htaccess" "$DST/"
cp "$SRC/sw.js" "$DST/"
cp "$SRC/sw-dn.js" "$DST/"
cp "$SRC/brochure-content.md" "$DST/"
cp "$SRC/USER-GUIDE.md" "$DST/"
cp "$SRC/SMS-SETUP.md" "$DST/"
cp "$SRC/plan.md" "$DST/"
cp "$SRC/prompt.md" "$DST/"
cp "$SRC/dn-credentials.md" "$DST/"

# Step 2: Copy directories recursively
cp -r "$SRC/admin" "$DST/"
cp -r "$SRC/mobile" "$DST/"
cp -r "$SRC/assets" "$DST/"
cp -r "$SRC/fonts" "$DST/"
cp -r "$SRC/icons" "$DST/"
cp -r "$SRC/id-card" "$DST/"
cp -r "$SRC/docs" "$DST/"
cp -r "$SRC/plan-markdown-files" "$DST/"
cp -r "$SRC/public" "$DST/"
cp -r "$SRC/exports" "$DST/"
cp -r "$SRC/.github" "$DST/"

# Step 3: Verify file count
echo "Source files (excl. server/node_modules/.git):"
find "$SRC" -not -path '*/node_modules/*' -not -path '*/.git/*' -not -name '*.sql' -not -name '*.zip' | wc -l
echo "Destination files:"
find "$DST" -type f | wc -l

# Step 4: Set correct ownership
chown -R azurefounderhub:azurefounderhub "$DST"
```

### Phase 2: Verify Apache Serves Content

```bash
# Test HTTP access
curl -sI https://digitalnagarik.com/
curl -sI https://digitalnagarik.com/admin/
curl -sI https://digitalnagarik.com/mobile/

# Test API proxy
curl -s https://digitalnagarik.com/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"test-admin@dn.test","password":"Test@123456"}'
```

### Phase 3: Git Commit

```bash
cd /home/digital-nagarik/public_html
git checkout -b live
git add digitalnagarik.com/
git commit -m "deploy: full platform migration to digitalnagarik.com

- All frontend files copied to digitalnagarik.com/
- Apache VirtualHost already configured with SSL
- Both nip.io and digitalnagarik.com run in parallel
- Shared backend: same API, DB, Redis"
git push origin live
git checkout main
```

### Phase 4: Browser Verification

1. Open `https://digitalnagarik.com/` → Landing page loads
2. Open `https://digitalnagarik.com/admin/` → Admin login page
3. Login with `test-admin@dn.test` / `Test@123456`
4. Navigate to Analytics → Verify zero cases (clean DB)
5. Open `https://digitalnagarik.com/mobile/` → Mobile PWA loads
6. Test `https://digital-nagarik.20.198.178.24.nip.io/admin/` → Still works independently

---

## 9. Parallel Operation Verification

### 9.1 What's Shared

| Resource | Shared? | Notes |
|----------|---------|-------|
| PostgreSQL Database | ✅ Yes | Same `dn-postgres` container |
| Redis Cache | ✅ Yes | Same `dn-redis` container |
| Node.js API | ✅ Yes | Same PM2 `dn-api` process |
| Docker containers | ✅ Yes | Same `dn-postgres`, `dn-redis` |
| File uploads | ✅ Yes | Uploaded files go to same server paths |

### 9.2 What's Independent

| Resource | Independent? | Notes |
|----------|-------------|-------|
| Static HTML/CSS/JS | ✅ Independent | Each domain has its own copy |
| Service Worker cache | ✅ Independent | Per-origin scope |
| SSL Certificate | ✅ Independent | Separate cert for each domain |
| Apache VirtualHost | ✅ Independent | Separate config files |
| Access logs | ✅ Independent | Separate log files |
| Browser localStorage | ✅ Independent | Per-origin storage |

### 9.3 Conflict-Free Guarantee

Since only static frontend files are duplicated and the backend is shared:
- **No data conflicts** — both domains read/write the same DB
- **No session conflicts** — JWT tokens are domain-agnostic (signed with same secret)
- **No race conditions** — single API process handles all requests
- **No cache conflicts** — Redis keys are API-level, not domain-specific

---

## 10. Rollback Plan

If anything goes wrong:

### Instant Rollback
```bash
# Disable the digitalnagarik.com Apache site
sudo a2dissite digitalnagarik.com-le-ssl.conf digitalnagarik.com.conf
sudo systemctl reload apache2
# digitalnagarik.com will stop responding
# nip.io continues unaffected
```

### Full Rollback
```bash
# Remove the copied files
rm -rf /home/digital-nagarik/public_html/digitalnagarik.com/*
# Or restore from zip backup
unzip public_html_backup_2026-09-03_16-51-52.zip -d /tmp/restore
```

### Database Rollback
```bash
# Restore from SQL backup (if ever needed)
PGPASSWORD='dN4g4r1k_2026_Secure' psql -h localhost -p 5434 \
  -U digital_nagarik -d digital_nagarik \
  < db_backup_full_2026-09-03_16-51-32.sql
```

---

## 11. Checklist

### Pre-Migration ✅
- [x] Full DB backup created (17MB SQL)
- [x] Full code backup created (1.8MB ZIP)
- [x] Apache VirtualHost created and SSL deployed
- [x] DNS propagated and verified
- [x] Target directory created
- [x] All shared services confirmed healthy

### Migration (To Be Executed)
- [ ] Copy all frontend files to `digitalnagarik.com/`
- [ ] Verify file count matches
- [ ] Set correct file ownership
- [ ] Test `https://digitalnagarik.com/` returns 200
- [ ] Test `https://digitalnagarik.com/admin/` loads
- [ ] Test `https://digitalnagarik.com/mobile/` loads
- [ ] Test API proxy works via new domain
- [ ] Test admin login works via new domain
- [ ] Test analytics page renders
- [ ] Verify `https://digital-nagarik.20.198.178.24.nip.io/` still works

### Post-Migration
- [ ] Create `live` git branch
- [ ] Commit and push all copied files
- [ ] Update `.gitignore` if needed
- [ ] Document the new deployment in README/plan.md
- [ ] Test on mobile device
- [ ] Test service worker registration on new domain
- [ ] Verify SSL auto-renewal is configured
- [ ] Monitor Apache error logs for 24 hours

---

## Appendix A: Directory Tree After Migration

```
/home/digital-nagarik/public_html/
├── digitalnagarik.com/          ← NEW: Live domain DocumentRoot
│   ├── index.html
│   ├── offline.html
│   ├── manifest.json
│   ├── favicon.svg
│   ├── logo.jpg
│   ├── icons.svg
│   ├── .htaccess
│   ├── sw.js
│   ├── sw-dn.js
│   ├── admin/
│   │   └── index.html
│   ├── mobile/
│   │   ├── index.html
│   │   ├── verify.html
│   │   ├── manifest.json
│   │   ├── css/ (5 files)
│   │   └── js/ (13 files)
│   ├── assets/ (8 files)
│   ├── fonts/ (1 file)
│   ├── icons/ (2 files)
│   ├── id-card/ (15 files)
│   ├── docs/ (4 files)
│   ├── plan-markdown-files/ (16 files)
│   ├── public/
│   ├── exports/
│   └── .github/
│
├── admin/                       ← UNCHANGED: nip.io admin
├── mobile/                      ← UNCHANGED: nip.io mobile
├── assets/                      ← UNCHANGED: nip.io assets
├── server/                      ← SHARED: API backend
├── index.html                   ← UNCHANGED: nip.io landing
└── ... (all other files unchanged)
```

## Appendix B: API Routes Reference

| Route | Method | Auth | Description |
|-------|--------|------|-------------|
| `/api/v1/auth/login` | POST | No | User login |
| `/api/v1/auth/register` | POST | No | Volunteer registration |
| `/api/v1/auth/refresh` | POST | No | Token refresh |
| `/api/v1/cases` | GET/POST | Yes | List/Create civic cases |
| `/api/v1/cases/:id` | GET/PATCH | Yes | Case detail/update |
| `/api/v1/cases/:id/timeline` | POST | Yes | Status transition |
| `/api/v1/districts` | GET | No | List districts |
| `/api/v1/districts/:id/upazilas` | GET | No | List upazilas |
| `/api/v1/users` | GET/POST | Yes | List/Create users |
| `/api/v1/users/:id` | GET/PATCH | Yes | User detail/update |
| `/api/v1/analytics/overview` | GET | Yes | Dashboard stats |
| `/api/v1/analytics/monthly-trends` | GET | Yes | Monthly case trends |
| `/api/v1/analytics/district-comparison` | GET | Yes | District comparison |
| `/api/v1/analytics/volunteer-performance` | GET | Yes | Volunteer metrics |
| `/api/v1/admin/*` | * | Yes | Admin operations |
| `/api/v1/id-cards/*` | * | Yes | ID card generation |
| `/api/v1/certificates/*` | * | Yes | Certificate management |
| `/api/v1/advocacy/*` | * | Yes | Advocacy letters |
| `/api/v1/reports/*` | * | Yes | Report generation |
| `/api/v1/sms/*` | * | Yes | SMS campaigns |
| `/api/v1/settings` | GET/PUT | Yes | App settings |
| `/api/v1/exports/*` | * | Yes | Data exports |
| `/api/v1/milestone/*` | * | Yes | Milestone tracking |
| `/api/v1/public-map/*` | * | No | Public case map |
| `/api/v1/dashboard/*` | * | Yes | Dashboard data |
| `/api/v1/notifications/*` | * | Yes | Notification rules |
| `/api/v1/verify/*` | * | No | Email/NID verification |
| `/api/v1/student-applications/*` | * | Yes | Student enrollment |

---

> **End of Migration Plan**  
> Ready for execution. No deletions, no moves — pure copy and verify.