diff --git a/README.md b/README.md index 05c704e..07bd7e1 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,65 @@ # Fabric.Backend.Guild -Guild Node service for Fabric. +A **guild node** for Fabric (NestJS, ES modules, MySQL/TypeORM, +socket.io). Default port `7002`, global prefix `/api`. Many independent +guild nodes can run; each registers with `Fabric.Backend.Center` and +introspects the user/guild tokens Center issues. -## Scope (MVP) -- Workspace/Guild/Channel/DM -- Message create/edit/delete/reply/@mention -- Per-channel/DM seq ordering + gap backfill API -- Webhook/Bot integration surface -- Guild-level audit logs +## Responsibilities -## Next -- API skeleton (NestJS) -- Chat domain models -- Seq allocator and range query endpoints +- **Guilds / channels / messaging** — per-channel `seq` ordering, edit + window, soft delete, reply, `<@id>` mentions (backtick-aware) plus + `<@user.name:NAME>` → `<@userId>` translation via Center. +- **Channel `x_type`** (required on create): `general`, `work`, `report`, + `discuss`, `triage`, `custom`. Plus `isPublic` and `closed` (closed → + history readable, posting returns `409`). +- **`wake_mapping`** — explicit wake list for `triage` (on-duty) and + `custom` (listeners) channels. +- **Per-recipient `wakeup`** — `message.created` is emitted per socket with + its own `wakeup` flag (author=false; general→all; report→none; + triage/custom→wake_mapping; discuss/work→the current speaker only). This + is **push-only metadata for the OpenClaw plugin**; UIs ignore it. +- **discuss/work turn engine** (`channel_turn_state`): speaking order and a + disjoint **bypass list** (bypass members aren't woken unless @-mentioned); + activation from idle, queue-jump, cross-round `/no-reply` pause, + `/force-proceed`, end-of-round shuffle, guild `/ack`, and a mention + sub-frame stack with a 5-level nesting cap (root + 4). `moveToBypass` + mid-rotation. +- **Files** — `POST /files` (multipart, configurable max size, default + 100 MB), `GET /files/:id` (Bearer **or** `?access_token=` for browser + `/`), automatic retention sweep (default 7 days). Messages carry + `attachments[]`. +- **Channel canvas** — one pinned document per channel (`md`/`html`/`text`), + re-share replaces, only the original sharer may update/remove; emits + `canvas.updated` / `canvas.removed`. +- **Realtime** — socket.io `/realtime`; `join_channel`/`leave_channel`, + `message.created/updated/deleted`, `canvas.*`, presence, typing. + +## Required env (hard-checked at startup) -## Required env (startup hard checks) - `FABRIC_BACKEND_GUILD_CENTER_BASE_URL` - `FABRIC_BACKEND_GUILD_CENTER_API_KEY` - `FABRIC_BACKEND_GUILD_NODE_ID` -If any of the above is missing, service startup fails immediately. +Missing any of these aborts startup. + +## Other env + +- `FABRIC_BACKEND_GUILD_PORT` (default 7002) +- `FABRIC_BACKEND_GUILD_DB_*`, `FABRIC_BACKEND_GUILD_DB_SYNC` +- `FABRIC_BACKEND_GUILD_FILE_DIR` (storage root), + `FABRIC_BACKEND_GUILD_FILE_MAX_BYTES` (default 100 MB), + `FABRIC_BACKEND_GUILD_FILE_TTL_DAYS` (default 7) +- `FABRIC_BACKEND_GUILD_CORS_ORIGINS` (empty = allow all; `null` origin — + `file://` desktop — is always allowed) + +## Run + +```bash +npm install +npm run build && npm start # or: npm run start:dev +``` + +Usually run via the root `docker-compose.local.yml` (`backend-guild1` +`test-guild1` :7002, `backend-guild2` `test-guild2` :7003). Schema is +auto-managed (`DB_SYNC`). ES modules (`NodeNext`).