# Folder Structure

How the contexts.live file system is organised.

---

## Top-level layout

```
contexts.live/                  ← nginx root
    cx/                         ← shared platform files
    org/                        ← one directory per organisation
    services/                   ← Node.js services (outside web root)
    monitor/                    ← log viewers and statistics pages
```

`services/` sits one level above the nginx root (`Sites/services/`) — intentionally not web-accessible.

---

## cx/ — shared platform files

```
cx/
    lib/            JS modules
    css/            CSS files
    fonts/          Font files
    img/            Shared images (icons etc.)
    docs/           Documentation
    user/           Shared audience-facing display pages
    client/         Shared operator/control pages (auth-protected)
    tools/          Operator utilities (auth-protected)
        editor/     Subtitle Editor (index.html, editor.js, editor.css)
    .cx-config.json Site root path — read by cx-org-create.sh
```

### cx/user/

Audience-facing display pages. Open access — no authentication required. Pages here are shared across all orgs via symlinks.

Examples: `cx-display-simple.html`, `cx-display-full.html`, `cx-display-score-split.html`

### cx/client/

Operator-facing control and monitor pages. Requires client or admin login. Pages here are shared across all orgs via symlinks.

Also contains: `cx-qr-sheet.html`

Examples: `cx-control-list.html`, `cx-control-auto.html`, `cx-monitor-operator.html`

### cx/tools/

Admin-only utilities. Requires admin login.

Contains: editor, cx-merge.html, cx-pack-migrate.html, cx-login.html, cx-user-admin.html, cx-export.js, cx-org-create.sh

---

## org/{slug}/ — per-org structure

```
org/{slug}/
    config.json         Org configuration
    packs/              Pack JSON files
        show2.json
        show2.-1.json   Previous version
        show2.-2.json   Two versions ago
    media/              Media files
        {packId}/
            ad.audio.en/    0001.mp3, 0002.mp3 ...
            score.image/    page-001.svg ...
    local/              Per-org custom pages (optional, open access)
    css → cx/css        Symlink
    user/ → cx/user/    Symlink — audience pages
    client/ → cx/client/ Symlink — operator pages
    tools/ → cx/tools/  Symlink — utilities
    index.html → cx/tools/cx-org-index.html  Symlink — org dashboard
```

### Symlinks

All `user/`, `client/`, `tools/`, and `index.html` are symlinks pointing into the shared `cx/` directory. This means every org automatically gets the same set of shared pages, without duplication. Per-org CSS overrides live in `css/` (loaded automatically by `cx-connect.js`).

### local/

Per-org custom pages — HTML files specific to this org that aren't in the shared `cx/user/` or `cx/client/` folders. Open access. Scanned by the org dashboard alongside `user/` and `client/`.

Also used for per-org glossary dictionary files (`cx-dict-{name}.js`) — these are IP-sensitive and loaded by `cx-render.js` when a display element uses `terms={name}`. Dictionary files are not shared across orgs.

Create `local/` manually if needed — the org create script does not create it.

### Versioned packs

cx-server keeps up to 10 versions of each pack:

```
show2.json       ← current
show2.-1.json    ← previous save
show2.-2.json    ← two saves ago
```

Versioned files are excluded from pack listings.

### config.json

```json
{
    "server": "contexts.live",
    "port": "8008",
    "slug": "new",
    "orgName": "New World Opera",
    "orgURL": "https://example.com",
    "logo": ""
}
```

To restrict audience display pages to URL-token access, add:

```json
{
    "access": "token",
    "token": "your-token-here"
}
```

See `cx-auth.md` section 12 for full details.

Read by `cx-connect.js` on every page load. `server` and `port` determine the socket connection target. `orgName`, `orgURL`, and `logo` appear in the org dashboard header.

---

## services/

```
services/
    cx-server/
        cx-server.js    Socket + HTTP API server
        .env            CX_PORT, CX_BASE, CERTS_PATH, LOG_LEVEL
        cx-server.log
    cx-auth/
        cx-auth.js         Auth oracle + user management
        cx-auth-users.json User accounts
        .env               AUTH_SECRET, AUTH_PORT, AUTH_HOST, CERTS_PATH, SITE_ROOT, LOG_LEVEL
        cx-auth.log
```

Both services are managed by PM2. Neither is web-accessible — they run on ports 8008 and 8010 respectively, accessed by nginx via `proxy_pass`.

---

## Access summary

| Path | Access |
|---|---|
| `cx/lib/`, `cx/css/`, `cx/fonts/`, `cx/img/` | Public |
| `cx/user/` (via org symlink) | Public |
| `cx/client/` (via org symlink) | Client or admin |
| `cx/tools/` | Admin |
| `cx/cx-admin-dashboard.html` | Admin |
| `org/{slug}/config.json` | Public |
| `org/{slug}/packs/` | Public |
| `org/{slug}/media/` | Public |
| `org/{slug}/local/` | Public |
| `org/{slug}/user/` | Public by default; token-protected if `config.json` sets `access: token` (symlink → cx/user/) |
| `org/{slug}/client/` | Client or admin (symlink → cx/client/) |
| `org/{slug}/tools/` | Admin (symlink → cx/tools/) |

---

## Creating a new org

```bash
bash cx/tools/cx-org-create.sh <slug>
```

See `tool-org-create.md` for full details.
