fix(iios): thread subject on create, graceful open_thread error, isolated test DB

- openThread/createThread accept a generic `subject` (group name) — stored on the
  thread, echoed via listThreads; kernel never interprets it.
- Gateway open_thread now returns an ACK'd { error } on failure instead of throwing
  (which never acked → clients hung on "loading"). Non-member/missing-thread opens
  fail cleanly.
- Tests run against an isolated `iios_test` database (vitest globalSetup creates +
  migrates it; test.env overrides DATABASE_URL) so `pnpm test` can never TRUNCATE the
  dev database again. Verified: full suite green, dev DB row counts unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-06 19:39:19 +05:30
parent 1af10d0f4a
commit c4206f9809
5 changed files with 47 additions and 13 deletions
@@ -28,11 +28,11 @@ export class ThreadsController {
return this.messages.listThreads(this.principal(auth));
}
/** Create a thread; `membership`/`creatorRole` are opaque, app-supplied thread attributes the kernel stores but never interprets. */
/** Create a thread; `membership`/`creatorRole`/`subject` are opaque, app-supplied attributes the kernel stores but never interprets. */
@Post()
@HttpCode(201)
async createThread(@Body() body: { membership?: string; creatorRole?: string }, @Headers('authorization') auth?: string) {
return this.messages.openThread(null, this.principal(auth), { membership: body?.membership, creatorRole: body?.creatorRole });
async createThread(@Body() body: { membership?: string; creatorRole?: string; subject?: string }, @Headers('authorization') auth?: string) {
return this.messages.openThread(null, this.principal(auth), { membership: body?.membership, creatorRole: body?.creatorRole, subject: body?.subject });
}
/** Governed membership: add a user (by userId) to a thread — policy enforces DM cap / roles. */