# Onebox Project Hints

## SSL Certificate Storage (NodeNext/SmartDB)

SSL certificates are stored directly in SmartDB as PEM content instead of file paths:

- `ISslCertificate` and `ICertificate` interfaces use `certPem`, `keyPem`, `fullchainPem` properties
- No filesystem storage for certificates - everything in DB
- `reverseproxy.ts` reads certificate PEM content from database
- `certmanager.ts` stores SmartACME certificates directly to database

## Architecture Notes

### Database Layer

The database layer is SmartDB/SmartData-backed. `OneboxDatabase` owns document classes and current startup migrations.

**Directory Structure:**

```
ts/database/
├── index.ts              # Main OneboxDatabase class
├── docs.ts               # SmartData document classes
└── secret-settings.ts    # Secret settings manager
```

**Import paths:**

- Main: `import { OneboxDatabase } from './database/index.js'`

**API Compatibility:**

- The `OneboxDatabase` class maintains the same public API
- Backend code works with SmartData document instances directly

## Current Migrations

- `valkey-platform-rename` renames legacy Redis platform data and records completion in metadata
- `coretraffic-platform-rename` renames persisted proxy platform data and records completion in metadata
- `corestore-platform-metadata` renames only the legacy storage-class setting through SmartData

Infrastructure migrations and persisted-data migrations live only in `ts_migration/`. The explicit `corestore-platform` migration requires a verified external volume checkpoint, persists replay-safe phases, retains recovery containers, and consolidates object storage plus SmartDB's MongoDB-wire endpoint under one pinned Corestore service. Normal startup does not run the infrastructure cutover.

### Cloudly legacy deployment settlement (schema 5)

- `ts_migration/cloudly-secrets-v2-settlement.ts` holds the pure helpers (authority metadata, handoffs, stdio requests, in-process MAC verification through `@serve.zone/interfaces/runtime`); `cloudly-secrets-v2-cutover.ts` orchestrates `runScratchSettlement` (inside `runRehearsal`, after `cloudlyPrepare`, before inspection) and `runProductionSettlement` (inside `execute`, before the apply attempt).
- The settlement image is pinned by index digest in `ts/cloudly-secrets-v2.ts` (`cloudlySecretsV2SettlementImage*`), independent of the schema-5 cutover target (24.1.0). Container transport is the private-file form of `secrets-v2 settlement-stdio`; request and response files are removed after every run.
- Artifacts and handoffs persist as encrypted service secrets under `SERVEZONE_SECRET_CUTOVER_SETTLEMENT_*`; checkpoints record only digests, byte counts, attempt ids and dispositions. Handoffs are removed once the production receipt is persisted.
- Authority lifetime is 12 hours (`cloudlySettlementAuthorityLifetimeMs`; the interfaces contract caps it at 24 hours): `execute` must run within 12 hours of `rehearse`; an expired source authority before production apply fails closed.
- Tests emulate Cloudly with `test/helpers/cloudly-settlement-responder.ts`, which produces HMAC-authentic artifacts from the interfaces encoders, so Onebox's verification path runs for real.

## Reverse Proxy (CoreTraffic Docker Service)

The reverse proxy uses **CoreTraffic** running as a Docker Swarm service for production-grade reverse proxying with TLS termination and WebSocket handling.

**Architecture:**

- CoreTraffic runs as Docker Swarm service (`onebox-coretraffic`) on the overlay network
- No host binary download required - uses `code.foss.global/serve.zone/coretraffic:latest`
- Routes are pushed dynamically via the CoreTraffic admin API (host port 2019)
- Automatic HTTPS disabled - certificates managed externally via SmartACME
- Zero-downtime configuration updates
- Services reached by Docker service name (e.g., `onebox-hello-world:80`)

**Key files:**

- `ts/classes/coretraffic.ts` - CoreTrafficManager class for Docker service and Admin API
- `ts/classes/reverseproxy.ts` - Delegates to CoreTrafficManager

**Certificate workflow:**

1. `CertRequirementManager` creates requirements for domains
2. Daemon processes requirements via `certmanager.ts`
3. Certificates stored in database (PEM content)
4. `reverseProxy.addCertificate()` passes PEM content to CoreTraffic route config
5. CoreTraffic serves TLS with the loaded certificates (no volume mounts needed)

**Docker Service Configuration:**

- Service name: `onebox-coretraffic`
- Image: `code.foss.global/serve.zone/coretraffic:latest`
- Network: `onebox-network` (overlay, attachable)
- Startup: CoreTraffic admin API listens on container port 3000, published on host port 2019

**Port Mapping:**

- Dev mode: HTTP on 8080, HTTPS on 8443, Admin on 2019
- Production: HTTP on 80, HTTPS on 443, Admin on 2019
- All ports use `PublishMode: 'host'` for direct binding

**Log Receiver:**

- `ProxyLogReceiver` remains the host-side access-log stream endpoint for proxy log integrations

**Ops-server log streaming (TypedRequest 8):**

- TypedRequest 8 removes the public `VirtualStream` constructor. Server-created streams must come from `typedsocket.createVirtualStream({ target, creatorDirection: 'send', contentType, authorization })`, with the target resolved through `typedsocket.getServerConnectionForRequest(toolsArg)`.
- That facade requires a `virtualStreamAuthorizationAdapter`, configured on the `UtilityWebsiteServer` in `ts/opsserver/classes.opsserver.ts`. It binds the verified admin identity and re-checks it on every open, chunk, accept and reject, rejecting anything that is not the exact server peer.
- Stream directions in the request interfaces are always **requester-local**. `TypedHandler` reverses them, so the log responses declare `TVirtualStream<'receive'>` and the handler side creates a sender.
- `send()` resolves only after the receiver dequeues, unlike the removed synchronous `sendData()`. `OutboundChunkWriter` in `ts/opsserver/handlers/logs.handler.ts` chains writes to preserve order, pauses the Docker log stream above its high-water mark, and on the first failure destroys the source, aborts the virtual stream and reports once.
