Ampelos dashboard: the web face, and the owner of the schema
Split out of the single Ampelos repository. Next.js app, Drizzle schema and migrations, brand art, planning notes. What left: scripts/, which was the agent's job library misfiled under web/ and imported nothing from src/; and deploy/truenas, whose broadcast posts to the scan listener on :3427 -- an agent script -- so it belongs beside the thing it talks to. This repository keeps the schema. The agent speaks raw SQL against the same tables and holds no copy of it, so a rename here can break it silently where it used to be one commit. The README says so, and the agent carries a snapshot to check against. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# ampelos-dashboard
|
||||
|
||||
The web face of Ampelos: inventory, calendar, requests, the link-verification
|
||||
panel, and the admin surfaces that drive the rest of the system. Next.js 16 App
|
||||
Router, Postgres via Drizzle, Authentik for sign-in.
|
||||
|
||||
It is also the **owner of the database schema**. See "Contracts" below, because
|
||||
that ownership is now split across two repositories.
|
||||
|
||||
## Running it
|
||||
|
||||
```bash
|
||||
npm install
|
||||
cp .env.example .env.local # then fill it in
|
||||
npm run db:migrate
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Production is a systemd unit (`ampelos.service`) running `next start` on :3000
|
||||
behind the reverse proxy for ampelos.sticknife.com.
|
||||
|
||||
Rebuilding in place is a single step, because `next build` replaces the build
|
||||
that `next start` is currently serving — do them together or the site is broken
|
||||
in between:
|
||||
|
||||
```bash
|
||||
npm run build && sudo systemctl restart ampelos.service
|
||||
```
|
||||
|
||||
## Contracts with ampelos-agent
|
||||
|
||||
The other half of the system is [ampelos-agent][agent]: acquisition, the
|
||||
filesystem maintenance jobs, and the satellites reporting in from other hosts.
|
||||
It does not import anything from this repository, and this repository does not
|
||||
import anything from it. They meet in exactly two places, and both are easy to
|
||||
break by accident now that they are versioned separately.
|
||||
|
||||
### 1. The database schema — owned here
|
||||
|
||||
`src/db/schema/` and `src/db/migrations/` are the definition. The agent speaks
|
||||
raw SQL against the same tables and holds no copy of the schema.
|
||||
|
||||
So a migration here can break the agent silently. The agent carries
|
||||
`scripts/check-schema.mjs`, a snapshot of the 24 tables and the load-bearing
|
||||
columns it reads; run it there after any migration that renames or removes
|
||||
something:
|
||||
|
||||
```bash
|
||||
cd ../ampelos-agent && npm run check:schema
|
||||
```
|
||||
|
||||
Adding tables and columns is always safe. Renaming and dropping are not.
|
||||
|
||||
### 2. Five HTTP endpoints
|
||||
|
||||
Three the agent calls here, and they are how the satellites report in:
|
||||
|
||||
| Endpoint | Caller | Breaks if this app is down |
|
||||
| --- | --- | --- |
|
||||
| `POST /api/agents/heartbeat` | `ampelos-herald.sh` on each host | Heartbeats stop, so the maintenance container never mounts edda, so backup and archive jobs skip themselves |
|
||||
| `POST /api/agents/status` | `ampelos-mountd.sh` | Mount state stops being reported |
|
||||
| `POST /api/agents/corrupt-files` | `ampelos-transcoder.mjs` | Unreadable files are logged locally instead |
|
||||
|
||||
Two this app calls there, via `AMPELOS_INDEXER_URL` (see `src/lib/indexer.ts`):
|
||||
|
||||
| Call | Used by | Breaks if the indexer is down |
|
||||
| --- | --- | --- |
|
||||
| search releases | `admin/search-actions.ts` | The manual search panel returns an error |
|
||||
| grab release | `admin/search-actions.ts` | Manual grabs fail; the automatic loop is unaffected |
|
||||
|
||||
Both directions authenticate with `AMPELOS_AGENT_TOKEN`, which must be the same
|
||||
value in both repositories' environments and belongs in neither's git history.
|
||||
|
||||
### What still works when the other half is stopped
|
||||
|
||||
Everything here reads from Postgres, so with the agent stopped the dashboard
|
||||
renders normally — inventory, calendar, verification — it simply goes stale, and
|
||||
manual search and grab fail. With the dashboard stopped, the agent keeps
|
||||
downloading, importing, scanning and reaping; only the edda-mounted tiers pause,
|
||||
for the heartbeat reason above.
|
||||
|
||||
## Layout
|
||||
|
||||
- `src/app/(admin)/` — the admin surfaces. Server Actions are reachable by
|
||||
direct POST, so every one of them checks the session itself.
|
||||
- `src/db/` — schema, migrations, client.
|
||||
- `media/` — source brand art. `public/` holds what the app actually serves.
|
||||
|
||||
The TrueNAS health-broadcast timer used to live here under `deploy/`. It posts
|
||||
to the scan listener on :3427, which is an agent script, so it moved to
|
||||
`ampelos-agent/deploy/truenas/` with the thing it talks to.
|
||||
|
||||
## Working on it
|
||||
|
||||
Read `AGENTS.md` first. Next.js 16 differs from what a model is likely to
|
||||
remember, and the local documentation in `node_modules/next/dist/docs/` is the
|
||||
authority.
|
||||
|
||||
[agent]: ../ampelos-agent
|
||||
Reference in New Issue
Block a user