# Nexus Deployment Architecture

> Build 86 — Platform Foundation POC  
> Last updated: 2026-06-05

## Purpose

This document describes how Nexus components are deployed from installer through cloud backend, update channel, and Coolify topology. It covers the **POC foundation** — not production hardening.

## Component overview

| Layer | Component | Role |
|-------|-----------|------|
| Device | **NexusSetup.exe** | WPF installer — prerequisites, shell deploy, local identity seed |
| Device | **NexusShell** | WPF overlay shell, local JSON identity, optional remote enrollment |
| Device | **In-process Agent** | Heartbeat + inventory on `:5055`, registers with Identity API |
| Cloud | **NexusIdentity.Api** | Identity + Control Center foundation API (SQLite/PostgreSQL) |
| Cloud | **Download CDN** | ZIP + `latest.json` update manifest |
| Ops | **Coolify** | Container host for backend + static downloads |

## End-to-end flow

```mermaid
flowchart TB
    subgraph Device["Windows Device"]
        Setup[NexusSetup.exe]
        Shell[NexusShell]
        Agent[In-process Agent]
        LocalId[(Local JSON Identity)]
    end

    subgraph Cloud["nexus.ninjakernen.info / Coolify"]
        Proxy[Reverse Proxy]
        API[NexusIdentity.Api]
        DB[(SQLite / PostgreSQL)]
        CDN[Downloads / latest.json]
    end

    Setup -->|install + seed| Shell
    Setup -->|seed org/user/device| LocalId
    Shell -->|enrollment| LocalId
    Shell -->|optional POST /api/enrollment/register| API
    Agent -->|heartbeat / register| API
    Shell -->|GET /api/control-center/dashboard| API
    API --> DB
    Shell -->|check updates| CDN
    Proxy --> API
    Proxy --> CDN
```

## Installer → device

1. **NexusSetup.exe** copies NexusShell to `%ProgramFiles%\Ninja Nexus\` (or chosen path).
2. Installer seeds **local identity JSON** (organization, user, device, trust) when selected.
3. Shell starts with `--safe-poc` overlay mode (Explorer remains available in POC).
4. First-run **Setup Flow** or **Enrollment** wizard writes device record locally.

Local identity is the **source of truth on device** until remote enrollment is configured and approved.

## Identity API

**Project:** `source/nexus-identity/NexusIdentity.Api`

| Concern | Storage | Notes |
|---------|---------|-------|
| Auth users / JWT | EF `Users`, `RefreshTokens` | POC seed users |
| Organizations | EF `Organizations` | 3 orgs seeded from shell catalog |
| Devices | EF `Devices` + `DeviceTrust` | Replaces in-memory registry |
| Enrollment | EF `EnrollmentRequests` | Pending → admin approve |
| Policies | EF `Policies` | Foundation schema + `PolicyService` |
| Control Center | `/api/control-center/dashboard` | Aggregated platform view |

**Connection strings:**

- Local dev: SQLite `Data Source=nexus-identity.db`
- Coolify: `NEXUS_DB_CONNECTION` → PostgreSQL (when healthy)

**Environment overrides:** `NEXUS_DB_CONNECTION`, `NEXUS_JWT_SIGNING_KEY`, `NEXUS_ALLOWED_ORIGINS`, `NEXUS_DOMAIN`

## Shell → remote platform

Configure in `appsettings.json`:

```json
{
  "ControlCenter": {
    "BaseUrl": "https://your-identity-api.example"
  }
}
```

When `ControlCenter:BaseUrl` is set:

1. After local enrollment, shell **POST**s to `/api/enrollment/register`.
2. Settings → **Control Center** fetches `/api/control-center/dashboard`.
3. Admin approves via **POST** `/api/enrollment/approve` (POC — no auth yet).

If BaseUrl is empty, platform features remain **local-only**.

## Update channel

```mermaid
sequenceDiagram
    participant Shell as NexusShell
    participant CDN as nexus.ninjakernen.info/downloads
    participant User as User

    Shell->>CDN: GET latest.json
    CDN-->>Shell: version, build, zip URL, sha256
    alt update available
        Shell->>CDN: GET NexusShell-{version}.zip
        Shell->>Shell: verify SHA256, stage, restart
    end
```

- Manifest: `https://nexus.ninjakernen.info/downloads/latest.json`
- Build tracked in `config/version.poc.json` (build **86**)
- Auto-install disabled by default in POC (`Update:AutoInstall: false`)

## Coolify topology (POC)

```mermaid
flowchart LR
    subgraph CoolifyHost["Coolify Host"]
        subgraph Stack["Nexus Stack"]
            Backend[nexus-backend container<br/>NexusIdentity.Api :8080]
            PG[(nexus-db PostgreSQL<br/>unhealthy in POC)]
            Static[Static downloads volume]
        end
    end

    Internet((Internet)) --> Domain[nexus.ninjakernen.info]
    Domain -->|/downloads/*| Static
    Domain -.->|/health, /api/* planned| Backend
    Backend --> PG
    Backend -.->|fallback SQLite| Backend
```

**Current POC gaps:**

- Main domain `/health` returns 404 — proxy routes not fully wired
- PostgreSQL container unhealthy — API uses SQLite in container
- No CI/CD — manual `dotnet publish` + Coolify deploy

## Production path (future)

| POC today | Production target |
|-----------|-------------------|
| Overlay shell | Winlogon / shell replacement |
| Local JSON + optional remote | Central enrollment + MDM-style trust |
| In-process agent | Windows Service + MSI |
| SQLite / broken PG | Managed PostgreSQL + backups |
| Manual deploy | CI/CD → Coolify / Azure |
| Open enrollment approve | JWT-protected admin API + Control Center UI |

## Related docs

- [NEXUS_POLICY_ARCHITECTURE.md](./NEXUS_POLICY_ARCHITECTURE.md)
- [../evidence/nexus-platform-foundation/SUMMARY.md](../evidence/nexus-platform-foundation/SUMMARY.md)
- [../evidence/nexus-coolify-project-setup/SUMMARY.md](../evidence/nexus-coolify-project-setup/SUMMARY.md)
