openvibers/openvibe.deals CHANGELOG.md

CHANGELOG.md

main 5.6 KB · 21 lines · markdown

Changelog

Unreleased

  • Sign in with a passkey on Deals' own origin (WebAuthn Related Origin Requests). The signed-out account line offers
    "Use a passkey" only after PublicKeyCredential.getClientCapabilities() reports relatedOrigins; the browser
    ceremony is brokered by POST /auth/passkey/options and /verify (SDK 0.151.0) with Deals' OAuth client, and
    Network verifies the exact origin and RP ID. Browsers without support and people without a key keep the ordinary
    OpenVibe sign-in. server/app.js (relatedPasskeys), server/render/layout.js, public/js/passkey-signin.js.
  • The sitemap cache holds index entries, not page views (memory on the host): /sitemap.xml, /sitemap-<n>.xml and /llms-full.txt kept every offer's and product's full view for DEALS_SITEMAP_TTL_MS — observations, sources, vote tallies and merge members — at ~6.7 KB per offer. On 2026-11-07 that was 667 MB resident (923 MB at measurement, 2 GB peak) for 50,000 offers, the most of any Node service on a 15 GB host that ran out of memory at 02:34. The cache now stores publication.indexEntry / productIndexEntry: the URL, lastmod and indexability decision, plus an /llms-full.txt summary for the first 10,000 indexable offers (the file truncates at 512 KB), ~0.6 KB an offer. Each offer needs two reads (its merge group and the group's latest observation) instead of ten, and listings.indexable() joins the store so no per-offer store lookup is needed; a product's lastmod and freshest observation come from one query. Output is unchanged (same URLs, same order, same lastmods, same gate). test/memory-budget.test.js boots the app on a 2,500-offer catalog, builds the sitemaps and runs one Sources import: the heap grows at most 12 MB past boot (measured 3.5 MB; the old full-view cache measured 12.8 MB at 2,000 offers) and stays under 200 MB overall.
  • Imported deals become searchable (the automatic review of imports): an offer imported from a configured feed source is checked when it is imported and passes when its link is https and points at that source's retailer domain, its title is not empty and at most 300 characters, its price is a positive number with a currency, it has not expired and it states none of the blocked/adult terms. A pass sets review_state = auto_approved (published, indexable, reviewed_by = system:import-checks); a fail stays pending with the failed check's name in review_failed_check. Offers people submit by hand keep today's review flow and a moderator can still hide any offer. server/domain/import-review.js, migration 0009_import_auto_review.sql, scripts/backfill-import-review.js (batches of 500, --dry-run, counts only), test/import-review.test.js.
  • llms.txt lists only URLs that answer (SEO-34): the Product JSON link pointed at /sitemaps/products.xml, which no longer exists once the sitemap is an index, and /sitemap.xml itself was a single 24,908-URL file a crawler waited out. The link now names the index, and test/pages.test.js sweeps every URL in the file for an answer below 400.
  • The sitemaps are a bounded index (SEO-16): GET /sitemap.xml (openvibe-shared seo.sitemapIndexXml) names /sitemap-pages.xml and one /sitemap-<n>.xml child per 10,000 catalog URLs — every indexable offer, then every product, in the order the site has always listed them — so no child can pass a crawler's per-file limit and the union of the children is exactly the old catalog sitemap. A chunk number past the last answers 404; robots.txt still names /sitemap.xml and the content type and cache-policy headers are unchanged. test/sitemap-build.test.js seeds 20,005 offers and a product and pins all of it.
  • The front page is curated (server/render/home.js): a search and the site's numbers beside the hero, then editors' picks, hot, just in, ending soon, under $20, categories, shops and crowdfunding, how it works and six questions (FAQPage and ItemList JSON-LD). The hot list moved to /hot (/?page=N → 301); new /ending, /picks, /c and /c/:category; /sitemaps/pages.xml lists them all (the sitemap had no page a person browses). Imported deals keep their source's category and editors' pick (Sources feed@3; migration 0007_offer_category_pick.sql adds staff_pick). Budgets: html 29.1 KB, css 24.2 KB.
  • Account export and deletion (ADR-033): network.account.export_requested and network.account.deleted are answered at POST /internal/events by server/domain/account-data.js over openvibe-sdk/account-data (SDK v0.37.0, was v0.35.0). The person's watches, votes, name and rate windows are deleted; what they contributed to the shared catalog stays without their id; staff moderation records stay attributed. The two subscriptions are created at boot. Migration 0003_account_data.sql adds account_data_events. test/account-data.test.js.
  • openvibe-contracts moves from v0.79.0 to v0.97.0 (pin, lockfile and node_modules); nothing in the range breaks Deals, and the contracts' own service check is green. All twelve deals.* ids are now defined by the release, so server/auth/capabilities.js drops its local fallback for proposed ids and sends every check through the library's grant rule; test/capabilities.test.js pins that every guarded id is defined and that exact, prefix, denied and unknown ids answer as capabilities.check() does. README and STATUS.json name v0.97.0.
  • Every page is rendered through openvibe-publishing/layout (v1.2.0, on openvibe-shared/shell v2.6.0): the head, the Frame, the noscript navigation, the footer and its init come from the shared document; robots and the canonical still come from the indexability gate's decision. Styling is unchanged.