openvibers/openvibe.deals Commits

The SQLite era is gone (on PostgreSQL since 2026-09-28; no compatibility kept): the one-time migrate-to-postgres script, *_DB_PATH settings (config, .env.example, systemd unit, test helpers), the unused better-sqlite3 dependency and its lockfile entries, and docs, docstrings and STATUS lines about SQLite or its rollback window. Reviewed independently; its blockers (an edited applied migration, the lockfile) are resolved here, Host's inventory follow-up is separate. npm test 14/14 test files passed.

OP OpenVibers committed 29 Sept 2026 · 0fe654574a · 17 files, +96 −81


Changes

ddiff --git a/.env.example b/.env.example
iindex f1d05bc..491c1ee 100644
---- a/.env.example
++++ b/.env.example
@@@ -17,24 +17,13 @@ TRUST_PROXY=2
#DEALS_LIMITS_MINUTE=120
#DEALS_LIMITS_HOUR=3000
--# SQLite database (production unit: /var/lib/openvibe-deals/deals.db)
# PostgreSQL (ADR-035), written by OpenVibe.Host roles/data/add-service.sh deals: the runtime role through PgBouncer,
--# the owner on a direct connection (migrations and the one-time import), and Valkey (shared limit counters).
++# the owner on a direct connection (migrations), and Valkey (shared limit counters).
# Without DATABASE_URL, development uses an embedded PGlite database in data/pglite.
DATABASE_URL=
DATABASE_DIRECT_URL=
VALKEY_URL=
VALKEY_PREFIX=
--# The SQLite file of releases before PostgreSQL: read once by scripts/migrate-to-postgres.js.
--# PostgreSQL (ADR-035), written by OpenVibe.Host roles/data/add-service.sh deals: the runtime role through PgBouncer,
--# the owner on a direct connection (migrations and the one-time import), and Valkey (shared limit counters).
--# Without DATABASE_URL, development uses an embedded PGlite database in data/pglite.
--DATABASE_URL=
--DATABASE_DIRECT_URL=
--VALKEY_URL=
--VALKEY_PREFIX=
--# The SQLite file of releases before PostgreSQL: read once by scripts/migrate-to-postgres.js.
--DEALS_DB_PATH=./data/deals.db
# OpenVibe.Network — SSO (OAuth2), JWKS, client-credentials tokens
OV_NETWORK_URL=https://openvibe.network
ddiff --git a/.gitignore b/.gitignore
iindex 0f84c2e..4c6243c 100644
---- a/.gitignore
++++ b/.gitignore
@@@ -4,9 +4,6 @@ dist/
.env
.env.*
!.env.example
--*.db
--*.db-wal
--*.db-shm
*.log
*.pem
*.key
ddiff --git a/README.md b/README.md
iindex 7ccefbf..20b5d93 100644
---- a/README.md
++++ b/README.md
@@@ -374,9 +374,7 @@ Production deploys with `sudo ovhost deploy deals` on the host (strategy `git-ch
fast-forward `/opt/openvibe.deals`, install on a lockfile change, restart, wait for `/api/ready`).
The unit is `openvibe-deals.service` on `127.0.0.1:4840`, the env file `/etc/openvibe/deals.env`. The database is
`ov_deals` on the host's data role (`sudo /opt/openvibe.host/roles/data/add-service.sh deals` writes its settings); the
--release migrates it at boot. The one-time move from SQLite is `scripts/migrate-to-postgres.js` (openvibe-sdk
--`runSqliteMigration`, with a `--pglite` rehearsal mode), run while the service is stopped; the old
--`/var/lib/openvibe-deals/deals.db` stays read-only for 7 days as the rollback.
++release migrates it at boot.
Rollback: ovhost puts the previous sha back by itself when `/api/ready` does not answer 2xx after the
restart; afterwards `sudo ovhost rollback deals --to <sha>`. Migrations only add tables and columns.
@@@ -393,7 +391,7 @@ First install (done once; kept for a rebuild):
`deals.env`), and add the grants listed above.
3. **Sources:** register and enable a `deals`-category source once a person has checked its terms.
4. **Search:** nothing to do unless `SEARCH_EVENT_OWNERS` is overridden there (the default includes `deals`).
--5. **systemd:** install `deploy/systemd/openvibe-deals.service` (port 4840, `StateDirectory=openvibe-deals`).
++5. **systemd:** install `deploy/systemd/openvibe-deals.service` (port 4840).
6. **nginx:** install `deploy/nginx/openvibe.deals.conf`. `/metrics` and `/internal/` are never proxied.
7. **Events subscription:** `node scripts/subscribe.js` (optional — the importer polls anyway).
8. **Contracts:** done: the capabilities and manifest are released in openvibe-contracts v0.23.0,
ddiff --git a/deploy/systemd/openvibe-deals.service b/deploy/systemd/openvibe-deals.service
iindex 630fde2..7226b34 100644
---- a/deploy/systemd/openvibe-deals.service
++++ b/deploy/systemd/openvibe-deals.service
@@@ -23,9 +23,6 @@ NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
--# Deals' own database lives in /var/lib/openvibe-deals; the code tree stays read-only.
--StateDirectory=openvibe-deals
--Environment=DEALS_DB_PATH=/var/lib/openvibe-deals/deals.db
[Install]
WantedBy=multi-user.target
ddiff --git a/docs/service-manifest-proposal.json b/docs/service-manifest-proposal.json
iindex 222e7f1..c0daf2b 100644
---- a/docs/service-manifest-proposal.json
++++ b/docs/service-manifest-proposal.json
@@@ -44,5 +44,5 @@
"namespacesOwned": [
"deals.*"
],
-- "notes": "Port 4840. Owns deal_products, deal_product_aliases, deal_offers, deal_offer_sources, deal_votes, deal_hotness_snapshots, deal_watches, deal_price_observations, deal_flags (+ deal_stores) in its own SQLite. Consumes OpenVibe.Network (SSO, identity.subject.resolve), OpenVibe.Sources (sources.item.read; sources.item.* events only wake the pull), OpenVibe.Community (community.comment.write, community.comment.moderate) and publishes through OpenVibe.Events (events.event.publish); OpenVibe.Search reads deals.index_document.* from Events; deals.watch.matched is for Network notifications (consumer not built yet)."
++ "notes": "Port 4840. Owns deal_products, deal_product_aliases, deal_offers, deal_offer_sources, deal_votes, deal_hotness_snapshots, deal_watches, deal_price_observations, deal_flags (+ deal_stores) in its own PostgreSQL database. Consumes OpenVibe.Network (SSO, identity.subject.resolve), OpenVibe.Sources (sources.item.read; sources.item.* events only wake the pull), OpenVibe.Community (community.comment.write, community.comment.moderate) and publishes through OpenVibe.Events (events.event.publish); OpenVibe.Search reads deals.index_document.* from Events; deals.watch.matched is for Network notifications (consumer not built yet)."
}
ddiff --git a/package-lock.json b/package-lock.json
iindex 5cefec1..ecd016d 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -9,7 +9,6 @@
"version": "0.1.0",
"license": "AGPL-3.0-only",
"dependencies": {
-- "better-sqlite3": "^11.10.0",
"cookie-parser": "^1.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
@@@ -113,7 +112,9 @@
"url": "https://feross.org/support"
}
],
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/better-sqlite3": {
"version": "11.10.0",
@@@ -121,6 +122,8 @@
"integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==",
"hasInstallScript": true,
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"bindings": "^1.5.0",
"prebuild-install": "^7.1.1"
@@@ -131,6 +134,8 @@
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"file-uri-to-path": "1.0.0"
}
@@@ -140,6 +145,8 @@
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@@@ -189,6 +196,8 @@
}
],
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
@@@ -242,7 +251,9 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-- "license": "ISC"
++ "license": "ISC",
++ "optional": true,
++ "peer": true
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
@@@ -316,6 +327,8 @@
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"mimic-response": "^3.1.0"
},
@@@ -331,6 +344,8 @@
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"engines": {
"node": ">=4.0.0"
}
@@@ -368,6 +383,8 @@
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
++ "optional": true,
++ "peer": true,
"engines": {
"node": ">=8"
}
@@@ -427,6 +444,8 @@
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"once": "^1.4.0"
}
@@@ -481,6 +500,8 @@
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"license": "(MIT OR WTFPL)",
++ "optional": true,
++ "peer": true,
"engines": {
"node": ">=6"
}
@@@ -572,7 +593,9 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/finalhandler": {
"version": "1.3.2",
@@@ -614,7 +637,9 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/function-bind": {
"version": "1.1.2",
@@@ -666,7 +691,9 @@
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/gopd": {
"version": "1.2.0",
@@@ -766,7 +793,9 @@
"url": "https://feross.org/support"
}
],
-- "license": "BSD-3-Clause"
++ "license": "BSD-3-Clause",
++ "optional": true,
++ "peer": true
},
"node_modules/inherits": {
"version": "2.0.4",
@@@ -778,7 +807,9 @@
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-- "license": "ISC"
++ "license": "ISC",
++ "optional": true,
++ "peer": true
},
"node_modules/iovalkey": {
"version": "0.4.0",
@@@ -1015,6 +1046,8 @@
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"engines": {
"node": ">=10"
},
@@@ -1027,6 +1060,8 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@@ -1035,7 +1070,9 @@
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/ms": {
"version": "2.0.0",
@@@ -1047,7 +1084,9 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/negotiator": {
"version": "0.6.3",
@@@ -1063,6 +1102,8 @@
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz",
"integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"semver": "^7.3.5"
},
@@@ -1099,6 +1140,8 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
++ "optional": true,
++ "peer": true,
"dependencies": {
"wrappy": "1"
}
@@@ -1324,6 +1367,8 @@
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
@@@ -1367,6 +1412,8 @@
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
"integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@@ -1417,6 +1464,8 @@
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
++ "optional": true,
++ "peer": true,
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@@@ -1432,6 +1481,8 @@
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@@ -1650,7 +1701,9 @@
"url": "https://feross.org/support"
}
],
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/simple-get": {
"version": "4.0.1",
@@@ -1671,6 +1724,8 @@
}
],
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
@@@ -1706,6 +1761,8 @@
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"safe-buffer": "~5.2.0"
}
@@@ -1715,6 +1772,8 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@@ -1724,6 +1783,8 @@
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz",
"integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
@@@ -1736,6 +1797,8 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"license": "MIT",
++ "optional": true,
++ "peer": true,
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
@@@ -1761,6 +1824,8 @@
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"license": "Apache-2.0",
++ "optional": true,
++ "peer": true,
"dependencies": {
"safe-buffer": "^5.0.1"
},
@@@ -1794,7 +1859,9 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-- "license": "MIT"
++ "license": "MIT",
++ "optional": true,
++ "peer": true
},
"node_modules/utils-merge": {
"version": "1.0.1",
@@@ -1818,7 +1885,9 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
-- "license": "ISC"
++ "license": "ISC",
++ "optional": true,
++ "peer": true
},
"node_modules/xtend": {
"version": "4.0.2",
ddiff --git a/package.json b/package.json
iindex 4644eea..2b8fcec 100644
---- a/package.json
++++ b/package.json
@@@ -20,7 +20,6 @@
"license": "AGPL-3.0-only",
"repository": "github:OpenVibers/OpenVibe.Deals",
"dependencies": {
-- "better-sqlite3": "^11.10.0",
"cookie-parser": "^1.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
ddiff --git a/scripts/migrate-to-postgres.js b/scripts/migrate-to-postgres.js
ddeleted file mode 100644
iindex 0e7bbae..0000000
---- a/scripts/migrate-to-postgres.js
++++ /dev/null
@@@ -1,26 +0,0 @@
--#!/usr/bin/env node
--'use strict';
--/**
-- * The one-time move of Deals's SQLite database (DEALS_DB_PATH) into its PostgreSQL schema (ADR-035; the procedure is
-- * openvibe-sdk docs/migrating-to-postgresql.md, section 6, carried out by openvibe-sdk/db runSqliteMigration).
-- *
-- * node scripts/migrate-to-postgres.js [--sqlite <file>] [--pglite] [--json]
-- *
-- * Applies migrations/ as the owner (DATABASE_DIRECT_URL), copies every table into emptied tables, verifies row counts
-- * and checksums, and exits 1 unless everything verified. The SQLite file is opened read-only. Every table keeps its
-- * name and columns.
-- */
--require('dotenv').config();
--const { runSqliteMigration } = require('openvibe-sdk/db');
--const configLib = require('../server/config');
--const { MIGRATIONS } = require('../server/db');
--
--const TABLES = {};
--
--if (require.main === module) {
-- const config = configLib.load();
-- runSqliteMigration({ service: 'deals', sqlite: config.dbPath, directUrl: config.db.directUrl, migrations: MIGRATIONS, tables: TABLES })
-- .then((code) => process.exit(code), (err) => { console.error(`migrate-to-postgres failed: ${err.message}`); process.exit(1); });
--}
--
--module.exports = { TABLES };
ddiff --git a/server/app.js b/server/app.js
iindex beb62d0..69c0c9b 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -48,7 +48,7 @@ const { assetVersion } = require('./render/layout');
const PUBLIC_DIR = path.join(__dirname, '..', 'public');
const VERSION = require('../package.json').version;
--/** opts: config, dbPath, now (clock), fetchImpl, auth, log, limitsNow (the per-actor limiter's clock, tests) */
++/** opts: config, now (clock), fetchImpl, auth, log, limitsNow (the per-actor limiter's clock, tests) */
async function createApp(opts = {}) {
const config = opts.config || configLib.load();
const log = opts.log || console;
ddiff --git a/server/config.js b/server/config.js
iindex e4c8771..a287691 100644
---- a/server/config.js
++++ b/server/config.js
@@@ -40,8 +40,6 @@ function load(env = process.env) {
// PostgreSQL (ADR-035): DATABASE_URL serves (PgBouncer), DATABASE_DIRECT_URL migrates (owner role).
db: { url: env.DATABASE_URL || '', directUrl: env.DATABASE_DIRECT_URL || '' },
valkey: { url: env.VALKEY_URL || '', prefix: env.VALKEY_PREFIX || 'ov:deals:' },
-- // The SQLite file of releases before the switch: read once by scripts/migrate-to-postgres.js.
-- dbPath: env.DEALS_DB_PATH || './data/deals.db',
// OpenVibe.Network: SSO (OAuth2 authorization server), JWKS, client-credentials tokens.
networkUrl: trim(env.OV_NETWORK_URL || 'https://openvibe.network'),
ddiff --git a/server/domain/limits.js b/server/domain/limits.js
iindex 88fcb9a..a9729c2 100644
---- a/server/domain/limits.js
++++ b/server/domain/limits.js
@@@ -1,7 +1,7 @@
'use strict';
/**
-- * Server-side sliding-window limits kept in SQLite (rate_events), so they hold across restarts and
++ * Server-side sliding-window limits kept in PostgreSQL (rate_events), so they hold across restarts and
* across every route that performs the same action (page forms and the API share them).
*
* limits.check(kind, key, max, windowMs) → throws 429 with retry_after when the window is full
ddiff --git a/server/domain/offers.js b/server/domain/offers.js
iindex f372e3f..a161404 100644
---- a/server/domain/offers.js
++++ b/server/domain/offers.js
@@@ -2,7 +2,7 @@
/**
* Offer writes: submission, edits, observations, expiry, moderation (disable / enable / review) and
-- * duplicate resolution (merge / unmerge). Every write is one SQLite transaction that also writes its
++ * duplicate resolution (merge / unmerge). Every write is one PostgreSQL transaction that also writes its
* events (outbox), its Search documents and, for observations, its watch notifications.
*
* Prices are never edited in place. A price, shipping cost, condition or availability is an
ddiff --git a/server/events/outbox.js b/server/events/outbox.js
iindex 1336a6b..192a965 100644
---- a/server/events/outbox.js
++++ b/server/events/outbox.js
@@@ -16,7 +16,7 @@
* indexEvent), consumed by Search's '*.index_document.*'
* subscription
*
-- * emit() runs inside the SQLite transaction that makes the change, so an event exists if and only
++ * emit() runs inside the PostgreSQL transaction that makes the change, so an event exists if and only
* if its change committed. The relay publishes with Deals' service token (events.event.publish,
* audience openvibe.events) only when EVENTS_URL and OV_OAUTH_CLIENT_SECRET are set; otherwise
* rows wait in event_outbox and /api/ready reports the relay as off.
ddiff --git a/server/http/actor-limits.js b/server/http/actor-limits.js
iindex edcfeed..d697b51 100644
---- a/server/http/actor-limits.js
++++ b/server/http/actor-limits.js
@@@ -5,7 +5,7 @@
*
* The per-address limits in app.js (/api/v1 240 a minute, form posts 60, sign-in) and the per-person
* abuse controls (domain/limits.js: votes an hour, submissions and flags a day, observations an hour,
-- * kept in SQLite) stay and keep deciding what is recorded. These cap requests, refused ones included,
++ * kept in PostgreSQL) stay and keep deciding what is recorded. These cap requests, refused ones included,
* by who makes them, once req.viewer is resolved (auth/viewer.js):
*
* a person user:usr_… (their own token or cookie, named by a service in
ddiff --git a/server/observability.js b/server/observability.js
iindex 89d8acb..08242c9 100644
---- a/server/observability.js
++++ b/server/observability.js
@@@ -2,7 +2,7 @@
/**
* Truthful readiness for GET /api/ready (openvibe-shared/ready, Track O).
*
-- * db required a real query on Deals' SQLite (the nine charter tables answer)
++ * db required a real query on Deals' PostgreSQL database (the nine charter tables answer)
* network_jwks optional the Network signing key has loaded; without it pages and feeds still
* serve, but nobody can sign in and service tokens are refused (503)
* events_relay optional the outbox relay is configured and has no rejected rows; when it is
ddiff --git a/test/helpers/boot.js b/test/helpers/boot.js
iindex b0356f3..9d267c8 100644
---- a/test/helpers/boot.js
++++ b/test/helpers/boot.js
@@@ -8,9 +8,6 @@
* t.events('deals.watch.matched') // envelopes in event_outbox
* t.submit(user, { url, title, price, … }) // a deal through the no-JS form, → offer row
*/
--const fs = require('fs');
--const os = require('os');
--const path = require('path');
const http = require('http');
const { startNetwork, startCommunity, startSources } = require('./mocks');
@@@ -25,13 +22,10 @@ async function boot(opts = {}) {
const network = await startNetwork();
const community = await startCommunity({ network });
const sources = await startSources({ network });
-- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ov-deals-test-'));
-- const dbPath = path.join(dir, 'deals.db');
const clock = opts.clock || makeClock();
const mod = network.addUser('moddy', { display_name: 'Mod', role: 'global_mod' });
const env = {
NODE_ENV: 'test', PORT: '0', BASE_URL: 'https://openvibe.deals', TRUST_PROXY: '1',
-- DEALS_DB_PATH: dbPath,
OV_NETWORK_URL: network.url, OV_NETWORK_INTERNAL_URL: network.url,
OV_OAUTH_CLIENT_ID: 'deals', OV_OAUTH_CLIENT_SECRET: 'shh', COOKIE_SECURE: 'false',
OV_COMMUNITY_URL: 'https://openvibe.community', OV_COMMUNITY_INTERNAL_URL: community.url,
@@@ -45,7 +39,7 @@ async function boot(opts = {}) {
const quiet = { log() {}, warn() {}, error: (...a) => { if (process.env.VERBOSE) console.error(...a); } };
const { createStore } = require('../../server/db');
-- // One database per boot (PGlite, or DEALS_TEST_STORE=pg: the containers); a restart keeps it, like a file did.
++ // One database per boot (PGlite, or DEALS_TEST_STORE=pg: the containers); a restart keeps it.
const testdb = await require('./db').testDb();
let server = null;
let built = null;
@@@ -100,10 +94,10 @@ async function boot(opts = {}) {
function offerJson(slug) { return get(`/d/${slug}.json`).then((r) => r.json().offer); }
const t = {
-- network, community, sources, clock, dbPath, mod, get, events, submit, offerJson, HOUR,
++ network, community, sources, clock, mod, get, events, submit, offerJson, HOUR,
csrf: (user) => require('../../server/auth/forms').csrfToken({ formSecret: env.DEALS_FORM_SECRET }, user),
async restart() { await stop(); await start(); },
-- async close() { await stop(); await testdb.close(); await network.close(); await community.close(); await sources.close(); fs.rmSync(dir, { recursive: true, force: true }); },
++ async close() { await stop(); await testdb.close(); await network.close(); await community.close(); await sources.close(); },
};
await start();
return t;
ddiff --git a/test/run.js b/test/run.js
iindex 9a63709..f232663 100644
---- a/test/run.js
++++ b/test/run.js
@@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
-- * Runs every test/*.test.js in its own process and fails if any fails. They use temp SQLite
++ * Runs every test/*.test.js in its own process and fails if any fails. They use temporary PGlite
* databases and in-process mocks of OpenVibe.Network, Community and Sources; none needs the
* network or a running site.
*