Files
t5de-hub/README.md
T
dhkatzandClaude Opus 5.5 51d5bb5ff3 Website: products, library, catalogs and their console page
/products (search), product pages with revisions, getting and staying on a
revision, retracting; /products/:id/edit; /create and new revisions upload
from the browser straight to the catalog with a token from the hub;
/library; /catalogs (directory, registering with a once-shown key);
/console/catalogs to approve or reject. Every page now sends a nonce-based
CSP (proxy.ts), so product descriptions can't run scripts.

buttonVariants now merges classes, so outline links get their border.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 19:06:08 -07:00

53 lines
3.0 KiB
Markdown

# t5de-hub
T5DE's hub: accounts linked to IMVU accounts, presence, and (to come) the registry of community products and
catalogs, T5DE-hosted rooms, and the moderation console. Part of T5DE (git.t5de.dev/t5de). Design:
[docs/design.md](docs/design.md); the API: [docs/api.md](docs/api.md); what a room needs from a server:
[docs/imq-rooms.md](docs/imq-rooms.md).
## What works
- **Accounts** (Better Auth): sign-up with email, username and password; sign-in by username. The first account is
an admin; roles user, moderator, admin.
- **Linking IMVU accounts**: the person puts a code in the account's tagline; the hub reads it from IMVU's public
API. The most recent proof wins (an account linked elsewhere moves, with a new pairwise ID). Link caps per person
(default 10).
- **Age**: an IMVU account counts as adult if IMVU says it's age verified or has Access Pass, checked by the hub.
- **Proxy sign-in**: OAuth 2.0 device authorization (`t5de-proxy signin` shows a code to enter at `/device`); the
proxy then uses its session as a bearer token. JWTs with published keys (`/.well-known/jwks.json`) for catalogs.
- **Presence**: signed-in proxies keep a WebSocket (`/api/v1/realtime`) telling the hub which IMVU account is in
use and the community products it wears. `/online` shows those who opted in, live, with the opt-in T5DE badge.
- **Products** (website): browsing and search, product pages, uploads straight from the browser to a catalog,
editing, revisions (retract, stay on one), the library, and registering catalogs (`docs/products.md`). Pages send
a strict Content Security Policy (`apps/web/proxy.ts`).
- **Console** (moderators): counts, who's online (live), people, link caps, bans, roles, the audit log.
## Layout
A Bun monorepo (workspaces, Turborepo):
| | |
| --- | --- |
| `apps/api` | The API: Elysia on Bun, Better Auth, the realtime WebSocket. Port 4101. |
| `apps/web` | The website: Next.js 16 (React server components), Tailwind CSS 4, shadcn/ui. Port 4100. Calls the API through its own `/api` (rewrites), typed end to end with Eden. |
| `packages/db` | Drizzle schema and migrations; Postgres in production, PGlite (in-process Postgres) for development and tests. |
## Development
Needs Bun (1.4) and Node (for Next.js).
bun install
bun run dev # the API on :4101 (database in apps/api/data) and the website on :4100
`bun run test` tests the API against PGlite; `bun run check-types`, `bun run build`.
## Running it
- **Self-hosted**: `AUTH_SECRET=$(openssl rand -base64 32) docker compose up -d` runs Postgres, the API and the
website (see `docker-compose.yml` for the public addresses).
- **Elsewhere**: the website deploys as is to Vercel and similar (`apps/web`, env `API_URL`); the API to any host
that runs Bun or containers (Railway, Render, Fly.io, Heroku), with `DATABASE_URL`, `AUTH_SECRET`, `API_URL` (its
public address) and `WEB_URL` (the website's).
T5DE's proxies reach the API's address directly (sign-in and the WebSocket): `t5de-proxy signin -hub <API address>`.