openvibers/openvibe.tips Commits
README and STATUS: PowerChat checkout works on openvibe.tips (TIPS_POWERCHAT_LINK_TEMPLATE set to the canonical tip link on the site account, as Live builds it) (#65)
Changes
@@@ -113,6 +113,12 @@ delivery record; a reversal before delivery cancels the queued effects (`tips.in| `external` | nothing — a tip on the creator's own PowerChat (ADR-012 EXTERNAL) | `POST /api/v1/interactions/external`, or Billing's `billing.receipt.external` (origin `billing-external`: Tips posts the chat line — `… tipped N Vibes: msg (PowerChat)` — plus overlay alert and goal, as Live's webhook did); once per (provider, provider_ref); never in Billing totals || `none` (simulation) | nothing | at once, `test = 1`: full effect path, no goal contribution, no durable event, excluded from totals |++PowerChat: Billing answers a PowerChat intent with a `checkout_ref` (`pcorder:<intent>`) and no URL, and Tips builds++the link from `TIPS_POWERCHAT_LINK_TEMPLATE` (`{ref}`, `{cents}`, `{bits}`). Production sets it since 2026-10-17 to++PowerChat's canonical tip link on the site's PowerChat account, the same link OpenVibe.Live builds for Vibes purchases++(`https://<powerchat>/<site account>/tip?app_client_id=…&app_ref={ref}&app_purpose=vibes&app_amount_cents={cents}`):++the payment's webhook reaches Billing through openvibe.live, Billing credits the supporter, and Tips gives the tip.++**Exactly one logical interaction:** the inbox claims `(consumer, event_id)` in the same serializabletransaction as the change, so a redelivered event does nothing; `billing_txn_id` is UNIQUE, so the sameBilling transaction under another event id (republish, replay) is still one interaction; API calls carry@@@ -406,9 +412,6 @@ With `VALKEY_URL` every process counts one caller together (`test/integration.te## What waits--- **PowerChat checkout from openvibe.tips**: Billing answers a PowerChat checkout with a `checkout_ref` and no-- URL, and `TIPS_POWERCHAT_LINK_TEMPLATE` is not set in production, so supporters on openvibe.tips pay with Vibes-- credit. (Tips on a streamer's own PowerChat page do arrive: `billing.receipt.external`, see below.)- **EXTERNAL PowerChat tips** arrive as `billing.receipt.external` since the Billing cutover (2026-10-17), throughthe `billing.receipt.*` subscription; the chat adapter posts the chat line and plays the alert, and Live advancesits own channel goal and tip history from `tips.interaction.ready` (OpenVibe.Live `server/tips/tips-events.js`).@@@ -7,12 +7,12 @@"adr": "ADR-012","authoritative": false,"deployed": true,-- "deployment": "Launched 2026-10-17 at https://openvibe.tips (openvibe-contracts 0.200.0 made Tips live; vhost deploy/nginx/openvibe.tips.conf installed): deployed with `sudo ovhost deploy tips`, /opt/openvibe.tips, unit openvibe-tips, 127.0.0.1:4610 behind nginx. Principal tips; Events subscriptions billing.transaction.* and billing.receipt.* -> /internal/events; TIPS_CHAT_ADAPTER=chat (chat lines and alerts through OpenVibe.Chat). OpenVibe.Live subscribes to tips.interaction.ready for its channel goal and tip history.",++ "deployment": "Launched 2026-10-17 at https://openvibe.tips (openvibe-contracts 0.200.0 made Tips live; vhost deploy/nginx/openvibe.tips.conf installed): deployed with `sudo ovhost deploy tips`, /opt/openvibe.tips, unit openvibe-tips, 127.0.0.1:4610 behind nginx. Principal tips; Events subscriptions billing.transaction.* and billing.receipt.* -> /internal/events; TIPS_CHAT_ADAPTER=chat (chat lines and alerts through OpenVibe.Chat). OpenVibe.Live subscribes to tips.interaction.ready for its channel goal and tip history. TIPS_POWERCHAT_LINK_TEMPLATE turns Billing's pcorder: ref into PowerChat's canonical tip link on the site account (since 2026-10-17).","database": "PostgreSQL 18 through PgBouncer (transaction mode) as the system of record, Valkey 9 for shared state (per-actor limits, overlay fan-out, overlay stream slots), ADR-035: database ov_tips from OpenVibe.Host's data role, schema in migrations/ (0001_initial expand, 0002_drop_legacy_import contract), async on openvibe-sdk/db v0.28.0, money paths serializable with row locks, PostgreSQL outbox and inbox.","contracts": "openvibe-contracts v0.200.0","sdk": "openvibe-sdk v0.50.1","shared": "openvibe-shared v4.3.0",-- "notes": "Runtime, API, SSR pages, overlays, the Billing settlement consumer and the events outbox are built, tested and deployed, together with /metrics (loopback only), truthful /api/ready (Billing and Events checks), supporter privacy (anonymous, hidden amount, private message), goal and supporter-page settings, export and erasure (tips.interaction.erased), moderation (word filter, hide/show, invited moderators, tips.interaction.moderated) and per-actor limits. Capabilities (18 tips.*) and payload schemas are in openvibe-contracts. Billing is the money ledger since the cutover (2026-10-17). A written internal threat review (docs/threat-review.md) with its fixes and test/security.test.js. Paid sounds (creators upload up to 12, supporters pay to play one on the overlay) since 2026-10-17. Not done: an independent security review; a PowerChat checkout link for tips made on openvibe.tips (TIPS_POWERCHAT_LINK_TEMPLATE unset: supporters there pay with Vibes credit).",++ "notes": "Runtime, API, SSR pages, overlays, the Billing settlement consumer and the events outbox are built, tested and deployed, together with /metrics (loopback only), truthful /api/ready (Billing and Events checks), supporter privacy (anonymous, hidden amount, private message), goal and supporter-page settings, export and erasure (tips.interaction.erased), moderation (word filter, hide/show, invited moderators, tips.interaction.moderated) and per-actor limits. Capabilities (18 tips.*) and payload schemas are in openvibe-contracts. Billing is the money ledger since the cutover (2026-10-17). A written internal threat review (docs/threat-review.md) with its fixes and test/security.test.js. Paid sounds (creators upload up to 12, supporters pay to play one on the overlay) since 2026-10-17. Not done: an independent security review.","features": ["tips, paid messages, TTS and media requests settled by OpenVibe.Billing (never Tips' own money)","paid sounds: creators upload up to 12 sounds, supporters pay to play one on the overlay, chat names it",
@@ -113,6 +113,12 @@ delivery record; a reversal before delivery cancels the queued effects (`tips.in
@@ -113,6 +113,12 @@ delivery record; a reversal before delivery cancels the queued effects (`tips.in
| `external` | nothing — a tip on the creator's own PowerChat (ADR-012 EXTERNAL) | `POST /api/v1/interactions/external`, or Billing's `billing.receipt.external` (origin `billing-external`: Tips posts the chat line — `… tipped N Vibes: msg (PowerChat)` — plus overlay alert and goal, as Live's webhook did); once per (provider, provider_ref); never in Billing totals |
| `external` | nothing — a tip on the creator's own PowerChat (ADR-012 EXTERNAL) | `POST /api/v1/interactions/external`, or Billing's `billing.receipt.external` (origin `billing-external`: Tips posts the chat line — `… tipped N Vibes: msg (PowerChat)` — plus overlay alert and goal, as Live's webhook did); once per (provider, provider_ref); never in Billing totals |
| `none` (simulation) | nothing | at once, `test = 1`: full effect path, no goal contribution, no durable event, excluded from totals |
| `none` (simulation) | nothing | at once, `test = 1`: full effect path, no goal contribution, no durable event, excluded from totals |
+PowerChat: Billing answers a PowerChat intent with a `checkout_ref` (`pcorder:<intent>`) and no URL, and Tips builds
+the link from `TIPS_POWERCHAT_LINK_TEMPLATE` (`{ref}`, `{cents}`, `{bits}`). Production sets it since 2026-10-17 to
+PowerChat's canonical tip link on the site's PowerChat account, the same link OpenVibe.Live builds for Vibes purchases
+(`https://<powerchat>/<site account>/tip?app_client_id=…&app_ref={ref}&app_purpose=vibes&app_amount_cents={cents}`):
+the payment's webhook reaches Billing through openvibe.live, Billing credits the supporter, and Tips gives the tip.
+
**Exactly one logical interaction:** the inbox claims `(consumer, event_id)` in the same serializable
**Exactly one logical interaction:** the inbox claims `(consumer, event_id)` in the same serializable
transaction as the change, so a redelivered event does nothing; `billing_txn_id` is UNIQUE, so the same
transaction as the change, so a redelivered event does nothing; `billing_txn_id` is UNIQUE, so the same
Billing transaction under another event id (republish, replay) is still one interaction; API calls carry
Billing transaction under another event id (republish, replay) is still one interaction; API calls carry
@@ -406,9 +412,6 @@ With `VALKEY_URL` every process counts one caller together (`test/integration.te
@@ -406,9 +412,6 @@ With `VALKEY_URL` every process counts one caller together (`test/integration.te
## What waits
## What waits
-- **PowerChat checkout from openvibe.tips**: Billing answers a PowerChat checkout with a `checkout_ref` and no
- URL, and `TIPS_POWERCHAT_LINK_TEMPLATE` is not set in production, so supporters on openvibe.tips pay with Vibes
- credit. (Tips on a streamer's own PowerChat page do arrive: `billing.receipt.external`, see below.)
- **EXTERNAL PowerChat tips** arrive as `billing.receipt.external` since the Billing cutover (2026-10-17), through
- **EXTERNAL PowerChat tips** arrive as `billing.receipt.external` since the Billing cutover (2026-10-17), through
the `billing.receipt.*` subscription; the chat adapter posts the chat line and plays the alert, and Live advances
the `billing.receipt.*` subscription; the chat adapter posts the chat line and plays the alert, and Live advances
its own channel goal and tip history from `tips.interaction.ready` (OpenVibe.Live `server/tips/tips-events.js`).
its own channel goal and tip history from `tips.interaction.ready` (OpenVibe.Live `server/tips/tips-events.js`).
@@ -7,12 +7,12 @@
@@ -7,12 +7,12 @@
"adr": "ADR-012",
"adr": "ADR-012",
"authoritative": false,
"authoritative": false,
"deployed": true,
"deployed": true,
- "deployment": "Launched 2026-10-17 at https://openvibe.tips (openvibe-contracts 0.200.0 made Tips live; vhost deploy/nginx/openvibe.tips.conf installed): deployed with `sudo ovhost deploy tips`, /opt/openvibe.tips, unit openvibe-tips, 127.0.0.1:4610 behind nginx. Principal tips; Events subscriptions billing.transaction.* and billing.receipt.* -> /internal/events; TIPS_CHAT_ADAPTER=chat (chat lines and alerts through OpenVibe.Chat). OpenVibe.Live subscribes to tips.interaction.ready for its channel goal and tip history.",
+ "deployment": "Launched 2026-10-17 at https://openvibe.tips (openvibe-contracts 0.200.0 made Tips live; vhost deploy/nginx/openvibe.tips.conf installed): deployed with `sudo ovhost deploy tips`, /opt/openvibe.tips, unit openvibe-tips, 127.0.0.1:4610 behind nginx. Principal tips; Events subscriptions billing.transaction.* and billing.receipt.* -> /internal/events; TIPS_CHAT_ADAPTER=chat (chat lines and alerts through OpenVibe.Chat). OpenVibe.Live subscribes to tips.interaction.ready for its channel goal and tip history. TIPS_POWERCHAT_LINK_TEMPLATE turns Billing's pcorder: ref into PowerChat's canonical tip link on the site account (since 2026-10-17).",
"database": "PostgreSQL 18 through PgBouncer (transaction mode) as the system of record, Valkey 9 for shared state (per-actor limits, overlay fan-out, overlay stream slots), ADR-035: database ov_tips from OpenVibe.Host's data role, schema in migrations/ (0001_initial expand, 0002_drop_legacy_import contract), async on openvibe-sdk/db v0.28.0, money paths serializable with row locks, PostgreSQL outbox and inbox.",
"database": "PostgreSQL 18 through PgBouncer (transaction mode) as the system of record, Valkey 9 for shared state (per-actor limits, overlay fan-out, overlay stream slots), ADR-035: database ov_tips from OpenVibe.Host's data role, schema in migrations/ (0001_initial expand, 0002_drop_legacy_import contract), async on openvibe-sdk/db v0.28.0, money paths serializable with row locks, PostgreSQL outbox and inbox.",
"contracts": "openvibe-contracts v0.200.0",
"contracts": "openvibe-contracts v0.200.0",
"sdk": "openvibe-sdk v0.50.1",
"sdk": "openvibe-sdk v0.50.1",
"shared": "openvibe-shared v4.3.0",
"shared": "openvibe-shared v4.3.0",
- "notes": "Runtime, API, SSR pages, overlays, the Billing settlement consumer and the events outbox are built, tested and deployed, together with /metrics (loopback only), truthful /api/ready (Billing and Events checks), supporter privacy (anonymous, hidden amount, private message), goal and supporter-page settings, export and erasure (tips.interaction.erased), moderation (word filter, hide/show, invited moderators, tips.interaction.moderated) and per-actor limits. Capabilities (18 tips.*) and payload schemas are in openvibe-contracts. Billing is the money ledger since the cutover (2026-10-17). A written internal threat review (docs/threat-review.md) with its fixes and test/security.test.js. Paid sounds (creators upload up to 12, supporters pay to play one on the overlay) since 2026-10-17. Not done: an independent security review; a PowerChat checkout link for tips made on openvibe.tips (TIPS_POWERCHAT_LINK_TEMPLATE unset: supporters there pay with Vibes credit).",
+ "notes": "Runtime, API, SSR pages, overlays, the Billing settlement consumer and the events outbox are built, tested and deployed, together with /metrics (loopback only), truthful /api/ready (Billing and Events checks), supporter privacy (anonymous, hidden amount, private message), goal and supporter-page settings, export and erasure (tips.interaction.erased), moderation (word filter, hide/show, invited moderators, tips.interaction.moderated) and per-actor limits. Capabilities (18 tips.*) and payload schemas are in openvibe-contracts. Billing is the money ledger since the cutover (2026-10-17). A written internal threat review (docs/threat-review.md) with its fixes and test/security.test.js. Paid sounds (creators upload up to 12, supporters pay to play one on the overlay) since 2026-10-17. Not done: an independent security review.",
"features": [
"features": [
"tips, paid messages, TTS and media requests settled by OpenVibe.Billing (never Tips' own money)",
"tips, paid messages, TTS and media requests settled by OpenVibe.Billing (never Tips' own money)",
"paid sounds: creators upload up to 12 sounds, supporters pay to play one on the overlay, chat names it",
"paid sounds: creators upload up to 12 sounds, supporters pay to play one on the overlay, chat names it",