Commit Graph
33 Commits
Author SHA1 Message Date
dhkatzandClaude Opus 5.5 fe3882695d ci: release pull requests, and conventional-commit PR titles
Pull request / title (pull_request) Successful in 1s
CI / test (pull_request) Successful in 59s
CI / image (apps/api/Dockerfile, t5de-hub-api) (pull_request) Skipped
CI / image (apps/web/Dockerfile, t5de-hub-web) (pull_request) Skipped
Pull requests only, squash-merged, titled as conventional commits (checked); release-bot keeps a
chore(release) pull request open, worked out by git-cliff, and merging it tags the release.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-03 08:37:16 +00:00
dhkatzandClaude Opus 5.5 21e1bd8790 A slim Staging bar on staging
CI / test (push) Successful in 57s
CI / image (apps/web/Dockerfile, t5de-hub-web) (push) Successful in 5s
CI / image (apps/api/Dockerfile, t5de-hub-api) (push) Successful in 5s
Shown above the header when the site is served from a staging. address, or with HUB_ENVIRONMENT=staging
(production hides it), read per request since staging and production run the same image.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-02 09:09:22 -08:00
dhkatzandClaude Opus 5.5 975e11e077 CI builds and pushes the images; Komodo only deploys
CI / test (push) Successful in 54s
CI / image (apps/web/Dockerfile, t5de-hub-web) (push) Successful in 4s
CI / image (apps/api/Dockerfile, t5de-hub-api) (push) Successful in 7s
After the tests pass, main pushes :latest-main and :main-<commit>, and vX.Y.Z tags push :X.Y.Z, :X.Y and
:latest to git.t5de.dev (registry login: the t5de org secret REGISTRY_TOKEN). Komodo deploys them once the
ref's CI has passed; it no longer builds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-31 15:53:10 +00:00
dhkatzandClaude Opus 5.5 7d20426d1b CI only tests again: Komodo builds and deploys
CI / test (push) Successful in 1m10s
Komodo now watches the t5de org (Gitea webhook → its t5de-push action, defined in t5de-infra): it builds and
deploys a commit to staging once this CI passes on main, and to prod for vX.Y.Z tags. So the deploy job and
.gitea/scripts/deploy.py go, and this repo no longer needs to know how it's deployed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 15:47:58 +00:00
dhkatzandClaude Opus 5.5 e3770ceb57 Deploy with Komodo: main to staging, vX.Y.Z to prod
CI / test (push) Successful in 1m6s
CI / deploy (push) Successful in 1m15s
CI now builds the API and website images after the tests, pushes them to git.t5de.dev, and deploys them through
Komodo (.gitea/scripts/deploy.py): pushes to main as :main to hub.staging.t5de.dev, vX.Y.Z tags as :X.Y.Z to
hub.t5de.dev, with the version pinned in t5de/t5de-infra.

The API image installs with --linker hoisted: Bun's isolated layout keeps the workspace links (@t5de/db) in each
package's own node_modules, which the image didn't copy, so the API couldn't start.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 08:16:05 -07:00
dhkatzandClaude Opus 5.5 97ce2be569 Deleting products: by their creators, and removal by moderation
CI / test (push) Successful in 1m4s
A creator deletes a product: it's no longer listed and nobody new can get it, while people who have it
keep it (its page, files and library entries stay, and rooms keep showing it), as old revisions stay
available. Moderation removes one everywhere, with a reason: its page and files answer 410, and it
leaves libraries and rooms. Both are on the product's page and in the audit log.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 08:10:24 -07:00
dhkatzandClaude Opus 5.5 07bbc11565 Website header: the T5DE logo, four links, and a profile menu
CI / test (push) Successful in 1m11s
The header shows T5DE's logo (the client's, also the tab icon) and Online, Rooms, Products and
Catalogs; the person's pages (Account, Library, Console for moderators) and signing out are in a menu
under their picture: their first linked IMVU account's avatar picture, which /me now gives (kept an
hour), or their initial. Creating a product moves to Products (New product, /products/new; /create
redirects there), as creating a room is on Rooms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 07:18:26 -07:00
dhkatzandClaude Opus 5.5 76c8e0342e Hosted rooms phase 2: moderators, bans, privacy, invites, images, favorites, ratings, recent rooms, occupancy watch
CI / test (push) Successful in 1m10s
Moderators (up to 20 IMVU accounts, set by ID or name) and the owner account boot
and ban over realtime (room.boot); bans are listed and lifted over REST. Private
rooms are unlisted and joined by the owner, moderators and holders of an accepted
invite (room.invite / room.invited / room.invite_reply / room.invite_answer).
Room images (PNG/JPEG by magic bytes, up to 512 KB) are stored in the database
and served with cache headers. Per-person favorites, ratings and recent rooms.
room.watch pushes room.occupancy; participants carry their IMVU name, and
GET .../participants lists them. Contract in docs/hosted-rooms.md, "Phase 2".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 06:07:41 -07:00
dhkatzandClaude Opus 5.5 43183ec7ee Hosted rooms' instance IDs name their owner: <owner>-<2100000000+n>
CI / test (push) Successful in 58s
The client takes a room's owner from the instance ID's first part; with 2100000000 there, the owner
couldn't decorate their hosted room (putting furniture on went to their home room instead).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 05:18:19 -07:00
dhkatzandClaude Opus 5.5 f65f36c1ea Decorations over IMVU rooms: the hub's side
CI / test (push) Successful in 1m13s
T5 products placed in ordinary IMVU rooms, kept per room instance
(room_decoration, migration 0006). GET /api/v1/decorations/:instance (and
?instances= for up to 20) gives what the viewer may see, with a hash;
PUT is for the room owner's T5DE person only, checks the products exist,
and tells every realtime session with a chat in that room ({"type":
"decor"}). Hosted rooms' IDs are refused.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:58:42 -07:00
dhkatzandClaude Opus 5.5 2a1fc94df6 Hosted rooms: the hub's side
CI / test (push) Successful in 1m5s
Rooms made on the website (hosted_room, migration 0005), the REST routes in
docs/hosted-rooms.md, and the realtime room.* protocol: joining with the
capacity, adult and linked-account rules, seats, numbered messages with
forged senders dropped and a rate limit, closing. The Rooms page lists them,
with a form to make one and the owner's edit and close.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:21:21 -07:00
dhkatzandClaude Opus 5.5 0c67232425 Badges: the proxy asks which IMVU accounts show the T5 badge
CI / test (push) Successful in 49s
POST /api/v1/badges {imvuIds} (at most 200) answers the linked accounts whose
badge is on, of people who aren't banned, in one query. It uses the existing
per-account showBadge (off by default, set from the account page).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:38:01 -07:00
dhkatzandClaude Opus 5.5 6668b55117 Products: carry the IMVU parent's image and categories
CI / test (push) Successful in 49s
Revisions with an IMVU parent store its public info (image, category path, gender)
from IMVU's product API, looked up after registering and in a periodic pass.
Product views gain parent, image and categories; GET /products takes category and
limit. The website shows the image on cards and product pages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 01:03:02 -07:00
dhkatzandClaude Opus 5.5 d57674d90c Products: images need https addresses; lowering a rating waits for review; library shows creators
CI / test (push) Successful in 50s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 19:14:12 -07:00
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
dhkatzandClaude Opus 5.5 b4f6fce9df Product registry: catalogs, revisions, product info and libraries
CI / test (push) Successful in 43s
The hub registers catalogs (hidden until a moderator approves them), hands out upload tokens, and records the
revisions catalogs register after validating uploads: numbered, never changed, signed by the hub (its own
Ed25519 key, published at /.well-known/t5de-keys.json). Creators edit product info (descriptions cleaned by an
allowlist) and can retract revisions. People get products into their library, optionally staying on a
revision; the proxy asks which revision to load and where. Contract in docs/products.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:53:52 -07:00
dhkatzandClaude Opus 5.5 7fea63fc4f Design: everywhere the T5 badge appears
CI / test (push) Successful in 37s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:41:43 -07:00
dhkatzandClaude Opus 5.5 143aeb3d84 Design: T5 products in the client's shop and inventory
CI / test (push) Successful in 40s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:38:23 -07:00
dhkatzandClaude Opus 5.5 6ba4d83317 Room channel and rooms list
CI / test (push) Successful in 6m38s
The realtime connection now carries the IMVU chats a client is in: the hub tells each proxy in a chat which
other T5DE users are there and what community products they wear (adult products only to adult accounts), on
joining and on every change. Rooms T5DE users enter are looked up on IMVU; those that are public, listed and
whose owner turned on "List my public rooms" appear on the new Rooms page, with the T5DE users in them who
show they're online. AP rooms are shown to adults only.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:14:43 -07:00
dhkatzandClaude Opus 5.5 7db9fc0370 Vendor-neutral age verification, with IMVU as the first provider
CI / test (push) Successful in 35s
Age checks are recorded in one table (age_check) by provider, method and result, never with documents or
birth dates; one rule decides whether an IMVU account counts as adult (its person's check, or its own).
Providers implement a small interface (start, webhook or browser completion, re-check) and are chosen by
configuration, so phone wallets and Didit can be added, or swapped, as adapters. IMVU's answer per account
is re-checked when it expires (about daily). Existing links' results move into the new table.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 05:44:36 -07:00
dhkatzandClaude Opus 5.5 339ba8e2d6 Presence: count an account as soon as it's linked; accept an empty outfit
CI / test (push) Successful in 36s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 05:07:28 -07:00
dhkatzandClaude Opus 5.5 7a06ba49c3 Rebuild the hub on Bun: Elysia API, Better Auth, Drizzle, Next.js website
CI / test (push) Successful in 30s
The hub becomes a Bun monorepo: apps/api (Elysia, Better Auth for accounts, roles, bans, proxy device
sign-in and JWT keys; tagline linking, presence and the console as before), packages/db (Drizzle; Postgres in
production, PGlite in development and tests), and the Next.js website from apps/web. Self-hostable with
docker compose; the website deploys to Vercel-style hosts, the API to any that runs Bun or containers. The
first version, in Go, is removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 05:03:54 -07:00
dhkatzandClaude Opus 5.5 64c552330b Website: Next.js app for accounts, linking, who's online, device sign-in and the console
apps/web: Next.js 16 (App Router), Tailwind 4 and shadcn/ui, light and dark from the system. Pages render on the
server and call the API with Eden Treaty (typed by @t5de/api), forwarding the visitor's cookie; forms use server
actions; sign-up, sign-in and sign-out use Better Auth's React client. /api is rewritten to the API so its cookies
are first-party. Who's online follows the API's event stream (Next's gzip is off: it held the stream back).
Standalone output with a Dockerfile; deploys to Vercel as is.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 05:02:00 -07:00
dhkatzandClaude Opus 5.5 7afada1c63 CI: test against a Postgres service (embedded Postgres won't run as root)
CI / test (push) Successful in 1m5s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 03:48:32 -07:00
dhkatzandClaude Opus 5.5 b9dc3f0ec1 Hub: accounts, IMVU linking by tagline, proxy sign-in, presence, console
CI / test (push) Failing after 42s
People sign up on the website and link IMVU accounts by putting a code in the account's tagline, which the
hub reads from IMVU's public API (the most recent proof wins; link caps per person). IMVU's age verification
or Access Pass make an account adult. T5DE's proxy signs in with a device code and keeps a WebSocket open,
reporting the IMVU account in use and the community products it wears; /online shows those who opted in.
Moderators get a console: who's online, people, link caps, bans, roles, and the audit log. Tests run the
website and API against an embedded Postgres and a fake IMVU API.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 03:45:52 -07:00
dhkatzandClaude Opus 5.5 54e569bea3 Latest revision by default; pins are opt-in per product, for what one wears
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:34:47 -07:00
dhkatzandClaude Opus 5.5 5db4939799 Product revisions with a public history
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:33:16 -07:00
dhkatzandClaude Opus 5.5 e923577c5a Editable product info, with HTML descriptions made safe
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:31:45 -07:00
dhkatzandClaude Opus 5.5 a229f8c5d0 Room list, occupancy, scenes and other sessions
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:20:20 -07:00
dhkatzandClaude Opus 5.5 0a4268bb62 Anyone can see catalogs' products; wearing needs membership
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:15:17 -07:00
dhkatzandClaude Opus 5.5 355002ec79 What a room needs from the server, for hosted rooms
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:10:42 -07:00
dhkatzandClaude Opus 5.5 4e0fca0825 Decide age, catalog access, takedown contacts, chat retention and server rendering
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:06:59 -07:00
dhkatzandClaude Opus 5.5 4564aa53cc Design draft for the hub, catalogs and community products
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 02:01:08 -07:00