diff --git a/.planning/phases/20-demo-instance-with-every-shared-plugin/20-CONTEXT.md b/.planning/phases/20-demo-instance-with-every-shared-plugin/20-CONTEXT.md new file mode 100644 index 00000000..0a079cbb --- /dev/null +++ b/.planning/phases/20-demo-instance-with-every-shared-plugin/20-CONTEXT.md @@ -0,0 +1,140 @@ +# Phase 20: Demo instance with every shared plugin - Context + +**Gathered:** 2026-10-28 +**Status:** Ready for planning + + +## Phase Boundary + +Phase 19.4.1 put `sm-demo-app` live on demo.summercms.io with the plugins of that time. This phase adds the chat family to that live instance and shows it working on the public Nuxt site: `chat`, `chatchannels`, `chatvideo`, `chatbots`, `forum`, `herald` and `userfriends` are mounted at tagged versions, seeded by `demo:seed`, deployed on rome, and given site UI through new shared Nuxt layers. Everything decided in 19.4.1 still holds (hosting on rome, own Centrifugo, `/backend` refused by nginx with the contact call to action, open registration behind Turnstile, the reset job, the demo banner, EN/PL, the summercms.io look). This phase does not repeat it. + +New shared repos created by this phase: `vue-chat-layer`, `vue-chatvideo-layer`, `vue-forum-layer`, `vue-userfriends-layer`, `sm-moderation-plugin`. + + + + +## Implementation Decisions + +### Chat frontend +- **D-01:** The chat UI is ported from `sm-bm-app`'s Vite SPA (`frontend/src/components/chat/`, `stores/chat.ts`, `api/chat.ts`, `lib/chat*.ts`, about 4.6k lines) into a new shared Nuxt layer, **`vue-chat-layer`**, consumed by `vue-demo-app` like the journal, menu, FAQ and paymentgateway layers. The layer is Golem15 code with no bm (JZ) specifics: BM link embeds, Terminarz deadline pins and other bm-only pieces are stripped or turned into slots or extension points. The layer names no application. — **Reversibility:** costly. A public layer with tagged releases; later sites pin it by tag. +- **D-02:** The full bm feature set: channels, DMs, threads, mentions, reactions, typing, unread counts, attachments, member picker, delete dialog, embeds (generic link embeds only). +- **D-03:** Chat appears as a full `/chat` page (channel sidebar, message pane) **and** a floating panel (DM list and unread badge) on every page for logged-in users. The homepage tour (19.4.1 D-11) gets a "Chat" card. +- **D-04:** Anonymous visitors on `/chat` see a description and a "register to chat" prompt, the same pattern as quizzes (19.4.1 D-18). There is no read-only preview, and the floating panel is hidden for them. +- **D-05:** Chatbots has no UI of its own. Its slash commands appear as a command picker in the `vue-chat-layer` composer. There is no `vue-chatbots-layer`. + +### Chat context and access +- **D-06:** One demo community: a single chat context (in the spirit of bm's `bm/1`, `plugins/jz/bm/classes/chat_context.go`, e.g. `demo/1`) implemented in `golem15.demo` as the host `contracts.Context` and the chatchannels `ChannelAccessResolver`. Every registered user is a member automatically. +- **D-07:** Channels are **seeded only** (for example #general, #announcements, a Polish channel). Users join seeded channels and cannot create channels of any kind. +- **D-08:** Any community member can DM any other member, as in bm. userfriends does not gate DMs. +- **D-09:** `demo:seed` creates a handful of persona users with message history, threads, reactions and pins in EN and PL channels. The reset job (19.4.1 D-09) wipes and reseeds them along with everything else. There is no live bot persona. + +### Video calls +- **D-10:** LiveKit is self-hosted on rome under supervisor, next to the demo's Centrifugo (19.4.1 D-17), with its own keys in `.env`. The media ports (UDP range, TCP fallback, TURN/TLS through nginx stream or LiveKit's embedded TURN) are opened on rome and documented in `sm-demo-app/DEPLOY.md`. — **Reversibility:** reversible. Moving to LiveKit Cloud later only changes `golem15.chatvideo.livekit_*` config. +- **D-11:** Calls start from DMs only. chat has DMs plus one context-wide group conversation (`GetGroupChat`) and no ad-hoc group DMs, and with D-07 there are no private channels, so in practice that means 1:1 calls. The researcher confirms this against the plugin. Calls are never started in seeded public channels. +- **D-12:** Caps for a public demo: `max_duration` about 15 minutes, about 4 participants per room, the plugin's existing rate limits, and the `chatvideo:reconcile-sessions` job ending idle rooms. +- **D-13:** The video UI is a **minimal call page** (own camera, remote tiles, mute, camera toggle, leave) built on `livekit-client` and released as the first version of a new shared **`vue-chatvideo-layer`**. bm has no video UI to port. + +### Forum, friends, push +- **D-14:** **`vue-forum-layer`** is a new shared layer with a `/forum` page: categories, threads and Markdown posts, seeded in EN and PL by `demo:seed`. +- **D-15:** **`vue-userfriends-layer`** is a new shared layer: friends list, requests and friend groups. It is linked from the chat sidebar and the profile. +- **D-16:** herald (Web Push) is mounted and configured (VAPID keys in `.env`) but has **no subscribe UI** in this phase. + +### Moderation +- **D-17:** A new shared plugin, **`sm-moderation-plugin`**, filters banned words and links in chat messages and forum posts. The banned-word and link lists are editable in its admin settings. On top of it: the plugins' rate limits, Turnstile on register (19.4.1 D-07), admins deleting messages and banning users from the backend, and the reset job. +- **D-18:** chat and forum fire their festival events after the save (`events.MessageCreated` etc.), so the filter needs a **new, generic, additive pre-save seam** in `sm-chat-plugin` and `sm-forum-plugin`: a host- or plugin-registered validator that can reject a message or post before it is persisted. The change is additive and ships as patch tags. It must not change the existing PHP-parity API or payloads (these plugins are WavePath's port target, Phase 31), and the seam names no application. — **Reversibility:** costly. A public plugin contract other consumers can start using. + +### Plan shape (suggestion; confirmed at plan time per the lean-planning rule) +- **D-19:** Backend first, then layers. The suggested split from the discussion, before the forum and userfriends layers and the moderation plugin were added: 01 mount and tag the chat family, demo context, seed, LiveKit and the rome deploy (with the folded todo); 02 the `vue-chat-layer` port; 03 `vue-chatvideo-layer` plus herald config; 04 forum and friends layers, slash-command picker, tour cards; 05 unit tests and live verification. The planner fits in `sm-moderation-plugin`, the pre-save seams and the two extra layers, and presents the final count for confirmation. + +### Claude's Discretion +- Seeded channel names and persona users, and how much EN/PL history to seed. +- How LiveKit's media and TURN ports are exposed on rome (embedded TURN vs nginx stream), as long as calls work from typical NAT'd browsers. +- The exact shape of the pre-save validator seam in chat and forum (interface name, registration through `pact` or the service registry), within D-18's constraints. +- Which chatbots commands are registered for the demo (`/help`, `/demo`, …) and what they answer. +- How `vue-chat-layer` exposes extension points for app-specific embeds. + +### Folded Todos +- **Commit sm-demo-app's leftover journal and oauthserver submodule moves** (`.planning/todos/pending/2026-10-26-sm-demo-app-journal-oauthserver-pointers.md`, g15office `ssuyq2os`): sm-demo-app still shows `M plugins/golem15/oauthserver`. This phase bumps submodule pointers and go.mod requires anyway, so the first plan moves each checkout to the tag go.mod requires and makes one `chore: bump to ` commit per plugin before mounting the chat family. `TestGoModRequiresTags` and `scripts/check-pins.sh` must pass. + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Prior demo decisions +- `.planning/phases/19.4.1-early-public-demo-on-demo-summercms-io/19.4.1-CONTEXT.md` — hosting, accounts, reset job, banner, tour, EN/PL, look, Centrifugo, tagged-module go.mod (D-01..D-23) +- `../sm-demo-app/DEPLOY.md` — rome layout, ports in use, supervisor programs, Centrifugo, release and rollback +- `../sm-demo-app/README.md` — local run, `demo:seed`, credentials handling +- `../sm-demo-app/summer.yaml`, `../sm-demo-app/go.mod` — the current plugin set and tagged requires + +### Chat UI source (port) +- `../sm-bm-app/frontend/src/components/chat/` — ChatPanel, MessageList, ChatMessage, ChatComposer, ChatHeader, DmList, MemberPicker, MentionPopup, ReactionBar, EmbedCard, EmbedPicker, StagingChips, DeleteDialog, Avatar +- `../sm-bm-app/frontend/src/stores/chat.ts`, `../sm-bm-app/frontend/src/api/chat.ts`, `../sm-bm-app/frontend/src/lib/chat{Events,Format,Text,Unread}.ts` (with their tests) +- `../sm-bm-app/plugins/jz/bm/classes/chat_context.go`, `../sm-bm-app/plugins/jz/bm/chat.go` — host context and access wiring to mirror in `golem15.demo` +- `.planning/phases/19.4.1-early-public-demo-on-demo-summercms-io/` plans for the presentations port (precedent for porting a bm Vite view into Nuxt) + +### Plugins +- `../sm-chat-plugin/README.md` — Context contract, Service, events, generic API, channel authorizer +- `../sm-chatchannels-plugin/README.md` — channels, access resolver +- `../sm-chatvideo-plugin/README.md` — LiveKit config keys, API, reconcile job, limits +- `../sm-chatbots-plugin/README.md` — command catalog, dispatch, bot-auth seam +- `../sm-forum-plugin/README.md`, `../sm-herald-plugin/README.md`, `../sm-userfriends-plugin/README.md` +- `.planning/phases/19-chat-and-chatchannels/19-CONTEXT.md` — chat port contract (PHP parity, D-07 generic API mirrors WavePath, which must not drift) +- `.planning/phases/19.1-chat-satellites/19.1-CONTEXT.md` — satellites decisions +- `.planning/notes/core-plugins-own-repos.md` — new shared plugin and layer repos, submodule mounting, commit order + +### Existing layers (pattern) +- `../vue-journal-layer`, `../vue-faq-layer`, `../vue-menu-layer`, `../vue-paymentgateway-layer`, `../vue-oauth-layer` — layer structure, tags, how `vue-demo-app` consumes them + + + + +## Existing Code Insights + +### Reusable Assets +- bm chat SPA (about 4.6k lines with tests): the store, the API client and the event handling port almost directly; components need Nuxt/SSR guards (client-only realtime). +- The demo's Centrifugo and `lighthouse` wiring from 19.4.1 plan 04 (speaker/remote sync) carries chat realtime too; chat authorizes `chat:conversation:{id}` and chatvideo `video:session:{id}`. +- `golem15.demo` plugin and `demo:seed`, with the EN/PL seeding through translate (19.4.1 D-13). +- The `realtime_test.go`, `seed_test.go`, `reset_test.go` and `go_mod_test.go` patterns in sm-demo-app for the new plugins. + +### Established Patterns +- Shared plugin and layer repos are their own git.golem15.com repos, mounted as submodules. Plugins are pushed and tagged first, then the pointer bump in the app goes in a separate commit. +- `go.mod` requires tagged versions (19.4.1 D-03); `scripts/check-pins.sh` and `TestGoModRequiresTags` enforce checkouts at the tag. +- chat/chatchannels APIs and events are PHP-parity contracts for WavePath (Phase 19 D-07, Phase 31). Changes are additive only. + +### Integration Points +- `golem15.demo`: chat `contracts.Context`, chatchannels `ChannelAccessResolver`, seed, moderation word lists, chatbots command registrations. +- `vue-demo-app/nuxt.config.ts` `extends`: four new layers. +- rome: new supervisor program for LiveKit, firewall and nginx changes, `.env` keys (LiveKit, VAPID). + + + + +## Specific Ideas + +- "There is a simple chat view in sm-bm-app": port it rather than build chat UI from scratch. +- The video UI starts small but as a reusable layer ("make it as initial vue-chatvideo-layer"), so later sites and the WavePath work can grow it. +- The user prefers reusable shared pieces over demo-only code: a layer for each satellite with UI, and a shared moderation plugin rather than a filter inside `golem15.demo`. + + + + +## Deferred Ideas + +- Web Push subscribe UI (opt-in notifications for DMs and mentions, sharing the PWA service worker): herald is mounted without UI here. +- User-created channels (public or private) and ad-hoc group DMs with group calls. +- A live bot persona answering in channels. +- A read-only `/chat` preview for anonymous visitors. + +### Reviewed Todos (not folded) +- "Prompt open admin and site tabs to reload when a new version is deployed": its site half was folded into 19.4.1 (D-22); the admin half is framework work, not this phase. +- "Translate Messages as a Nuxt i18n JSON editor", "Port the menu plugin as sm-menu-plugin…", and the user/mfa/cabana/build todos that matched on keywords only: they are unrelated to the chat family on the demo. + + + +--- + +*Phase: 20-demo-instance-with-every-shared-plugin* +*Context gathered: 2026-10-28* diff --git a/.planning/phases/20-demo-instance-with-every-shared-plugin/20-DISCUSSION-LOG.md b/.planning/phases/20-demo-instance-with-every-shared-plugin/20-DISCUSSION-LOG.md new file mode 100644 index 00000000..22209eed --- /dev/null +++ b/.planning/phases/20-demo-instance-with-every-shared-plugin/20-DISCUSSION-LOG.md @@ -0,0 +1,137 @@ +# Phase 20: Demo instance with every shared plugin - Discussion Log + +> **Audit trail only.** Do not use as input to planning, research, or execution agents. +> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered. + +**Date:** 2026-10-28 +**Phase:** 20-demo-instance-with-every-shared-plugin +**Areas discussed:** Chat frontend source, Chat context & access, Video calls hosting, Abuse & satellites scope + +The user corrected the opening premise: "There is simple chat view in sm-bm-app". bm's Vite SPA chat (about 4.6k lines) became the port source. + +Folded todo: "Commit sm-demo-app's leftover journal and oauthserver submodule moves" (Fold it in). + +--- + +## Chat frontend source + +| Option | Description | Selected | +|--------|-------------|----------| +| New vue-chat-layer | Shared Nuxt layer; bm-specific bits stripped or slots | ✓ | +| Demo-only pages | Port into vue-demo-app as 19.4.1 did for presentations | | +| Layer, but later | Demo-only now, extraction as backlog todo | | + +| Option | Description | Selected | +|--------|-------------|----------| +| Full bm feature set | Channels, DMs, threads, mentions, reactions, typing, unread, attachments | ✓ | +| Core only | Channels and DMs with realtime, unread, typing | | + +| Option | Description | Selected | +|--------|-------------|----------| +| Dedicated /chat page | Full-page chat plus tour card | | +| Page + floating panel | /chat plus floating DM/unread widget | ✓ | + +| Option | Description | Selected | +|--------|-------------|----------| +| Read-only #general preview | Live read-only seeded channel | | +| Login prompt only | As quizzes D-18 | ✓ | + +--- + +## Chat context & access + +| Option | Description | Selected | +|--------|-------------|----------| +| One demo community | Single context like bm/1 | ✓ | +| Per-user workspaces | Users create contexts | | + +| Option | Description | Selected | +|--------|-------------|----------| +| Seeded public + user private | Users create private channels | | +| Anyone, any channel | | | +| Seeded only | Join seeded channels, DM each other | ✓ | + +| Option | Description | Selected | +|--------|-------------|----------| +| Seeded users + history, EN/PL | Persona users with history | ✓ | +| Plus a live bot | Bot answers slash commands | | +| Empty channels | | | + +| Option | Description | Selected | +|--------|-------------|----------| +| Any member of the community | userfriends does not gate DMs | ✓ | +| Friends only | | | + +--- + +## Video calls hosting + +| Option | Description | Selected | +|--------|-------------|----------| +| Self-host on rome | LiveKit under supervisor, own keys | ✓ | +| LiveKit Cloud free tier | | | +| Decide in research | | | + +| Option | Description | Selected | +|--------|-------------|----------| +| DMs and private groups | No calls in public channels | ✓ | +| Any conversation | | | + +| Option | Description | Selected | +|--------|-------------|----------| +| LiveKit components in the chat layer | Call view on livekit-client | | +| Minimal call page | Bare-bones join page | ✓ (as the initial vue-chatvideo-layer) | + +**Notes:** "make it as initial vue-chatvideo-layer". Since channels are seeded only and chat has no ad-hoc group DMs, calls are effectively 1:1 DMs. + +| Option | Description | Selected | +|--------|-------------|----------| +| Short calls, few people | ~15 min, ~4 participants | ✓ | +| Plugin defaults | | | + +--- + +## Abuse & satellites scope + +| Option | Description | Selected | +|--------|-------------|----------| +| Rate limits + report + reset | No content filter | | +| Plus a word filter | Banned words/link filter | ✓ | +| Posting needs approval | | | + +Follow-up, filter home: Hook in plugins + list in demo / Demo plugin only / **New shared plugin** ✓ + +| Option | Description | Selected | +|--------|-------------|----------| +| Forum page + friends in chat + /commands | Built in demo or chat layer | | +| A layer for each | vue-forum-layer, vue-userfriends-layer | ✓ | +| Forum only | | | + +Follow-up, which layers: **forum + userfriends; commands in chat layer** ✓ / Also a vue-chatbots-layer + +| Option | Description | Selected | +|--------|-------------|----------| +| Push for DMs and mentions | Opt-in notifications | | +| Mounted, no UI | | ✓ | + +| Option | Description | Selected | +|--------|-------------|----------| +| Backend first, then layers | 5-plan split | ✓ | +| You decide at plan time | | | + +--- + +## Claude's Discretion + +- Seeded channel names, personas, history volume +- LiveKit port/TURN exposure on rome +- Shape of the pre-save validator seam in chat and forum +- Demo chatbots commands +- vue-chat-layer extension points for embeds + +## Deferred Ideas + +- Web Push subscribe UI +- User-created channels and ad-hoc group DMs/group calls +- Live bot persona +- Anonymous read-only chat preview