New uploads are drafts: only their creator and moderators see them, nobody can get or wear them, and they're deleted if not published within 30 days (their catalogs get delete changes). The creator reviews the info and publishes it. Editing a product's info is a permission check now (product:edit): moderators can edit anyone's with a reason the creator sees, lock fields (product:lock; locked fields need product:edit-locked) and lower ratings (product:rate-lower, not below its files'). Every change is kept in the product's info history, with who and why, and can be undone by the same rules. Products can be unlisted (out of search and lists, the link still works) and tagged; lists filter by tag and catalog. The console has a Products section (everyone's for moderators, by status) and a drafts to-do. A product's own category is left for later: the hub has no list of IMVU's categories to pick from. Co-Authored-By: Claude Opus 5.5 <[email protected]>
T5DE Hub website
The hub's website: accounts, linked IMVU accounts, who's online, signing T5DE in, and the moderation console.
Next.js (App Router), Tailwind CSS and shadcn/ui. Pages are rendered on the server, which calls the hub's API
(apps/api) with the visitor's cookie; forms use server actions. The browser only talks to this app: /api/* is
rewritten to the API, so the API's session cookies belong to the website's origin.
Develop
From the repository root, bun install, then start the API (cd apps/api && bun src/index.ts) and the website:
cd apps/web
bun run dev # http://localhost:4100
bun run check-types
bun run build
The first account created is the hub's admin.
Configuration
| Variable | Default | What |
|---|---|---|
API_URL |
http://localhost:4101 |
The API's address as this app reaches it. Needed at build time and at run time (below). |
PORT |
4100 |
The standalone server's port (next start and bun run dev use 4100). |
The API's WEB_URL must be this website's public address (it's where Better Auth trusts requests from, and where
T5DE's sign-in code page is).
API_URL is read in two places: by server code on every request, and by next.config.ts's /api rewrite, which
Next fixes when it builds. So build with the same API_URL the app will run with.
Deploy
Container
The Dockerfile builds a standalone server (output: "standalone"). Build it from the repository root:
docker build -f apps/web/Dockerfile --build-arg API_URL=http://api:4101 -t t5de-hub-web .
docker run -p 4100:4100 -e API_URL=http://api:4101 t5de-hub-web
Next's own gzip is off (it held back the API's live event stream), so put a reverse proxy that compresses in front,
and don't let it buffer text/event-stream responses (/api/v1/online/events).
Vercel
Import the repository with the project's root directory set to apps/web (Vercel installs the Bun workspace from the
root). Set API_URL to the API's public address for both builds and runtime. Nothing else is needed: there's no
custom server.