openvibers/openvibe.events Commits
Events: the retired events.openvibe.network vhost is deleted (plan T7) (#39)
Changes
@@@ -11,8 +11,7 @@ HOST=127.0.0.1NODE_ENV=development# The API origin (plan T7): everything Events names about itself — Location headers, realtime URLs,# limits.json links, llms.txt/sitemap, the home's examples — uses it; defaults to https://openvibe.events--# in production, to http://localhost:PORT otherwise. events.openvibe.network answers until every client--# moves, then redirects (308).++# in production, to http://localhost:PORT otherwise.#BASE_URL=https://openvibe.events# The product origin; defaults to BASE_URL (openvibe.events is the API and product origin, plan T7).#EVENTS_SITE_URL=https://openvibe.events@@@ -3,7 +3,7 @@> Durable events, subscriptions, delivery, retry, dead letters and replay for the network.**Status:** alpha (roadmap Wave 3), deployed on `openvibe-ovh` (unit `openvibe-events`, 127.0.0.1:4300, public at `https://openvibe.events`). Live (`live.stream.*`), Media, Chat, Games, Network and OpenRestream publish to it in production, and every consumer webhook requires signature v2. Media's completion events reach Live through Events (`/internal/media-events`; Live keeps the older `/internal/media-webhook` during the transition), and the shared notification bell can follow `network.notification.created` over the realtime stream with a Network ticket.--**Domain:** `openvibe.events` is the API and product origin (plan T7): the JSON API, the realtime gateway (ADR-005 put Realtime inside Events; `realtime.openvibe.network` has no runtime of its own), the home page and its `robots.txt`/`sitemap.xml`/`llms.txt`. `events.openvibe.network` answers 308 to the same path on openvibe.events.++**Domain:** `openvibe.events` is the API and product origin (plan T7): the JSON API, the realtime gateway (ADR-005 put Realtime inside Events; `realtime.openvibe.network` has no runtime of its own), the home page and its `robots.txt`/`sitemap.xml`/`llms.txt`. The old `events.openvibe.network` address was retired on 2026-10-10.**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §6 and §6.3.**License:** AGPL-3.0 (same as every OpenVibe service).@@@ -357,8 +357,8 @@ fast-forward `/opt/openvibe.events`, install on a lockfile change, restart, waitThe unit is `openvibe-events.service` on `127.0.0.1:4300`, the env file `/etc/openvibe/events.env`. The database is`ov_events` on the host's data role (`sudo /opt/openvibe.host/roles/data/add-service.sh events` writes its settings); therelease migrates it at boot. nginx serves `openvibe.events`, the API and product origin, from--[deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf); `events.openvibe.network` answers 308 to the--same path there ([deploy/nginx/events.openvibe.network.conf](deploy/nginx/events.openvibe.network.conf)). ovhost treats open++[deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf) (the old `events.openvibe.network` address was retired++on 2026-10-10). ovhost treats openrealtime connections as a report-only drain, so `--wait-idle` waits for them.Rollback: ovhost puts the previous sha back by itself when `/api/ready` does not answer 2xx after therestart; afterwards `sudo ovhost rollback events --to <sha>`. Migrations only add tables and columns.@@@ -21,7 +21,7 @@],"capabilitiesRegistered": true,"deployed": true,-- "deployment": "Deployed with `sudo ovhost deploy events`: /opt/openvibe.events, unit openvibe-events, 127.0.0.1:4300; public at https://openvibe.events (plan T7: the API and product origin; realtime SSE, health, token-guarded /api/v1/events, /api/v1/subscriptions, /api/v1/checkpoints; /api/v1/deliveries host-local; events.openvibe.network answers the same surface until every client moves, then redirects 308); real traffic since 2026-09-23 (Live, Media, Chat, Games, Network and OpenRestream publish; on 2026-09-23 8 subscriptions, held by Search, Tips, VIP, News and Reviews); restore drill passed 2026-09-23",++ "deployment": "Deployed with `sudo ovhost deploy events`: /opt/openvibe.events, unit openvibe-events, 127.0.0.1:4300; public at https://openvibe.events (plan T7: the API and product origin; realtime SSE, health, token-guarded /api/v1/events, /api/v1/subscriptions, /api/v1/checkpoints; /api/v1/deliveries host-local; the old events.openvibe.network address was retired on 2026-10-10); real traffic since 2026-09-23 (Live, Media, Chat, Games, Network and OpenRestream publish; on 2026-09-23 8 subscriptions, held by Search, Tips, VIP, News and Reviews); restore drill passed 2026-09-23","features": ["durable event store with the canonical envelope","subscriptions with signed webhook delivery (v1 and v2), retry, dead letters and replay",ddeleted file mode 100644@@@ -1,38 +0,0 @@--## ═══════════════════════════════════════════════════════════════--## events.openvibe.network — Nginx Configuration (REFERENCE)--##--## Deployed to /etc/nginx/sites-available/events.openvibe.network.conf — keep them in sync,--## and reload nginx after changing it.--##--## OpenVibe.Events' API, realtime stream and product home are on https://openvibe.events--## (deploy/nginx/openvibe.events.conf, plan T7). This old name answers 308 to the same path and query--## there: a 308 keeps the method and the body, so a POST to /api/v1/events is replayed as a POST.--## Services on this host never come through here: they call 127.0.0.1:4300 directly.--## ═══════════════════════════════════════════════════════════════----server {-- listen 80;-- listen [::]:80;-- server_name events.openvibe.network;---- location /.well-known/acme-challenge/ { root /var/www/certbot; }-- location / { return 308 https://openvibe.events$request_uri; }--}----server {-- listen 443 ssl;-- listen [::]:443 ssl;-- http2 on;-- server_name events.openvibe.network;---- ssl_certificate /etc/letsencrypt/live/openvibe.network/fullchain.pem;-- ssl_certificate_key /etc/letsencrypt/live/openvibe.network/privkey.pem;-- ssl_protocols TLSv1.2 TLSv1.3;---- access_log /var/log/nginx/events.openvibe.network.access.log;-- error_log /var/log/nginx/events.openvibe.network.error.log;---- add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;---- location / { return 308 https://openvibe.events$request_uri; }--}@@@ -6,9 +6,8 @@#### openvibe.events is the API and product origin (plan T7): the same Node service (port 4300,## systemd unit openvibe-events) answers the product home and its discovery files, the--## token-guarded JSON API, the realtime gateway and health, all here. events.openvibe.network--## keeps answering the same surface unchanged (deploy/nginx/events.openvibe.network.conf) until--## every client has moved; a later change turns it into a redirect (308) to this host.++## token-guarded JSON API, the realtime gateway and health, all here. The old++## events.openvibe.network address was retired on 2026-10-10 (its last service caller stopped 09-30).#### The Node service (port 4300) answers here:## / the product home (server/home.js) for a browser, the text/plain API index otherwise@@@ -26,7 +25,7 @@## /internal/ host-local service endpoints, refused here## ═══════════════════════════════════════════════════════════════--# Distinct zone names: events.openvibe.network.conf declares its own and both files load in one config.++# Zone names carry this site's prefix (ovevents_apex_*) so they never collide with another vhost's in one config.limit_req_zone $binary_remote_addr zone=ovevents_apex_connect:10m rate=2r/s;limit_conn_zone $binary_remote_addr zone=ovevents_apex_streams:10m;limit_req_zone $binary_remote_addr zone=ovevents_apex_api:10m rate=20r/s;@@@ -81,8 +81,8 @@ function load(env = process.env) {const port = int(env.PORT, 4300);const maxInflight = int(env.EVENTS_MAX_INFLIGHT, 20);const prefixes = sourcePrefixes(env);-- // openvibe.events is the API origin and the product origin (plan T7); events.openvibe.network answers-- // until every client moves, then redirects (308). Everything Events names about itself uses this.++ // openvibe.events is the API origin and the product origin (plan T7; the old events.openvibe.network address was++ // retired on 2026-10-10). Everything Events names about itself uses this.const baseUrl = (env.BASE_URL || (isProduction ? 'https://openvibe.events' : `http://localhost:${port}`)).replace(/\/$/, '');return {port,@@@ -166,10 +166,7 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no rediassert.match(catchAll, /limit_except GET HEAD \{ deny all; \}/, 'the catch-all only passes GET and HEAD');assert.match(catchAll, /proxy_pass http:\/\/127\.0\.0\.1:4300;/, 'and lets the app answer (favicon, 404 page)');assert.ok(!/location \/ \{ return 404; \}/.test(conf), 'nginx\'s bare 404 page (no lang) is gone');-- const old = fs.readFileSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf'), 'utf8')-- .split('\n').filter((l) => !/^\s*#/.test(l)).join('\n');-- assert.ok(!old.includes('proxy_pass'), 'events.openvibe.network serves nothing itself');-- assert.strictEqual((old.match(/return 308 https:\/\/openvibe\.events\$request_uri;/g) || []).length, 2, 'HTTP and HTTPS answer 308 to openvibe.events');++ assert.ok(!fs.existsSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf')), 'the retired events.openvibe.network vhost is gone (plan T7)');assert.ok(conf.includes('return 301 https://openvibe.events$request_uri;'), ':80 and www reach the apex');});
@@ -11,8 +11,7 @@ HOST=127.0.0.1
@@ -11,8 +11,7 @@ HOST=127.0.0.1
NODE_ENV=development
NODE_ENV=development
# The API origin (plan T7): everything Events names about itself — Location headers, realtime URLs,
# The API origin (plan T7): everything Events names about itself — Location headers, realtime URLs,
# limits.json links, llms.txt/sitemap, the home's examples — uses it; defaults to https://openvibe.events
# limits.json links, llms.txt/sitemap, the home's examples — uses it; defaults to https://openvibe.events
-# in production, to http://localhost:PORT otherwise. events.openvibe.network answers until every client
-# moves, then redirects (308).
+# in production, to http://localhost:PORT otherwise.
#BASE_URL=https://openvibe.events
#BASE_URL=https://openvibe.events
# The product origin; defaults to BASE_URL (openvibe.events is the API and product origin, plan T7).
# The product origin; defaults to BASE_URL (openvibe.events is the API and product origin, plan T7).
#EVENTS_SITE_URL=https://openvibe.events
#EVENTS_SITE_URL=https://openvibe.events
@@ -3,7 +3,7 @@
@@ -3,7 +3,7 @@
> Durable events, subscriptions, delivery, retry, dead letters and replay for the network.
> Durable events, subscriptions, delivery, retry, dead letters and replay for the network.
**Status:** alpha (roadmap Wave 3), deployed on `openvibe-ovh` (unit `openvibe-events`, 127.0.0.1:4300, public at `https://openvibe.events`). Live (`live.stream.*`), Media, Chat, Games, Network and OpenRestream publish to it in production, and every consumer webhook requires signature v2. Media's completion events reach Live through Events (`/internal/media-events`; Live keeps the older `/internal/media-webhook` during the transition), and the shared notification bell can follow `network.notification.created` over the realtime stream with a Network ticket.
**Status:** alpha (roadmap Wave 3), deployed on `openvibe-ovh` (unit `openvibe-events`, 127.0.0.1:4300, public at `https://openvibe.events`). Live (`live.stream.*`), Media, Chat, Games, Network and OpenRestream publish to it in production, and every consumer webhook requires signature v2. Media's completion events reach Live through Events (`/internal/media-events`; Live keeps the older `/internal/media-webhook` during the transition), and the shared notification bell can follow `network.notification.created` over the realtime stream with a Network ticket.
-**Domain:** `openvibe.events` is the API and product origin (plan T7): the JSON API, the realtime gateway (ADR-005 put Realtime inside Events; `realtime.openvibe.network` has no runtime of its own), the home page and its `robots.txt`/`sitemap.xml`/`llms.txt`. `events.openvibe.network` answers 308 to the same path on openvibe.events.
+**Domain:** `openvibe.events` is the API and product origin (plan T7): the JSON API, the realtime gateway (ADR-005 put Realtime inside Events; `realtime.openvibe.network` has no runtime of its own), the home page and its `robots.txt`/`sitemap.xml`/`llms.txt`. The old `events.openvibe.network` address was retired on 2026-10-10.
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §6 and §6.3.
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §6 and §6.3.
**License:** AGPL-3.0 (same as every OpenVibe service).
**License:** AGPL-3.0 (same as every OpenVibe service).
@@ -357,8 +357,8 @@ fast-forward `/opt/openvibe.events`, install on a lockfile change, restart, wait
@@ -357,8 +357,8 @@ fast-forward `/opt/openvibe.events`, install on a lockfile change, restart, wait
The unit is `openvibe-events.service` on `127.0.0.1:4300`, the env file `/etc/openvibe/events.env`. The database is
The unit is `openvibe-events.service` on `127.0.0.1:4300`, the env file `/etc/openvibe/events.env`. The database is
`ov_events` on the host's data role (`sudo /opt/openvibe.host/roles/data/add-service.sh events` writes its settings); the
`ov_events` on the host's data role (`sudo /opt/openvibe.host/roles/data/add-service.sh events` writes its settings); the
release migrates it at boot. nginx serves `openvibe.events`, the API and product origin, from
release migrates it at boot. nginx serves `openvibe.events`, the API and product origin, from
-[deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf); `events.openvibe.network` answers 308 to the
-same path there ([deploy/nginx/events.openvibe.network.conf](deploy/nginx/events.openvibe.network.conf)). ovhost treats open
+[deploy/nginx/openvibe.events.conf](deploy/nginx/openvibe.events.conf) (the old `events.openvibe.network` address was retired
+on 2026-10-10). ovhost treats open
realtime connections as a report-only drain, so `--wait-idle` waits for them.
realtime connections as a report-only drain, so `--wait-idle` waits for them.
Rollback: ovhost puts the previous sha back by itself when `/api/ready` does not answer 2xx after the
Rollback: ovhost puts the previous sha back by itself when `/api/ready` does not answer 2xx after the
restart; afterwards `sudo ovhost rollback events --to <sha>`. Migrations only add tables and columns.
restart; afterwards `sudo ovhost rollback events --to <sha>`. Migrations only add tables and columns.
@@ -21,7 +21,7 @@
@@ -21,7 +21,7 @@
],
],
"capabilitiesRegistered": true,
"capabilitiesRegistered": true,
"deployed": true,
"deployed": true,
- "deployment": "Deployed with `sudo ovhost deploy events`: /opt/openvibe.events, unit openvibe-events, 127.0.0.1:4300; public at https://openvibe.events (plan T7: the API and product origin; realtime SSE, health, token-guarded /api/v1/events, /api/v1/subscriptions, /api/v1/checkpoints; /api/v1/deliveries host-local; events.openvibe.network answers the same surface until every client moves, then redirects 308); real traffic since 2026-09-23 (Live, Media, Chat, Games, Network and OpenRestream publish; on 2026-09-23 8 subscriptions, held by Search, Tips, VIP, News and Reviews); restore drill passed 2026-09-23",
+ "deployment": "Deployed with `sudo ovhost deploy events`: /opt/openvibe.events, unit openvibe-events, 127.0.0.1:4300; public at https://openvibe.events (plan T7: the API and product origin; realtime SSE, health, token-guarded /api/v1/events, /api/v1/subscriptions, /api/v1/checkpoints; /api/v1/deliveries host-local; the old events.openvibe.network address was retired on 2026-10-10); real traffic since 2026-09-23 (Live, Media, Chat, Games, Network and OpenRestream publish; on 2026-09-23 8 subscriptions, held by Search, Tips, VIP, News and Reviews); restore drill passed 2026-09-23",
"features": [
"features": [
"durable event store with the canonical envelope",
"durable event store with the canonical envelope",
"subscriptions with signed webhook delivery (v1 and v2), retry, dead letters and replay",
"subscriptions with signed webhook delivery (v1 and v2), retry, dead letters and replay",
deleted file mode 100644
deleted file mode 100644
@@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
-## ═══════════════════════════════════════════════════════════════
-## events.openvibe.network — Nginx Configuration (REFERENCE)
-##
-## Deployed to /etc/nginx/sites-available/events.openvibe.network.conf — keep them in sync,
-## and reload nginx after changing it.
-##
-## OpenVibe.Events' API, realtime stream and product home are on https://openvibe.events
-## (deploy/nginx/openvibe.events.conf, plan T7). This old name answers 308 to the same path and query
-## there: a 308 keeps the method and the body, so a POST to /api/v1/events is replayed as a POST.
-## Services on this host never come through here: they call 127.0.0.1:4300 directly.
-## ═══════════════════════════════════════════════════════════════
-
-server {
- listen 80;
- listen [::]:80;
- server_name events.openvibe.network;
-
- location /.well-known/acme-challenge/ { root /var/www/certbot; }
- location / { return 308 https://openvibe.events$request_uri; }
-}
-
-server {
- listen 443 ssl;
- listen [::]:443 ssl;
- http2 on;
- server_name events.openvibe.network;
-
- ssl_certificate /etc/letsencrypt/live/openvibe.network/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/openvibe.network/privkey.pem;
- ssl_protocols TLSv1.2 TLSv1.3;
-
- access_log /var/log/nginx/events.openvibe.network.access.log;
- error_log /var/log/nginx/events.openvibe.network.error.log;
-
- add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
-
- location / { return 308 https://openvibe.events$request_uri; }
-}
@@ -6,9 +6,8 @@
@@ -6,9 +6,8 @@
##
##
## openvibe.events is the API and product origin (plan T7): the same Node service (port 4300,
## openvibe.events is the API and product origin (plan T7): the same Node service (port 4300,
## systemd unit openvibe-events) answers the product home and its discovery files, the
## systemd unit openvibe-events) answers the product home and its discovery files, the
-## token-guarded JSON API, the realtime gateway and health, all here. events.openvibe.network
-## keeps answering the same surface unchanged (deploy/nginx/events.openvibe.network.conf) until
-## every client has moved; a later change turns it into a redirect (308) to this host.
+## token-guarded JSON API, the realtime gateway and health, all here. The old
+## events.openvibe.network address was retired on 2026-10-10 (its last service caller stopped 09-30).
##
##
## The Node service (port 4300) answers here:
## The Node service (port 4300) answers here:
## / the product home (server/home.js) for a browser, the text/plain API index otherwise
## / the product home (server/home.js) for a browser, the text/plain API index otherwise
@@ -26,7 +25,7 @@
@@ -26,7 +25,7 @@
## /internal/ host-local service endpoints, refused here
## /internal/ host-local service endpoints, refused here
## ═══════════════════════════════════════════════════════════════
## ═══════════════════════════════════════════════════════════════
-# Distinct zone names: events.openvibe.network.conf declares its own and both files load in one config.
+# Zone names carry this site's prefix (ovevents_apex_*) so they never collide with another vhost's in one config.
limit_req_zone $binary_remote_addr zone=ovevents_apex_connect:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=ovevents_apex_connect:10m rate=2r/s;
limit_conn_zone $binary_remote_addr zone=ovevents_apex_streams:10m;
limit_conn_zone $binary_remote_addr zone=ovevents_apex_streams:10m;
limit_req_zone $binary_remote_addr zone=ovevents_apex_api:10m rate=20r/s;
limit_req_zone $binary_remote_addr zone=ovevents_apex_api:10m rate=20r/s;
@@ -81,8 +81,8 @@ function load(env = process.env) {
@@ -81,8 +81,8 @@ function load(env = process.env) {
const port = int(env.PORT, 4300);
const port = int(env.PORT, 4300);
const maxInflight = int(env.EVENTS_MAX_INFLIGHT, 20);
const maxInflight = int(env.EVENTS_MAX_INFLIGHT, 20);
const prefixes = sourcePrefixes(env);
const prefixes = sourcePrefixes(env);
- // openvibe.events is the API origin and the product origin (plan T7); events.openvibe.network answers
- // until every client moves, then redirects (308). Everything Events names about itself uses this.
+ // openvibe.events is the API origin and the product origin (plan T7; the old events.openvibe.network address was
+ // retired on 2026-10-10). Everything Events names about itself uses this.
const baseUrl = (env.BASE_URL || (isProduction ? 'https://openvibe.events' : `http://localhost:${port}`)).replace(/\/$/, '');
const baseUrl = (env.BASE_URL || (isProduction ? 'https://openvibe.events' : `http://localhost:${port}`)).replace(/\/$/, '');
return {
return {
port,
port,
@@ -166,10 +166,7 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
@@ -166,10 +166,7 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
assert.match(catchAll, /limit_except GET HEAD \{ deny all; \}/, 'the catch-all only passes GET and HEAD');
assert.match(catchAll, /limit_except GET HEAD \{ deny all; \}/, 'the catch-all only passes GET and HEAD');
assert.match(catchAll, /proxy_pass http:\/\/127\.0\.0\.1:4300;/, 'and lets the app answer (favicon, 404 page)');
assert.match(catchAll, /proxy_pass http:\/\/127\.0\.0\.1:4300;/, 'and lets the app answer (favicon, 404 page)');
assert.ok(!/location \/ \{ return 404; \}/.test(conf), 'nginx\'s bare 404 page (no lang) is gone');
assert.ok(!/location \/ \{ return 404; \}/.test(conf), 'nginx\'s bare 404 page (no lang) is gone');
- const old = fs.readFileSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf'), 'utf8')
- .split('\n').filter((l) => !/^\s*#/.test(l)).join('\n');
- assert.ok(!old.includes('proxy_pass'), 'events.openvibe.network serves nothing itself');
- assert.strictEqual((old.match(/return 308 https:\/\/openvibe\.events\$request_uri;/g) || []).length, 2, 'HTTP and HTTPS answer 308 to openvibe.events');
+ assert.ok(!fs.existsSync(path.join(__dirname, '..', 'deploy', 'nginx', 'events.openvibe.network.conf')), 'the retired events.openvibe.network vhost is gone (plan T7)');
assert.ok(conf.includes('return 301 https://openvibe.events$request_uri;'), ':80 and www reach the apex');
assert.ok(conf.includes('return 301 https://openvibe.events$request_uri;'), ':80 and www reach the apex');
});
});