Files
Goa-gel-fullstack/docs/architecture/ARCHITECTURE_GUIDE.md
Mahi 80566bf0a2 feat: Goa GEL Blockchain e-Licensing Platform - Full Stack Implementation
Complete implementation of the Goa Government e-Licensing platform with:

Backend:
- NestJS API with JWT authentication
- PostgreSQL database with Knex ORM
- Redis caching and session management
- MinIO document storage
- Hyperledger Besu blockchain integration
- Multi-department workflow system
- Comprehensive API tests (266/282 passing)

Frontend:
- Angular 21 with standalone components
- Angular Material + TailwindCSS UI
- Visual workflow builder
- Document upload with progress tracking
- Blockchain explorer integration
- Role-based dashboards (Admin, Department, Citizen)
- E2E tests with Playwright (37 tests)

Infrastructure:
- Docker Compose orchestration
- Blockscout blockchain explorer
- Development and production configurations
2026-02-07 10:23:29 -04:00

27 KiB

Goa GEL Blockchain Document Verification Platform - Architecture Guide

Executive Summary

The Goa Government E-License (GEL) Blockchain Document Verification Platform is a comprehensive solution for managing government licenses and permits through a multi-department approval workflow backed by blockchain technology. The platform leverages Hyperledger Besu with QBFT consensus to ensure tamper-proof records of license issuance.

Key Innovation: Multi-department approval workflows with immutable blockchain records and soulbound NFT certificates.


1. System Context (C4 Level 1)

Overview

The GEL platform serves as the central integration point for government entities, citizens, and external systems.

Actors & Systems

External Actors

  • Citizens: Submit license requests, upload documents, track approval status
  • Government Departments: Configure workflows, review and approve requests
  • Department Operators: Manage department users and approval rules
  • Platform Operators: System administration, monitoring, maintenance

External Systems

  • DigiLocker Mock: Verifies document authenticity (POC implementation)
  • Legacy Department Systems: Integration for existing government databases
  • National Blockchain Federation: Future interoperability with national systems

2. Container Architecture (C4 Level 2)

Layered Architecture

Frontend Layer

Next.js 14 + shadcn/ui
├── Pages: Dashboard, License Requests, Approvals
├── Components: Forms, Document Upload, Status Tracking
├── State: React Context + TanStack Query
└── Styling: Tailwind CSS (dark theme optimized)
Port: 3000

API & Backend Layer

NestJS TypeScript API Gateway (Port 3001)
├── Auth Service (API Key + Secret POC)
├── Workflow Service
├── Approval Service
├── Document Service
└── Blockchain Integration Module

Data Layer

PostgreSQL Database (Port 5432)
├── license_requests table
├── approvals table
├── documents table
├── audit_logs table
└── department_registry table

Redis Cache (Port 6379)
├── Session management
├── Workflow state cache
└── Real-time notifications

MinIO Object Storage (Port 9000)
├── License documents (PDFs)
├── Supporting images
├── Document proofs
└── Generated certificates

Blockchain Layer

Hyperledger Besu Network (QBFT Consensus)
├── 4 Validator Nodes (Ports 8545-8548)
├── RPC Endpoints
├── Peer-to-Peer Network
└── Smart Contracts:
    ├── LicenseRequestNFT (ERC-721 Soulbound)
    ├── ApprovalManager
    ├── DepartmentRegistry
    └── WorkflowRegistry

3. Blockchain Architecture Deep Dive

Hyperledger Besu Configuration

Network Topology

4 Validator Nodes (QBFT Consensus)
├── Validator 1 (RPC: 8545, P2P: 30303)
├── Validator 2 (RPC: 8546, P2P: 30304)
├── Validator 3 (RPC: 8547, P2P: 30305)
└── Validator 4 (RPC: 8548, P2P: 30306)

Consensus Rule: Requires 3/4 (75%) validator approval
Block Time: ~12 seconds

Smart Contracts

1. LicenseRequestNFT (ERC-721 Soulbound)

Contract Type: ERC-721 (Non-Fungible Token)
Purpose: Issue immutable, non-transferable license certificates

Key Functions:
- mint(applicant, licenseHash, metadataURI, issuerDept)
  └─ Creates NFT, emits Transfer event
- burn(tokenId)
  └─ Revokes license, removes from circulation
- ownerOf(tokenId)  address
- tokenURI(tokenId)  string (IPFS or HTTP)

Soulbound Property:
- _beforeTokenTransfer() override prevents transfers
- Only issuer can revoke
- Applicant owns NFT but cannot sell/transfer

2. ApprovalManager

Purpose: Record and manage multi-department approvals

Key Functions:
- recordApproval(licenseHash, department, signature)
  └─ Logs approval from specific department
- recordRejection(licenseHash, department, reason)
  └─ Logs rejection with reason
- requestChanges(licenseHash, department, details)
  └─ Request changes from applicant
- getApprovalChain(licenseHash)  approvalRecord[]
  └─ Full approval history

Data Structures:
ApprovalRecord {
  licenseHash: bytes32,
  department: address,
  approvalStatus: enum (PENDING, APPROVED, REJECTED, CHANGES_REQUESTED),
  timestamp: uint256,
  notes: string,
  signature: bytes
}

3. DepartmentRegistry

Purpose: Maintain department information and approvers

Key Functions:
- registerDepartment(deptId, deptName, metadata)
- setApprovers(deptId, approverAddresses[])
- getApprovers(deptId)  address[]
- isDeptApprover(deptId, address)  bool

Data Structure:
Department {
  deptId: bytes32,
  name: string,
  approvers: address[],
  isActive: bool,
  registeredAt: uint256
}

4. WorkflowRegistry

Purpose: Define and manage license approval workflows

Key Functions:
- defineWorkflow(workflowId, licenseType, departments[])
- getWorkflow(workflowId)  workflowConfig
- getNextApprovers(workflowId, currentStep)  address[]

Data Structure:
Workflow {
  workflowId: bytes32,
  licenseType: string,
  departments: Department[],
  isSequential: bool,
  timeout: uint256,
  createdAt: uint256
}

Example: Resort License POC
├─ Step 1: Tourism Department Review (Parallel possible)
└─ Step 2: Fire Safety Department Review

On-Chain vs Off-Chain Data Split

On-Chain Data (Blockchain State)

Immutable & Transparent
├── License Hashes (SHA-256 of documents)
├── Approval Records (with signatures)
├── Department Registry
├── Workflow Definitions
└── NFT Ownership Records

Benefits:
- Tamper-proof
- Publicly verifiable
- Immutable audit trail
- Non-repudiation

Off-Chain Data (PostgreSQL + MinIO)

Flexible & Queryable
├── Full License Request Details
├── Applicant Information
├── Document Metadata
├── Workflow State (current step)
├── User Comments & Notes
├── Audit Logs (indexed queries)
└── Actual Document Files (PDFs, images)

Benefits:
- Searchable
- Quick queries
- Scalable storage
- Privacy controls

Data Linking

SHA-256 Hash: Immutable Bridge Between On-Chain & Off-Chain

Document File
    ↓ (hash)
SHA-256: 0x7f8c...a1b2
    ↓ (stored on-chain)
Smart Contract State
    ↓ (referenced in off-chain DB)
PostgreSQL record contains this hash
    ↓ (verification)
Anyone can hash the document and verify it matches blockchain record

4. Workflow State Machine

License Request States

DRAFT
├─ Initial state
├─ Applicant can edit
├─ No blockchain record
└─ Can transition to: SUBMITTED or [abandon]

        ↓ [submit for review]

SUBMITTED
├─ Hash recorded on blockchain
├─ Locked from editing
├─ Routed to appropriate departments
└─ Can transition to: IN_REVIEW or [withdraw]

        ↓ [route to approvers]

IN_REVIEW
├─ Multi-department approval workflow
├─ Can be parallel or sequential
├─ Department approvers review documents
└─ Can transition to: APPROVED, REJECTED, or PENDING_RESUBMISSION

        ├─ [all approve] → APPROVED
        ├─ [any reject] → REJECTED
        └─ [changes requested] → PENDING_RESUBMISSION

PENDING_RESUBMISSION
├─ Applicant notified of required changes
├─ Time-limited window for corrections
├─ Can resubmit documents
└─ Can transition to: SUBMITTED or [withdraw]

        ↓ [resubmit with changes]

SUBMITTED (again in workflow)
        ↓ [back to IN_REVIEW]

APPROVED (Final State)
├─ All departments approved
├─ ERC-721 Soulbound NFT minted
├─ License certificate generated
├─ Verifiable on blockchain
└─ Can transition to: REVOKED only

        ↓ [license revoked/expired]

REVOKED
├─ License cancelled
├─ NFT burned from circulation
├─ Audit trail preserved
└─ End state

REJECTED (Terminal State)
├─ Request denied permanently
├─ Reason recorded on-chain
├─ Applicant can appeal (future feature)
└─ Can transition to: DRAFT (reapply)

Approval States (Per Department)

PENDING
├─ Awaiting department review
├─ Notification sent to approvers
└─ Can transition to: APPROVED, REJECTED, or CHANGES_REQUESTED

    ├─ [approve] → APPROVED
    ├─ [reject] → REJECTED
    └─ [request changes] → CHANGES_REQUESTED

APPROVED
├─ Department approved this request
└─ Recorded on blockchain with signature

REJECTED
├─ Department rejected request
├─ Reason recorded
└─ Triggers overall REJECTED state

CHANGES_REQUESTED
├─ Department needs clarifications/corrections
├─ Specific details provided
└─ Applicant must resubmit

REVIEW_REQUIRED
├─ Resubmitted after changes
├─ Needs re-review
└─ Back to PENDING

5. End-to-End Data Flow

11-Step Resort License Approval Process

Step 1-2: Submission & Upload

1. Citizen creates Resort License request in Next.js frontend
2. Fills in applicant information (name, contact, resort details)
3. Uploads supporting documents:
   - Property proof
   - Health certificate
   - Fire safety plan
   - Environmental clearance
   - etc.

Frontend sends to NestJS API:
POST /licenses/create
├── Body: License form data
├── Files: Multipart documents
└── Auth: API Key header

Step 3: Document Processing & Hashing

3a. NestJS Document Service:
    - Receives files
    - Validates file types and sizes
    - Uploads to MinIO with unique IDs
    - Generates SHA-256 hash of each document
    - Creates document metadata records in PostgreSQL

3b. License Request:
    - Created with status: DRAFT
    - All documents linked via hashes
    - No blockchain record yet

3c. API Response to Frontend:
    - License request ID
    - Document upload status
    - License saved locally for editing

Step 4: Blockchain Recording

4a. When citizen submits for approval:
    - API aggregates all document hashes
    - Creates combined SHA-256 (licenseHash)
    - Calls smart contract via RPC

4b. Smart Contract Call:
    POST https://besu-validator-1:8545
    ├─ Method: DocumentRegistrar.recordDocumentHash()
    ├─ Params:
    │  ├─ licenseHash: bytes32
    │  ├─ licenseType: "ResortLicense"
    │  ├─ department: address (Tourism Dept)
    │  └─ timestamp: uint256
    └─ Result: Transaction receipt with block number

4c. QBFT Consensus:
    - Transaction sent to all 4 validators
    - Each validator verifies signature and state
    - 3/4 validators must agree
    - Block included in chain
    - Event: DocumentHashRecorded emitted

4d. Database Update:
    UPDATE license_requests
    SET status = 'SUBMITTED',
        blockchain_tx_hash = '0x...',
        blockchain_block_num = 12345,
        submitted_at = NOW()
    WHERE request_id = 'LR-001'

Step 5-6: Route to Departments (Parallel)

5a. Workflow Engine determines routing:
    - License type: ResortLicense
    - Query WorkflowRegistry for approval workflow
    - Returns: [Tourism Department, Fire Safety Department]
    - Mode: Parallel (can approve simultaneously)

5b. Create Approval Requests:
    INSERT INTO approvals
    ├─ approval_id: 'APR-001-TOURISM'
    ├─ license_id: 'LR-001'
    ├─ department: 'Tourism'
    ├─ status: 'PENDING'
    ├─ assigned_to: [list of approver emails]
    └─ created_at: NOW()

    INSERT INTO approvals
    ├─ approval_id: 'APR-001-FIRE'
    ├─ license_id: 'LR-001'
    ├─ department: 'Fire Safety'
    ├─ status: 'PENDING'
    ├─ assigned_to: [list of approver emails]
    └─ created_at: NOW()

5c. Webhook Notifications (via Redis Pub/Sub):
    EventPublished: "approval.assigned"
    ├─ recipient: approver@tourism.gov.in
    ├─ action: "Resort License #LR-001 awaiting review"
    └─ link: "https://gel-platform/approvals/APR-001-TOURISM"

6. Parallel Approval Assignment:
    - Tourism Department reviews resort location & management
    - Fire Safety Department reviews fire safety plan
    - Both can review simultaneously

Step 7-8: Department Approvals

7a. Tourism Approver Reviews:
    Frontend shows:
    ├─ Applicant details (name, experience)
    ├─ Resort location (map, nearby facilities)
    ├─ Proposed capacity & amenities
    ├─ Property proof documents
    └─ Can download or view embedded

7b. Tourism Approver Approves:
    POST /approvals/APR-001-TOURISM/approve
    ├─ Body:
    │  ├─ decision: "APPROVED"
    │  ├─ comments: "Location suitable, management experienced"
    │  └─ signature: signatureHash (if using digital signature)
    └─ Auth: Department user credentials

7c. Backend Processing:
    a) Update database:
       UPDATE approvals
       SET status = 'APPROVED',
           reviewed_by = 'approver@tourism.gov.in',
           reviewed_at = NOW(),
           comments = 'Location suitable...'
       WHERE approval_id = 'APR-001-TOURISM'

    b) Record on blockchain:
       Call ApprovalManager.recordApproval()
       ├─ licenseHash: 0x7f8c...a1b2
       ├─ department: 0xTourismDeptAddress
       ├─ status: APPROVED
       ├─ timestamp: block.timestamp
       └─ Result: Event ApprovalRecorded emitted

    c) Update workflow state (Redis cache):
       KEY: "license:LR-001:approvals"
       VALUE: {
         "APR-001-TOURISM": {"status": "APPROVED", ...},
         "APR-001-FIRE": {"status": "PENDING", ...}
       }

7d. Fire Safety Approver Reviews & Approves (Parallel):
    Similar process with fire safety specific documents

8. Parallel Completion:
    Both departments complete their approvals
    - Database updated
    - Blockchain events recorded
    - Workflow cache synchronized

Step 9: Final Approval & NFT Minting

9a. Workflow Engine Monitors State:
    Check all approvals for license LR-001
    Result: 2/2 approvals = APPROVED

9b. Trigger License Approval:
    a) Generate License Certificate:
       - Template: ResortLicense_Template.pdf
       - Fill with: Applicant name, Resort location, Date, etc.
       - Upload to MinIO: /certificates/LR-001-cert.pdf
       - Hash: SHA-256 of PDF

    b) Prepare NFT Metadata:
       {
         "name": "Goa Resort License - [Resort Name]",
         "description": "Blockchain-verified Resort License issued by...",
         "image": "https://storage/license-badge.png",
         "attributes": {
           "license_type": "ResortLicense",
           "issue_date": "2026-02-03",
           "expiry_date": "2027-02-03",
           "issuer": "Tourism Department, Goa",
           "certificate_hash": "0xabcd...",
           "license_request_hash": "0x7f8c...",
           "applicant": "Resort Owner Name"
         }
       }
       Upload to MinIO: /metadata/LR-001-metadata.json

    c) Mint Soulbound NFT:
       Call LicenseRequestNFT.mint()
       ├─ to: applicant_wallet_address
       ├─ licenseHash: 0x7f8c...a1b2
       ├─ metadataURI: "https://storage/metadata/LR-001-metadata.json"
       ├─ issuerDept: tourismDeptAddress
       └─ Result: Transaction with tokenId

    d) QBFT Consensus & Finalization:
       - 3/4 validators approve mint transaction
       - NFT created in smart contract state
       - tokenId: 1001 (auto-incremented)
       - ownerOf(1001) = applicant_wallet
       - Event: Transfer(address(0), applicant, 1001)

    e) Update Database:
       UPDATE license_requests
       SET status = 'APPROVED',
           nft_token_id = 1001,
           nft_address = '0xLicenseNFTContractAddress',
           approved_at = NOW()
       WHERE request_id = 'LR-001'

       INSERT INTO audit_logs
       VALUES (license_id='LR-001', action='APPROVED', ..., timestamp=NOW())

Step 10: Notifications & State Update

10a. Send Approval Notification:
     Webhook Event: "license.approved"
     ├─ recipient: citizen@email.com
     ├─ subject: "Your Resort License Has Been Approved!"
     ├─ body: "License #LR-001 approved on [date]"
     └─ link: "https://gel-platform/licenses/LR-001"

10b. Update Frontend:
     WebSocket notification to citizen's browser
     ├─ Status changed to: APPROVED
     ├─ Show NFT badge
     ├─ Enable download buttons
     └─ Display approval timeline

10c. Cache Invalidation:
     Redis invalidates:
     ├─ license:LR-001:* (all license data)
     ├─ citizen:citizen@email.com:licenses
     └─ dashboard:pending-approvals
     (Fresh data will be loaded on next request)

10d. Update Department Dashboards:
     ├─ Remove from "Pending Review" list
     ├─ Add to "Approved" list with approval details
     └─ Show NFT minting confirmation

Step 11: License Verification

11a. Citizen Downloads License Certificate:
     GET /licenses/LR-001/certificate

11b. Certificate Generation:
     a) Retrieve license metadata from DB
     b) Get NFT details from blockchain
     c) Generate PDF with all details + QR code
     d) QR Code contains: https://gel-verify.goa.gov.in?verify=0x7f8c...a1b2
     e) Return PDF

11c. Third-party Verification (e.g., Hotel Inspector):
     a) Scan QR code on license certificate
     b) GET https://gel-verify.goa.gov.in/verify?hash=0x7f8c...a1b2

     c) Verification Service:
        i. Query blockchain for this hash
        ii. Check if NFT still valid (not revoked/burned)
        iii. Return: {
          "valid": true,
          "license_type": "ResortLicense",
          "holder": "Resort Name",
          "issue_date": "2026-02-03",
          "expiry_date": "2027-02-03",
          "issuer": "Tourism Department"
        }
        iv. Inspector can verify instantly without needing central server

11d. On-Chain Verification:
     Call LicenseRequestNFT.ownerOf(tokenId)
     └─ Returns: citizen_address (verifying NFT still exists)

     Call ApprovalManager.getApprovalChain(licenseHash)
     └─ Returns: Complete approval history [Tourism: APPROVED, Fire: APPROVED]

6. Deployment Architecture

Docker Compose Environment

All services run in isolated containers with defined networks and volumes.

Services Overview

version: '3.9'

services:
  # Frontend
  frontend:
    image: node:18-alpine
    build: ./frontend
    container_name: gel-frontend
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://api:3001
      - NEXT_PUBLIC_BLOCKCHAIN_RPC=http://besu-1:8545
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      - api
    networks:
      - gel-network

  # NestJS Backend API
  api:
    image: node:18-alpine
    build: ./backend
    container_name: gel-api
    ports:
      - "3001:3001"
    environment:
      - DATABASE_URL=postgresql://gel_user:${DB_PASSWORD}@postgres:5432/goa_gel
      - REDIS_URL=redis://redis:6379
      - MINIO_ENDPOINT=minio:9000
      - BLOCKCHAIN_RPC=http://besu-1:8545
      - BLOCKCHAIN_NETWORK_ID=1337
      - API_SECRET_KEY=${API_SECRET_KEY}
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      - postgres
      - redis
      - minio
      - besu-1
    networks:
      - gel-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # PostgreSQL Database
  postgres:
    image: postgres:15-alpine
    container_name: gel-postgres
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=goa_gel
      - POSTGRES_USER=gel_user
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - gel-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U gel_user"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis Cache
  redis:
    image: redis:7-alpine
    container_name: gel-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    networks:
      - gel-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # MinIO S3-compatible Storage
  minio:
    image: minio/minio:latest
    container_name: gel-minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
    volumes:
      - minio_data:/minio_data
    command: server /minio_data --console-address ":9001"
    networks:
      - gel-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  # Hyperledger Besu Validator Nodes
  besu-1:
    image: hyperledger/besu:latest
    container_name: gel-besu-1
    ports:
      - "8545:8545"  # RPC
      - "30303:30303"  # P2P
    volumes:
      - ./besu/config.toml:/etc/besu/config.toml
      - ./besu/genesis.json:/etc/besu/genesis.json
      - ./besu/keys/node1:/opt/besu/keys
      - besu_data_1:/data
    environment:
      - BESU_RPC_HTTP_ENABLED=true
      - BESU_RPC_HTTP_HOST=0.0.0.0
      - BESU_RPC_HTTP_PORT=8545
      - BESU_RPC_WS_ENABLED=true
      - BESU_RPC_WS_HOST=0.0.0.0
    networks:
      - gel-network
    depends_on:
      - besu-2
      - besu-3
      - besu-4

  besu-2:
    image: hyperledger/besu:latest
    container_name: gel-besu-2
    ports:
      - "8546:8545"
      - "30304:30303"
    volumes:
      - ./besu/config.toml:/etc/besu/config.toml
      - ./besu/genesis.json:/etc/besu/genesis.json
      - ./besu/keys/node2:/opt/besu/keys
      - besu_data_2:/data
    networks:
      - gel-network

  besu-3:
    image: hyperledger/besu:latest
    container_name: gel-besu-3
    ports:
      - "8547:8545"
      - "30305:30303"
    volumes:
      - ./besu/config.toml:/etc/besu/config.toml
      - ./besu/genesis.json:/etc/besu/genesis.json
      - ./besu/keys/node3:/opt/besu/keys
      - besu_data_3:/data
    networks:
      - gel-network

  besu-4:
    image: hyperledger/besu:latest
    container_name: gel-besu-4
    ports:
      - "8548:8545"
      - "30306:30303"
    volumes:
      - ./besu/config.toml:/etc/besu/config.toml
      - ./besu/genesis.json:/etc/besu/genesis.json
      - ./besu/keys/node4:/opt/besu/keys
      - besu_data_4:/data
    networks:
      - gel-network

  # Prometheus Monitoring
  prometheus:
    image: prom/prometheus:latest
    container_name: gel-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    networks:
      - gel-network

  # Grafana Dashboards
  grafana:
    image: grafana/grafana:latest
    container_name: gel-grafana
    ports:
      - "3002:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana_storage:/var/lib/grafana
      - ./monitoring/grafana/provisioning:/etc/grafana/provisioning
    depends_on:
      - prometheus
    networks:
      - gel-network

networks:
  gel-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

volumes:
  postgres_data:
  redis_data:
  minio_data:
  besu_data_1:
  besu_data_2:
  besu_data_3:
  besu_data_4:
  prometheus_data:
  grafana_storage:

Environment Configuration

# .env file
DB_PASSWORD=your_secure_db_password
MINIO_PASSWORD=your_secure_minio_password
API_SECRET_KEY=your_secure_api_key
GRAFANA_PASSWORD=your_secure_grafana_password

# Optional: Domain configuration
FRONTEND_URL=https://gel-platform.goa.gov.in
API_URL=https://api.gel-platform.goa.gov.in

Startup Process

# 1. Build all images
docker-compose build

# 2. Start all services
docker-compose up -d

# 3. Initialize database
docker-compose exec postgres psql -U gel_user -d goa_gel -f /docker-entrypoint-initdb.d/init.sql

# 4. Verify services
docker-compose ps
docker-compose logs -f api

# 5. Access services
# Frontend: http://localhost:3000
# API: http://localhost:3001
# MinIO Console: http://localhost:9001
# Prometheus: http://localhost:9090
# Grafana: http://localhost:3002

7. Key Technical Benefits

Immutability & Trust

  • Once a license is recorded on blockchain, it cannot be tampered with
  • Full approval history is cryptographically verifiable
  • Any party can independently verify license authenticity

Transparency

  • Multi-department approvals are publicly recorded
  • Citizens can see real-time status of their requests
  • Audit trail of every action is preserved

Efficiency

  • Parallel approval workflows reduce processing time
  • Automated notifications keep stakeholders informed
  • Real-time status updates via WebSocket/Redis

Security

  • API Key + Secret authentication (POC)
  • JWT tokens for session management
  • Role-based access control (RBAC)
  • Immutable audit logs prevent tampering

Scalability

  • Off-chain document storage (MinIO)
  • On-chain hashing ensures scalability
  • Redis caching for high-traffic operations
  • Horizontal scaling possible for all services

Interoperability

  • ERC-721 standard enables future integrations
  • REST API for third-party systems
  • Blockchain records can be shared with National Blockchain Federation
  • Legacy system integration via adapters

8. Future Enhancements

Phase 2 (Post-POC)

  • OAuth 2.0 integration with DigiLocker (real, not mocked)
  • Multi-signature smart contracts for critical decisions
  • Insurance coverage integration

Phase 3

  • DAO governance for workflow changes
  • Cross-chain interoperability (Cosmos/Polkadot)
  • Mobile app for on-the-go approvals

Phase 4

  • AI-powered document verification
  • National Blockchain Federation integration
  • License marketplace for portability

9. File Locations

All diagrams and related files are located in:

/sessions/cool-elegant-faraday/mnt/Goa-GEL/

Mermaid Diagram Files (.mermaid)

  • system-context.mermaid - C4 Context diagram
  • container-architecture.mermaid - Container architecture
  • blockchain-architecture.mermaid - Blockchain layer details
  • workflow-state-machine.mermaid - State transitions
  • data-flow.mermaid - Sequence diagram
  • deployment-architecture.mermaid - Docker Compose setup

HTML Preview Files (.html)

  • Each .mermaid file has a corresponding .html file for browser viewing
  • Open in any modern web browser (Chrome, Firefox, Safari, Edge)
  • Uses CDN-hosted mermaid.js for rendering

Conversion to PNG

See the README.md file for multiple options to convert diagrams to PNG format.


10. Getting Started

  1. Review Diagrams

    • Open .html files in browser for quick visualization
    • Or visit mermaid.live to paste .mermaid content
  2. Understand Architecture

    • Start with system-context for high-level overview
    • Move to container-architecture for technical details
    • Deep-dive with blockchain-architecture for smart contracts
  3. Implement

    • Use deployment-architecture for Docker Compose setup
    • Reference data-flow for integration points
    • Review workflow-state-machine for business logic
  4. Documentation

    • Convert diagrams to PNG for presentations
    • Include in technical documentation
    • Share with stakeholders for feedback

Document Version: 1.0
Platform: Goa GEL (Goa Government E-License)
Last Updated: 2026-02-03
Status: POC Phase 1