docs(19.4.1-04): complete presentations, phone remote and quizzes plan
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
---
|
||||
phase: 19.4.1-early-public-demo-on-demo-summercms-io
|
||||
plan: 04
|
||||
subsystem: demo
|
||||
status: complete
|
||||
tags: [demo, presentations, deck-viewer, speaker-view, phone-remote, centrifugo, lighthouse, quizzes, i18n, deploy, rome, playwright]
|
||||
|
||||
requires:
|
||||
- phase: 19.4.1-03
|
||||
provides: "accounts behind Turnstile, the guided tour, EN/PL through the locale cookie, the reload-on-deploy banner, check-local.sh and check-live.sh"
|
||||
provides:
|
||||
- "bm's presentation system as Nuxt pages in vue-demo-app: the public deck /p/{slug}-{hash}, the speaker view /presentations/{slug}, the phone remote /presentations/{slug}/pilot and My presentations /presentations, all client-only"
|
||||
- "/roadmap: a redirect to the roadmap deck of the active language (roadmap or roadmap-pl), generated from the framework's ROADMAP.md, OIDC screenshots included"
|
||||
- "the demo's own Centrifugo v6 on rome (127.0.0.1:8010, supervisor program summercms-demo-centrifugo) wired through lighthouse: GET /api/realtime/token behind jwt.auth, presentations.realtime-owner and the golem15.demo.realtime bucket; POST /api/realtime/subscribe for Centrifugo only; nginx /ws"
|
||||
- "decks written in markdown by any registered user through /_demo/api/v1/presentations: no CSS, no context, never published, fixed themes (default, atlas, monografia, summer), at most 60 slides"
|
||||
- "quizzes: the public list of the language at /quizzes (GET /_demo/api/v1/quizzes?context=demo:{locale}, no answers), the register prompt, and for members the quiz player, the score and the past attempts"
|
||||
- "a member's home page Presentations card and a header link lead to My presentations; logged out the card goes straight to the deck of the language"
|
||||
- "the remote opens in a 390x844 popup on a computer (speaker view Open remote, My presentations Remote); phones open it in place"
|
||||
- "scripts/check-local.sh roadmap|realtime|decks|quizzes|back|remote, check-back.cjs and check-remote.cjs (Playwright), check-deploy and check-live with the realtime, deck, quiz and browser-history checks"
|
||||
affects: [19.4.1-05, sm-demo-app, vue-demo-app]
|
||||
|
||||
actuals:
|
||||
tokens: 98700 # chars/4 over the diffs: sm-demo-app b4caccc..2258047 (images, go.sum and the pointer excluded) 94171 chars, vue-demo-app dc26edf..92fd17f (pnpm-lock.yaml excluded) 300507 chars
|
||||
tasks: 7
|
||||
commits: 24 # measured per repo: sm-demo-app 14 (git rev-list --count b4caccc..HEAD), vue-demo-app 10 (dc26edf..HEAD)
|
||||
plan_head_before: cba0a98 # summercms.go ledger; it carries no code commit of this plan, only this SUMMARY and the ROADMAP update
|
||||
plan_head_after: cba0a98 # summercms.go HEAD when this SUMMARY was written (git rev-list --count cba0a98..HEAD = 0)
|
||||
repo_heads: # where the code commits live
|
||||
sm-demo-app: "b4caccc..2258047 (origin/master = 2258047)"
|
||||
vue-demo-app: "dc26edf..92fd17f (origin/master = 92fd17f)"
|
||||
|
||||
tech-stack:
|
||||
added:
|
||||
- "centrifuge@5.7.3 (npm, exact pin from the RESEARCH legitimacy audit, the version bm uses); its protobufjs build script skipped (allowBuilds false)"
|
||||
- "Centrifugo v6.5.1 on rome at /usr/local/bin/centrifugo (rome's existing binary, the one bm's instance runs)"
|
||||
patterns:
|
||||
- "Port a Vite SPA view as a client-only Nuxt page (routeRules ssr false) with its libraries copied unchanged and its words moved to i18n keys"
|
||||
- "A demo wrapper around a shared plugin's handlers that narrows the input (drops CSS and context, forces unpublished, fixed themes) instead of changing the plugin"
|
||||
- "Login-dependent links from the session cookie that SSR reads, so the server's HTML and the hydrated DOM agree"
|
||||
- "Browser checks with the global Playwright (CommonJS for NODE_PATH): history, hydration, popup size and a remote round trip"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- ../sm-demo-app/plugins/demo/realtime.go
|
||||
- ../sm-demo-app/plugins/demo/routes.go
|
||||
- ../sm-demo-app/plugins/demo/decks_api.go
|
||||
- ../sm-demo-app/plugins/demo/quizzes_api.go
|
||||
- ../sm-demo-app/config/realtime.yaml
|
||||
- ../sm-demo-app/config/golem15.presentations.yaml
|
||||
- ../sm-demo-app/deploy/centrifugo.json.example
|
||||
- ../sm-demo-app/deploy/supervisor/summercms-demo-centrifugo.conf
|
||||
- ../sm-demo-app/scripts/check-back.cjs
|
||||
- ../sm-demo-app/scripts/check-remote.cjs
|
||||
- ../sm-demo-app/vue-demo-app/app/components/deck/DeckViewer.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/deck/SpeakerTools.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/deck/DeckForm.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/remote/RemoteDrawer.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/remote/RemoteKeys.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/remote/RemoteTopBar.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/AttemptList.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/lib/deck/themes.ts
|
||||
- ../sm-demo-app/vue-demo-app/app/lib/realtime.ts
|
||||
- ../sm-demo-app/vue-demo-app/app/lib/pilot.ts
|
||||
- ../sm-demo-app/vue-demo-app/app/assets/deck/themes/summer.css
|
||||
- ../sm-demo-app/vue-demo-app/app/composables/useRoadmapPath.ts
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/roadmap.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/p/[slugHash].vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/presentations/index.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/presentations/new.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/presentations/[slug]/index.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/presentations/[slug]/pilot.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/presentations/[slug]/edit.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/quizzes/index.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/quizzes/[slug].vue
|
||||
modified:
|
||||
- ../sm-demo-app/plugins/demo/plugin.go
|
||||
- ../sm-demo-app/plugins/demo/console/seed.go
|
||||
- ../sm-demo-app/plugins/demo/console/seed_locales.go
|
||||
- ../sm-demo-app/plugins/demo/content/ROADMAP.md
|
||||
- ../sm-demo-app/boot_test.go
|
||||
- ../sm-demo-app/deploy/nginx/demo.summercms.io.conf
|
||||
- ../sm-demo-app/deploy/env.example
|
||||
- ../sm-demo-app/deploy/site.env.example
|
||||
- ../sm-demo-app/scripts/dev.sh
|
||||
- ../sm-demo-app/scripts/check-local.sh
|
||||
- ../sm-demo-app/scripts/check-deploy.sh
|
||||
- ../sm-demo-app/scripts/check-live.sh
|
||||
- ../sm-demo-app/scripts/smoke.sh
|
||||
- ../sm-demo-app/DEPLOY.md
|
||||
- ../sm-demo-app/README.md
|
||||
- ../sm-demo-app/vue-demo-app/nuxt.config.ts
|
||||
- ../sm-demo-app/vue-demo-app/package.json
|
||||
- ../sm-demo-app/vue-demo-app/pnpm-workspace.yaml
|
||||
- ../sm-demo-app/vue-demo-app/i18n/locales/en.json
|
||||
- ../sm-demo-app/vue-demo-app/i18n/locales/pl.json
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/index.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/pages/register.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/SiteHeader.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/SiteFooter.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/components/DemoBanner.vue
|
||||
- ../sm-demo-app/vue-demo-app/app/assets/css/site.css
|
||||
|
||||
key-decisions:
|
||||
- "The demo runs its own Centrifugo v6.5.1 on rome (127.0.0.1:8010, /usr/local/bin/centrifugo, supervisor program summercms-demo-centrifugo) with its own HMAC secret, API key and proxy secret; nothing is shared with bm's instance on 8000 (D-17)."
|
||||
- "Assumption A3 held: Centrifugo v6 accepts static_headers under channel.proxy.subscribe.http. centrifugo checkconfig accepts the template, and live subscribes reach the Go subscribe proxy with the secret (the remote drives the speaker view on demo.summercms.io and in check-remote)."
|
||||
- "The demo deck API refuses edits to a published deck with 403, so the visitor's roadmap decks stay as the seed writes them."
|
||||
- "Logged in, the home page's Presentations card goes to /presentations, My presentations; logged out it goes straight to the deck of the language. SSR reads the session cookie, so the server's link and the hydrated one agree. The header shows My presentations for members, hidden under 720 px."
|
||||
- "On a computer the remote opens in a 390x844 popup, a single named window reused on the next click. The popup is opened without noopener so a blocked popup can be detected, and its opener is set to null at once. Blocked popups fall back to a new tab, then to this tab. Phones (coarse pointer) and modified clicks follow the link."
|
||||
|
||||
requirements-completed: [SC-4, D-13, D-14, D-15, D-16, D-17, D-18, D-23]
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "/roadmap opens the roadmap deck of the language in the ported viewer, OIDC screenshots included"
|
||||
requirement: D-16
|
||||
verification:
|
||||
- kind: integration
|
||||
ref: "check-local.sh roadmap; snapshot --site of both decks; check-live /roadmap redirects and the public deck page"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "The user stepped through both decks and the OIDC screenshots on the live demo (Task 7)"
|
||||
- id: D2
|
||||
description: "Speaker view and phone remote synced through the demo's own Centrifugo; My presentations"
|
||||
requirement: D-17
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "TestBootAllPlugins realtime sub-test (routes mounted with the Centrifugo driver)"
|
||||
status: pass
|
||||
- kind: integration
|
||||
ref: "check-local.sh realtime (401 without a JWT, token for the owner, remote publish, websockets:health, checkconfig)"
|
||||
status: pass
|
||||
- kind: e2e
|
||||
ref: "check-local.sh remote (check-remote.cjs: Open remote opens a 390x844 popup without an opener, the remote fits it, Next in the popup moves the speaker view); check-live /ws upgrade 101 and a foreign Origin refused"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "The user drove the live speaker view from a phone (Task 7)"
|
||||
- id: D3
|
||||
description: "Decks in markdown for any registered user, never published, no CSS or context"
|
||||
requirement: D-15
|
||||
verification:
|
||||
- kind: integration
|
||||
ref: "check-local.sh decks (auth, CSS, context, publish, script sanitizing, theme, update, owner, 403 on a published deck)"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "The user created and presented a deck live (Task 7)"
|
||||
- id: D4
|
||||
description: "Quizzes: public list without answers, register prompt, saved attempts"
|
||||
requirement: D-18
|
||||
verification:
|
||||
- kind: integration
|
||||
ref: "check-local.sh quizzes; smoke.sh; check-live quiz list and Polish quiz"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "The user took a quiz logged out and in (Task 7)"
|
||||
- id: D5
|
||||
description: "Members' Presentations link (card and header), SSR and hydration agree"
|
||||
requirement: D-14
|
||||
verification:
|
||||
- kind: e2e
|
||||
ref: "check-back.cjs member home EN and PL, run by check-local back and check-live on demo.summercms.io"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D6
|
||||
description: "Live on demo.summercms.io"
|
||||
requirement: SC-4
|
||||
verification:
|
||||
- kind: e2e
|
||||
ref: "build.sh release 4e73a1460aff, smoke ok, check-deploy ok, check-live https://demo.summercms.io ok, websockets:health Configuration OK"
|
||||
status: pass
|
||||
human_judgment: true
|
||||
rationale: "\"everything passes … aside that, everything is approved, great job\"; the two fixes asked for were deployed and check-live is green"
|
||||
|
||||
duration: ~2h25m wall clock (plan 03 closed 16:33 +02:00 at cba0a98; the last redeploy and this SUMMARY by 18:58)
|
||||
completed: 2026-10-20
|
||||
---
|
||||
|
||||
# Phase 19.4.1 Plan 04: Presentations, phone remote and quizzes Summary
|
||||
|
||||
**demo.summercms.io runs bm's presentation system as Nuxt pages: /roadmap opens the roadmap deck of the visitor's language in the ported viewer, a deck owner presents from the speaker view and drives it from the phone remote through the demo's own Centrifugo, and any registered user writes decks in markdown. Anonymous visitors browse the quizzes of their language; members take them and see their attempts. Members reach My presentations from the home page card and the header. On a computer the remote opens in a phone-sized popup.**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** about 2h25m wall clock, including the Task 5 go-ahead, the deploys and the Task 7 check with its two fixes
|
||||
- **Started:** 2026-10-20T14:33Z (after plan 03 closed at cba0a98)
|
||||
- **Completed:** 2026-10-20T16:58Z
|
||||
- **Tasks:** 7/7
|
||||
- **Files modified:** 85 (26 in sm-demo-app including the vue-demo-app pointer, 59 in vue-demo-app)
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- **Roadmap deck (D-16).** `GET /_demo/api/v1/roadmap?locale=en|pl` returns the published roadmap deck's slug and public hash. Any other locale gets the English deck. `/roadmap` redirects there: a 302 on the server, a history replace on client navigation. The decks come from the ROADMAP.md snapshot embedded in the binary. `demo:seed` rewrites them on every deploy and keeps their hashes.
|
||||
- **Speaker view, remote, My presentations (D-14, D-17).** bm's views run client-only (`routeRules` ssr false). The remote logic is bm's and is unchanged. The `golem15.demo` plugin wires lighthouse as bm's app plugin does: the token route sits behind `jwt.auth`, `presentations.realtime-owner` and the `golem15.demo.realtime` bucket (120 a minute per user), and the subscribe proxy is checked by `X-Centrifugo-Secret`. `config/realtime.yaml` keeps `driver: "null"`, and `.env` selects Centrifugo.
|
||||
- **Decks in markdown (D-15).** `/presentations/new` and `/presentations/{slug}/edit` call `/_demo/api/v1/presentations`, which wraps the presentations plugin's manage handlers. The owner comes from the JWT, and every HTML field still passes `classes.Clean`. The wrapper drops CSS and context, keeps decks unpublished, allows the themes default, atlas, monografia and summer, and caps a deck at 60 slides. The markdown source lives in the slide's owner-only todo field, so the edit form reopens what the user wrote.
|
||||
- **Quizzes (D-18, D-13).** `/quizzes` is server-rendered from `GET /_demo/api/v1/quizzes?context=demo:{locale}`, which returns slug, title, description and question count and never any answers. Anonymous visitors see a register prompt. Members take a quiz on the quizzes plugin's API and see the score and bm's AttemptList. The seed adds summercms-podstawy (demo:pl) and the Polish deck pierwsze-kroki.
|
||||
- **Fixes after the user's check (Task 7).** The user approved the live demo ("everything passes … aside that, everything is approved, great job") and asked for two fixes. Both are deployed:
|
||||
1. **Presentations link by login state.** When logged in, the home page's Presentations card links to `/presentations` with its own sentence ("write your own in My presentations and drive it from your phone"; in PL "napisz własną prezentację w Moich prezentacjach…"). When logged out, the card still links straight to the deck of the language (745fa0b). SSR reads the session cookie just as the header does, so the server's HTML and the hydrated DOM agree, with no flash and no mismatch. The header shows "My presentations" ("Moje prezentacje") next to Log out for members. It is hidden under 720 px, where the card leads there instead.
|
||||
2. **Remote in a phone-sized popup.** The speaker tools have a new "Open remote" button ("Otwórz pilota"). It, and My presentations' Remote, open the deck's remote in a 390x844 popup at the right edge of the current window. Phones and modified clicks open it in place, as before.
|
||||
- **Checks.** `check-local.sh` gained roadmap, realtime, decks, quizzes, back and remote. `check-back.cjs` checks Back from the deck, the deep link and the members' card and header link in EN and PL, with no hydration mismatch, both locally and live. `check-remote.cjs` checks the popup size, that the popup has no opener, the remote layout at 390x844 (nothing wider than the window, Next inside it), and that Next in the popup moves the speaker view. The remote check needs a login, so it runs locally only. `check-deploy.sh` checks the Centrifugo config, the ports, and the absence of a subscribe-proxy location. `check-live.sh` checks the realtime, deck and quiz routes, the /ws upgrade and the browser history.
|
||||
|
||||
## bm files ported (from sm-bm-app/frontend/src; sm-bm-app itself untouched)
|
||||
|
||||
| Demo file | bm source | Changes |
|
||||
|-----------|-----------|---------|
|
||||
| app/lib/deck/clock.ts, compose.ts, engine.ts, reading.ts, remote.ts, styles.ts | lib/deck/* | none (byte-identical); their Polish copy is mapped to i18n keys by useDeckText where shown |
|
||||
| app/lib/deck/themes.ts | lib/deck/themes.ts | the summer theme added (summer.css, the summercms.io look) |
|
||||
| app/lib/markdown.ts, app/lib/api/http.ts | lib/markdown.ts, api/http.ts | none |
|
||||
| app/lib/realtime.ts | lib/realtime.ts | import paths and comments only |
|
||||
| app/lib/pilot.ts | lib/pilot.ts | Task 7: openRemoteWindow and remoteLinkClick (the phone-sized popup) |
|
||||
| app/lib/forms.ts, api/presentations.ts, api/quizzes.ts | same | import paths |
|
||||
| app/lib/api/client.ts | api/client.ts | the token store reads and writes the demo's JWT cookie instead of localStorage; the onUnauthorized hook sends to /login (useDeckSession) |
|
||||
| app/lib/api/types.ts | api/types.ts | only the presentation and quiz types |
|
||||
| app/assets/deck/deck.css, deck-speaker.css, themes/atlas.css, monografia.css | deck/* | none; summer.css is new |
|
||||
| app/components/deck/DeckViewer.vue | components/deck/DeckViewer.vue | i18n words, the compact demo banner offset (hidden in fullscreen), the summer theme |
|
||||
| app/components/deck/SpeakerTools.vue | components/deck/SpeakerTools.vue | i18n words; Task 7: the Open remote button |
|
||||
| app/components/remote/RemoteDrawer.vue, RemoteKeys.vue, RemoteTopBar.vue | components/remote/* | i18n words; RemoteIcon.vue added for the key icons |
|
||||
| app/components/AttemptList.vue | components/AttemptList.vue | i18n words |
|
||||
| app/pages/p/[slugHash].vue | views/PresentationPublicView.vue | route param, demo banner |
|
||||
| app/pages/presentations/[slug]/index.vue | views/PresentationSpeakerView.vue | route slug, login redirect, i18n, demo paths; Task 7: remoteHref |
|
||||
| app/pages/presentations/[slug]/pilot.vue | views/PresentationRemoteView.vue | fonts through @nuxt/fonts, login redirect, i18n, demo banner |
|
||||
| app/pages/presentations/index.vue | views/MyPresentationsView.vue | site layout, New deck and Edit, private note; Task 7: Remote opens the popup |
|
||||
| app/pages/quizzes/index.vue, [slug].vue | QuizzesView, QuizView | the demo's public list; the demo's own choice-quiz player (bm's self_check step kept) |
|
||||
| app/composables/useToast.ts | bm's Pinia toast store | shared Nuxt state, no Pinia |
|
||||
|
||||
## Rome (no secret values recorded)
|
||||
|
||||
- **Centrifugo:** v6.5.1, `/usr/local/bin/centrifugo -c /srv/summercms-demo/centrifugo.json` as the supervisor program `summercms-demo-centrifugo` (user summercms-demo). It listens on 127.0.0.1:8010, and nginx sends `/ws` to `/connection/websocket` there. The subscribe proxy calls Go on 127.0.0.1:8098, and nginx never routes it. `centrifugo.json` is 640 root:summercms-demo. bm's instance on 8000 is untouched.
|
||||
- **Environment:** 7 keys were added to `.env` (the realtime driver, API URL, API key, token secret, proxy secret, WS URL and the presentations remote key) and 1 to `site.env` (`NUXT_DEMO_API_BASE`). All were generated on rome and never printed. The old nginx vhost copy is in `/root/`.
|
||||
- **Final release:** sm-demo-app **2258047** with vue-demo-app **92fd17f**, build **4e73a1460aff**. The steps were upload with `--chown=root:root`, migrate, demo:seed (the roadmap decks updated), swap and restart. nginx and Centrifugo are unchanged in this redeploy. websockets:health printed Configuration OK, and three supervisor programs are RUNNING. Rollback copies are `bin/demo.prev` and `site/.output.prev` (the previous release, 6651eb05abf5).
|
||||
- The seed printed the presentations plugin's harmless GORM "record not found" lines.
|
||||
|
||||
## Task Commits
|
||||
|
||||
| Task | Repo | Commits |
|
||||
|------|------|---------|
|
||||
| 1. Tracer: /roadmap in the ported viewer | sm-demo-app; vue-demo-app | b66f3b0; 0c0bb01 |
|
||||
| 2. Speaker view, remote, realtime | sm-demo-app; vue-demo-app | b8a9ca3; 97913c1 |
|
||||
| 3. Decks in markdown | sm-demo-app; vue-demo-app | 86b267f; 0364be8 |
|
||||
| 4. Quizzes | sm-demo-app; vue-demo-app | a28cd4e; 699221b |
|
||||
| Prep: ROADMAP snapshot, pointer, Task 6 local files | sm-demo-app | b5d8e9d, 829d8fd, 7f9cab8 |
|
||||
| 5. Go-ahead (decision) | - | approved |
|
||||
| 6. Live with the demo's own Centrifugo | vue-demo-app; sm-demo-app | a4b333c, 25e6a9e; f0f3b6e, efceaed, dac0194 |
|
||||
| 7. User check and fixes | vue-demo-app; sm-demo-app | 745fa0b, e17ee5f, 418a82c, 92fd17f; 82ea75c, 991332a, 97e6589, 2258047 |
|
||||
|
||||
vue-demo-app was pushed before sm-demo-app every time. Remote masters: sm-demo-app 2258047, vue-demo-app 92fd17f.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
1. **[Plan 03 open item] Summer theme.** The summer theme (summercms.io's look) was ported into the viewer, `themes.ts` and the deck API's theme list.
|
||||
2. **[Rule 3] DeckViewer edits.** The viewer sits below the compact demo banner (hidden in fullscreen) and takes its words from i18n.
|
||||
3. **[Rule 3] Polish strings in the ported library.** `lib/deck/remote.ts` and `compose.ts` keep bm's Polish copy byte-identical. `useDeckText` maps it to EN/PL i18n keys where it is shown. The Polish i18n wording for the extra slide is "Slajd dodatkowy", the library's own term.
|
||||
4. **[Rule 3] Dev WebSocket.** Nitro's dev proxy does not carry WebSocket upgrades, so a `listen` hook in nuxt.config.ts sends `/ws` upgrades to the local Centrifugo in development. a4b333c then proxied only `/api/realtime/token` to Go, as nginx does.
|
||||
5. **[Rule 3] checkconfig.** `centrifugo checkconfig` needs a `.json` extension, so the template is checked from a `.json` copy.
|
||||
6. **[Rule 2] PUT on a published deck returns 403.** This protects the seeded roadmap decks. check-local asserts it.
|
||||
7. **[Rule 3] Quiz player.** The demo has its own choice-quiz player on the plugin's API rather than bm's QuizView store. bm's self_check step is kept.
|
||||
8. **[Rule 2] Register `?next`.** Registration returns to a same-site `next` path, as login does.
|
||||
9. **[Rule 3] `snapshot --site`.** dev.sh renders the decks through the site's own viewer as well.
|
||||
10. **[Rule 3] protobufjs.** centrifuge's protobufjs build script is skipped (`allowBuilds: false`), because it only prints a version warning.
|
||||
11. **[Rule 3] `NUXT_DEMO_API_BASE`.** The site reads the demo API on the server through `NUXT_DEMO_API_BASE`. Without it, the build-time default would point at port 8097.
|
||||
12. **[Rule 1] Whole-card tour links.** Tour cards with a page are clickable as a whole.
|
||||
13. **Task 6 local files prepared early.** The nginx, supervisor, check-deploy and check-live changes (7f9cab8) were committed before the Task 5 go-ahead. Nothing was deployed before it.
|
||||
14. **[Task 7] Back button.** Back from the roadmap deck returned to the `/roadmap` redirect. The card now links straight to the deck (745fa0b), and check-back.cjs covers it.
|
||||
15. **[Task 7] Footer link.** The footer's SummerCMS links to summercms.io (e17ee5f).
|
||||
16. **[Task 7, user fix 1] Members' Presentations link** (418a82c). See Accomplishments.
|
||||
17. **[Task 7, user fix 2] Phone-sized remote popup** (92fd17f). See Accomplishments. Notes:
|
||||
- The user asked for `window.open` with `noopener`. With `noopener`, `window.open` always returns null, so a blocked popup could not be detected. The popup is therefore opened without it, and `opener` is set to null right away, before the remote loads. That has the same effect.
|
||||
- **There is no QR code to keep.** Neither bm nor the demo ever had one, and adding one would need a new npm package, which needs approval. "The plain link for real phones" is My presentations' Remote link, which phones still follow in place.
|
||||
- The Open remote button is new: the speaker tools had no Remote button before, only the "Remote" status chip.
|
||||
- Headless Chromium caps windows to an 800x600 screen, so check-remote launches with `--window-size=1920,1080`.
|
||||
|
||||
**Impact:** every change is local to sm-demo-app and vue-demo-app. No shared plugin or file under sm-bm-app changed, and the only npm package added is the audited centrifuge@5.7.3.
|
||||
|
||||
## Threat model update
|
||||
|
||||
T-19.4.1-25 to -32 and -SC are mitigated as planned (check-local decks, quizzes and realtime; check-deploy; check-live). The remote popup adds no surface. It is a same-origin page that already existed, and its opener is cut.
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
- The local remote check needs the visitor's JWT. This session's secret guard blocks reading `.env` in an ad-hoc command, so the check runs through `check-local.sh remote`, which reads the credentials itself and never prints them.
|
||||
- After this plan's ROADMAP commit, the embedded ROADMAP snapshot in sm-demo-app (`plugins/demo/content/ROADMAP.md`, synced from cba0a98 in b5d8e9d) is stale again. `scripts/build.sh release` refuses a stale snapshot, so **plan 05 must run `scripts/sync-roadmap.sh` and commit before its release**.
|
||||
|
||||
## Open items for later plans
|
||||
|
||||
- **Plan 05:** re-sync the ROADMAP snapshot before the release (see above).
|
||||
- The Accounts tour card still links to /register for members. This is out of scope here.
|
||||
- A QR code for the remote in the speaker view would need an approved package.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None. The realtime secrets were generated on rome and are not recorded anywhere else.
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
Ready for 19.4.1-05.
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None.
|
||||
|
||||
## Threat Flags
|
||||
|
||||
None beyond the threat model above.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- sm-demo-app commits found: b66f3b0, b8a9ca3, 86b267f, a28cd4e, b5d8e9d, 829d8fd, 7f9cab8, f0f3b6e, efceaed, dac0194, 82ea75c, 991332a, 97e6589, 2258047; origin/master = 2258047 = HEAD.
|
||||
- vue-demo-app commits found: 0c0bb01, 97913c1, 0364be8, 699221b, a4b333c, 25e6a9e, 745fa0b, e17ee5f, 418a82c, 92fd17f; origin/master = 92fd17f = HEAD.
|
||||
- Files found: scripts/check-remote.cjs, scripts/check-back.cjs, plugins/demo/realtime.go, deploy/centrifugo.json.example, app/lib/pilot.ts, app/components/deck/SpeakerTools.vue.
|
||||
- Local: check-local ok for all eleven checks. Release: build 4e73a1460aff, smoke ok, check-deploy ok. Live: check-live ok, websockets:health Configuration OK, summercms-demo, summercms-demo-site and summercms-demo-centrifugo RUNNING.
|
||||
Reference in New Issue
Block a user