# DCRouter Storage Overview

DCRouter uses a **unified database layer** backed by `@push.rocks/smartdata` for all persistent data. All data is stored as typed document classes in a single database.

## Database Modes

### Embedded Mode (default)
When no external MongoDB URL is provided, DCRouter starts an embedded `LocalSmartDb` (Rust-based MongoDB-compatible engine) via `@push.rocks/smartdb`.

```
~/.serve.zone/dcrouter/tsmdb/
```

### External Mode
Connect to any MongoDB-compatible database by providing a connection URL.

```typescript
dbConfig: {
  mongoDbUrl: 'mongodb://host:27017',
  dbName: 'dcrouter',
}
```

## Configuration

```typescript
dbConfig: {
  enabled: true,                                    // default: true
  mongoDbUrl: undefined,                            // default: embedded LocalSmartDb
  storagePath: '~/.serve.zone/dcrouter/tsmdb',     // default (embedded mode only)
  dbName: 'dcrouter',                               // default
  cleanupIntervalHours: 1,                          // TTL cleanup interval
}
```

## Document Classes

All data is stored as smartdata document classes in `ts/db/documents/`.

| Document Class | Collection | Unique Key | Purpose |
|---|---|---|---|
| `StoredRouteDoc` | storedRoutes | `id` | Programmatic routes (created via API) |
| `RouteOverrideDoc` | routeOverrides | `routeName` | Hardcoded route enable/disable overrides |
| `ApiTokenDoc` | apiTokens | `id` | API tokens (hashed secrets, scopes, expiry) |
| `VpnServerKeysDoc` | vpnServerKeys | `configId` (singleton) | VPN server Noise + WireGuard keypairs |
| `VpnClientDoc` | vpnClients | `clientId` | VPN client registrations |
| `AcmeCertDoc` | acmeCerts | `domainName` | ACME certificates and keys |
| `ProxyCertDoc` | proxyCerts | `domain` | SmartProxy TLS certificates |
| `CertBackoffDoc` | certBackoff | `domain` | Per-domain cert provision backoff state |
| `RemoteIngressEdgeDoc` | remoteIngressEdges | `id` | Edge node registrations |
| `VlanMappingsDoc` | vlanMappings | `configId` (singleton) | MAC-to-VLAN mapping table |
| `AccountingSessionDoc` | accountingSessions | `sessionId` | RADIUS accounting sessions |
| `CachedEmail` | cachedEmails | `id` | Email metadata (TTL: 30 days) |
| `CachedIPReputation` | cachedIPReputation | `ipAddress` | IP reputation results (TTL: 24 hours) |

## Architecture

```
DcRouterDb (singleton)
  ├── LocalSmartDb (embedded, Rust) ─── or ─── External MongoDB
  └── SmartdataDb (ORM)
        └── @Collection(() => getDb())
              ├── StoredRouteDoc
              ├── RouteOverrideDoc
              ├── ApiTokenDoc
              ├── VpnServerKeysDoc / VpnClientDoc
              ├── AcmeCertDoc / ProxyCertDoc / CertBackoffDoc
              ├── RemoteIngressEdgeDoc
              ├── VlanMappingsDoc / AccountingSessionDoc
              ├── CachedEmail (TTL)
              └── CachedIPReputation (TTL)
```

### TTL Cleanup

`CacheCleaner` runs on a configurable interval (default: 1 hour) and removes expired documents where `expiresAt < now()`.

## Disabling

For tests or lightweight deployments without persistence:

```typescript
dbConfig: { enabled: false }
```
