forked from cms/tibi-svelte-starter
✨ feat: enhance project setup and architecture documentation
- Updated `tibi-project-setup` skill to clarify project initialization goals and steps. - Improved `tibi-ssr-caching` skill to detail SSR architecture, responsibilities, and caching mechanisms. - Introduced `website-solution-architecture` skill for translating website requirements into coherent solutions. - Refined `AGENTS.md` to provide a structured roadmap for project development phases. - Added `ADMIN_ASSET_VERSION` to `api/config.yml.env` for asset versioning. - Updated SSR request flow and cache invalidation logic in `api/hooks/ssr/AGENTS.md`. - Removed obsolete `esbuild.config.admin.js` and integrated asset versioning into the main `esbuild.config.js`. - Adjusted `api/collections/content.yml` to utilize asset versioning for admin scripts.
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
---
|
||||
name: realtime-and-live-workflows
|
||||
description: Use tibi-server SSE channels for live website and admin workflows. Covers channel design, subscription hooks, replay/TTL/buffer behavior, permission boundaries, and when realtime fits a website project.
|
||||
---
|
||||
|
||||
# realtime-and-live-workflows
|
||||
|
||||
## When to use this skill
|
||||
|
||||
Use this skill when:
|
||||
|
||||
- A website or admin feature needs live updates
|
||||
- You want SSE-based notifications, preview refreshes, status feeds, or dashboards
|
||||
- Hooks or jobs should push messages to connected clients
|
||||
- You need to decide whether realtime is actually appropriate for the feature
|
||||
|
||||
## Goal
|
||||
|
||||
The goal is to model realtime as a deliberate workflow, not as a random event stream.
|
||||
|
||||
On this stack, realtime means:
|
||||
|
||||
- SSE transport
|
||||
- in-memory per-project channels
|
||||
- server-side send from hooks/jobs
|
||||
- subscription endpoints implemented in hooks
|
||||
|
||||
## Source of truth
|
||||
|
||||
Use these sources when implementing or reviewing realtime behavior:
|
||||
|
||||
- `tibi-server/docs/07-realtime.md`
|
||||
- `tibi-server/docs/11-jobs.md`
|
||||
- the relevant hook files under `api/hooks/`
|
||||
|
||||
## Core architecture
|
||||
|
||||
tibi-server realtime is based on per-project in-memory pub/sub channels.
|
||||
|
||||
Important characteristics:
|
||||
|
||||
- channels are created on demand
|
||||
- channels are isolated per project
|
||||
- the transport is SSE, not WebSockets
|
||||
- messages are not durable across restarts
|
||||
- hooks subscribe, hooks or jobs send
|
||||
|
||||
This makes realtime useful for live UX, but not for durable messaging.
|
||||
|
||||
## Good use cases for website projects
|
||||
|
||||
Good fits:
|
||||
|
||||
- live status or progress streams
|
||||
- lightweight admin notifications
|
||||
- system messages pushed from jobs
|
||||
- preview or refresh signals after mutations
|
||||
- dashboards with current in-memory activity
|
||||
|
||||
Weak fits:
|
||||
|
||||
- business-critical guaranteed delivery
|
||||
- cross-instance distributed eventing
|
||||
- durable queue semantics
|
||||
- workflows that require replay beyond a bounded in-memory buffer
|
||||
|
||||
## Subscription design
|
||||
|
||||
Realtime subscriptions should be exposed intentionally through dedicated read hooks that hold the SSE connection open.
|
||||
|
||||
Design the endpoint around:
|
||||
|
||||
- who may subscribe
|
||||
- which channel names exist
|
||||
- what event shape clients receive
|
||||
- how replay and freshness should work
|
||||
|
||||
Do not expose a generic raw event hose unless the project truly needs that.
|
||||
|
||||
## Channel options that matter
|
||||
|
||||
When modeling realtime behavior, decide these explicitly:
|
||||
|
||||
- `bufferSize`
|
||||
- `onFull`
|
||||
- `messageTTL`
|
||||
- `lastN`
|
||||
- `maxAge`
|
||||
|
||||
These are product decisions, not low-level afterthoughts.
|
||||
|
||||
### Buffer size
|
||||
|
||||
Use a larger buffer only when reconnecting clients should receive some recent history. Do not overestimate it as persistence.
|
||||
|
||||
### On-full behavior
|
||||
|
||||
- `drop-oldest` favors receiving the newest state, even if some history is lost
|
||||
- `drop-newest` preserves older pending messages for the subscriber and skips the new one
|
||||
|
||||
For most live UI use cases, `drop-oldest` is the more natural choice.
|
||||
|
||||
### Replay and freshness
|
||||
|
||||
Use `lastN` or `maxAge` only when reconnecting clients genuinely benefit from recent context.
|
||||
|
||||
For notification-like channels, some replay can help.
|
||||
For pure live status indicators, it may be better to show only new events.
|
||||
|
||||
## Permission boundaries
|
||||
|
||||
Channels do not carry independent auth rules. Access is controlled by the hook/collection permission layer that exposes the SSE endpoint.
|
||||
|
||||
That means:
|
||||
|
||||
- secure the subscription endpoint, not just the client code
|
||||
- do not assume channel names themselves protect access
|
||||
- be explicit about who may connect and what data is safe to send
|
||||
|
||||
## Event design
|
||||
|
||||
Prefer small, explicit event shapes.
|
||||
|
||||
Good event payloads usually include:
|
||||
|
||||
- event `type`
|
||||
- relevant identifier
|
||||
- minimal status or message fields
|
||||
- timestamp when useful
|
||||
|
||||
Avoid pushing whole documents unless the live client truly needs them.
|
||||
|
||||
## Hooks vs. jobs
|
||||
|
||||
Use hooks to send events when changes happen immediately in response to requests.
|
||||
|
||||
Use jobs to send events when the trigger is scheduled or background-driven.
|
||||
|
||||
Typical patterns:
|
||||
|
||||
- hook sends `content-updated`
|
||||
- job sends `maintenance-warning`
|
||||
- hook sends `import-finished`
|
||||
- job sends `daily-report-ready`
|
||||
|
||||
## Operational limits
|
||||
|
||||
This realtime system is intentionally lightweight.
|
||||
|
||||
Important limits:
|
||||
|
||||
- messages are lost on server restart
|
||||
- no cross-server synchronization
|
||||
- no durable backlog
|
||||
- slow subscribers can miss messages due to ring-buffer behavior
|
||||
|
||||
If the feature cannot tolerate these limits, this realtime system is the wrong abstraction.
|
||||
|
||||
## Recommended modeling patterns
|
||||
|
||||
### Live admin notifications
|
||||
|
||||
Recommended shape:
|
||||
|
||||
- authenticated SSE endpoint
|
||||
- narrow event schema
|
||||
- optional short replay via `lastN`
|
||||
|
||||
### Preview refresh signal
|
||||
|
||||
Recommended shape:
|
||||
|
||||
- hook emits lightweight invalidation or refresh event
|
||||
- client decides whether to refetch
|
||||
- do not stream full content when a simple signal is enough
|
||||
|
||||
### Scheduled status feed
|
||||
|
||||
Recommended shape:
|
||||
|
||||
- job emits events to a system channel
|
||||
- UI listens and renders current status
|
||||
- TTL keeps stale messages from resurfacing after reconnect
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- Using realtime as a replacement for persistence
|
||||
- Publishing sensitive data because “the UI needs it quickly”
|
||||
- Creating one generic catch-all channel for unrelated features
|
||||
- Ignoring replay/TTL/buffer behavior and assuming delivery guarantees
|
||||
|
||||
## Verification checklist
|
||||
|
||||
After adding realtime behavior, verify all of these:
|
||||
|
||||
1. The subscription endpoint is permissioned correctly.
|
||||
2. The event shape is explicit and minimal.
|
||||
3. Replay/TTL/buffer settings match the intended UX.
|
||||
4. Disconnect/reconnect behavior is acceptable.
|
||||
5. The feature still behaves sensibly after a server restart.
|
||||
6. `yarn validate` stays clean.
|
||||
|
||||
## What an LLM should inspect first
|
||||
|
||||
When asked to add realtime to this starter, inspect in this order:
|
||||
|
||||
1. `tibi-server/docs/07-realtime.md`
|
||||
2. the hook that should expose or emit the events
|
||||
3. whether a job is also part of the workflow
|
||||
4. the permission boundary of the SSE endpoint
|
||||
5. the exact event contract the client needs
|
||||
|
||||
This prevents building live features with unclear delivery or security assumptions.
|
||||
Reference in New Issue
Block a user