Skip to content

Quota upgrade card: name the transfers ceiling, and stop selling it on ParaSign - #366

Merged
Apolloccrypt merged 2 commits into
mainfrom
fix/quota-upgrade-copy
Sep 2, 2026
Merged

Quota upgrade card: name the transfers ceiling, and stop selling it on ParaSign#366
Apolloccrypt merged 2 commits into
mainfrom
fix/quota-upgrade-copy

Conversation

@Apolloccrypt

@Apolloccrypt Apolloccrypt commented Sep 2, 2026

Copy link
Copy Markdown
Owner

relay/lib/tiers.js geeft elke gemeten tier een eindig transfers_month (Community 10, Pro 500, Business 2000) en relay/lib/entitlements.js houdt zelfs enterprise op ENTERPRISE_MONTHLY_CEILING in plaats van Infinity. Op acht plekken stond toch "unlimited", waaronder de 402-kaart die de relay toont op precies het moment dat het plafond bijt.

Onderweg bleek de helft van die plekken een tweede fout te hebben, die deze PR niet zelf kan oplossen.

Besluit voor Mick: bundelen of gescheiden houden

/pricing verkocht ParaSign Pro met "Unlimited transfers". Dat woord is voor geen enkele tier waar. Maar er 500 van maken zou net zo onwaar zijn geweest, om een scherpere reden.

Transfers zijn een ParaSend-capaciteit, opgeslagen op plan_parasend. Het pad dat ParaSign Pro verkoopt is entitlements.applyProductTier(acct, 'parasign', 'pro'): de Mollie-webhook en de admin-grant. Dat schrijft alleen plan_parasign en laat plan_parasend bewust staan. Een ParaSign Pro-koper op een gratis ParaSend-tier houdt dus 10 transfers per maand. relay/test/parasign-pro-perks.test.js pint dat al sinds het geschreven werd, met de opmerking dat jij beslist.

Twee opties, allebei geldig:

  1. Bundelen. ParaSend Pro meeleveren bij ParaSign Pro. Dan moet applyProductTier het ook echt schrijven, en mogen de kaarten 500 noemen. De drie negatieve pins hieronder draaien dan vanzelf om naar "moet er staan": ze vragen het de entitlement-laag, ze herhalen het antwoord niet.
  2. Gescheiden houden, zoals nu. ParaSign Pro verkoopt handtekeningen en de API; wie transfers wil koopt ParaSend Pro. Dat is wat deze PR doet, want het is de enige stand die vandaag waar is.

Deze PR kiest niet voor je. Hij haalt de onware regel weg en zet er een hek omheen dat meebeweegt zodra je optie 1 kiest.

Per treffer, oud en nieuw

ParaSign-kaarten: de transfers-regel is weg. ParaSign Pro verkoopt handtekeningen.

Waar Was Nu
frontend/pricing.html, ParaSign Pro-kaart "Unlimited transfers - API access" "API access"
frontend/parasign.html, ParaSign Pro-kaart "500 ParaSend transfers a month" regel verwijderd
frontend/js/quota-upgrade.js, ParaSign Pro-pitch in de 402 "... up to 1,000. Unlimited transfers. API access." "... up to 1,000. API access."
frontend/js/dashboard.js, samenvatting betalende ParaSign-klant "..., unlimited transfers, and a connection ..." "..., and a connection ..."

ParaSend-contexten: het echte getal, uit tiers.js. Daar handhaaft de relay het ook.

Waar Was Nu
frontend/js/quota-upgrade.js, kop transfer-402 altijd "Community monthly limit reached." de tier die de 402 meldt
frontend/js/quota-upgrade.js, aanbod transfer-402 "for a higher limit" "for 500 transfers a month", en geen upsell naar een tier die je al hebt
frontend/docs/paramant-ot-brief.html, Pro-tier "Unlimited transfers" / "Managed, unlimited" "500 transfers a month" / "Managed relay"
docs/ + frontend/docs/self-hosting.md, plantabel pro/enterprise "Unlimited" uploads per dag, 500 MB, unlimited bestandsgrootte, verzonnen kolom Priority de tiers.js-cijfers, met outbound_per_hour op de plek van Priority
admin/server.js, rate limit anonieme drop "free account for unlimited drops" "free account for 10 transfers a month"

Het 402-antwoord deed zijn deel al

Sinds #361 meldt relay.js:4688 bij monthly_transfer_quota_reached de tier die besliste (_psend.tier) plus diens plafond (_psend.quotas.transfers_month), niet het samengevoegde accountplan. De kaart negeerde allebei: hij drukte "Community" af wie er ook keek, en bood ParaSend Pro aan een Pro-account aan. Aan de relay was niets te repareren; de kaart leest ze nu, met de gespiegelde tabel alleen als terugval voor een backend van voor #361.

Wat blijft staan, en waarom het waar is

  • "No limit on receiving" en "unlimited receiving" (about.html, signup.html): niets meet ontvangen, negatief gepind sinds Link the product pages, state the hourly ceiling, and write one monthly form #359.
  • "Unlimited registered devices" op ParaSend Enterprise: tiers.js devices: UNLIMITED.
  • "unlock unlimited users" (docs, relay): LICENSE_MAX_KEYS is echt Infinity bij max_keys: "unlimited".
  • docs/api.md enterprise devices en downloads per uur: spiegelt tiers.js correct.
  • vs.html: beschrijft de opslag van een concurrent.
  • CHANGELOG, ADR's, security-audit: historisch verslag, geen claim.

Gemeld, niet aangeraakt:

  • frontend/parasign.html houdt "Up to 500 ParaSend retrievals an hour through the API" op de ParaSign Pro-kaart. Dat is outbound_per_hour, dezelfde soort claim als de transfers-regel en met hetzelfde leveringsgat, maar Link the product pages, state the hourly ceiling, and write one monthly form #359 heeft die regel er bewust neergezet en gepind. Valt onder hetzelfde besluit hierboven.
  • docs/businessmodel.md verkoopt een OT-model van 12 euro per maand met "Unlimited transfers" dat nergens meer op slaat. Staat niet in frontend/, wordt dus niet geserveerd.
  • De Evaluation-tier in de OT-brief belooft "1000 transfers / 30 days" terwijl Community er 10 heeft. Zelfde drift, buiten de opdracht "Unlimited".

Tests

  • tests/ui-truthfulness.test.mjs, twee blokken. Het eerste verbiedt "unlimited transfers" over de hele frontend, scripts en geserveerde markdown inbegrepen: pricing-page.test.js verbood het al, maar alleen op /parasign en /parasend en alleen in .html, en precies daardoor overleefde het in frontend/js/. Het tweede loopt vier ParaSign-scopes af (de ParaSign-grid van /pricing, de plankaarten van /parasign, PRODUCT_INCLUDES.parasign in dashboard.js, freeSignHtml in quota-upgrade.js) en faalt op elk transfers-getal zolang de grant er geen levert.
  • relay/test/pricing-page.test.js vervangt de assertie die het omgekeerde beweerde. Die zei dat /parasign het plafond moest noemen dat een ParaSign Pro-account "actually derives" via derivePlanParasend, maar die helper vuurt alleen op een oud samengevoegd plan, nooit op het koop-pad.
  • relay/test/quota-upgrade-render.test.js rendert de echte kaarten, vergelijkt elk cijfer per beslissende tier met tiers.js/entitlements.js, verbiedt het woord in dat bestand helemaal, en pint de ParaSign-pitch negatief.
  • relay/test/parasign-pro-perks.test.js houdt zijn FINDING: de grant verzet nog steeds geen ParaSend-plafond.

Alle drie de negatieve pins draaien applyProductTier écht en vergelijken de uitkomst met PARASEND.pro. Kies je optie 1, dan slaan ze om naar "moet er staan", zodat het hek nooit een ware regel van de kaart houdt.

Bewijs

Sabotage, allemaal rood:

Sabotage Rood in
"Unlimited transfers" terug op /pricing ui-truthfulness, pricing-page
"unlimited transfers" terug in js/dashboard.js ui-truthfulness (noemt bestand en tekst)
"Unlimited transfers" terug in de 402-kaart quota-upgrade-render, ui-truthfulness
"Unlimited transfers" terug in de OT-brief ui-truthfulness
tiers.js pro 500 -> 400 quota-upgrade-render, pricing-page
transfers-getal terug op de /pricing ParaSign-kaart ui-truthfulness, pricing-page
transfers-getal terug op de /parasign ParaSign-kaart ui-truthfulness, pricing-page
transfers-getal terug in de 402 ParaSign-pitch quota-upgrade-render, ui-truthfulness
transfers-getal terug in dashboard.js ui-truthfulness
omgekeerd: applyProductTier schrijft wél plan_parasend='pro' alle drie de pins slaan om naar "de kaart mag het nu noemen"

Groen: ui-truthfulness, site-claims, pricing-page, quota-upgrade-render, parasign-pro-perks, frontend-loading-contract, pricing-fold, first-screen, seo-contract, links, navigation-shell, csp-inline, cache-bust, eslint, static-sanity (11 checks).

Head-elementen niet aangeraakt. ?v= gebumpt op de scripttags onderaan de body (quota-upgrade.js 3 -> 4, dashboard.js 6 -> 7), omdat de inhoud van allebei achter een immutable cache veranderde.

relay/lib/tiers.js gives every metered tier a finite transfers_month (10
Community, 500 Pro, 2,000 Business) and relay/lib/entitlements.js holds even
enterprise to ENTERPRISE_MONTHLY_CEILING rather than Infinity. Five places said
"unlimited transfers" anyway, including the 402 card the relay shows at the
exact moment the cap bites.

Per hit, old and new:

| Where | Was | Now |
|---|---|---|
| frontend/js/quota-upgrade.js, ParaSign Pro pitch | "Unlimited transfers." | "500 ParaSend transfers a month." |
| frontend/js/quota-upgrade.js, transfer 402 header | "Community monthly limit reached." always | the tier the 402 reports (#361) |
| frontend/js/quota-upgrade.js, transfer 402 offer | "for a higher limit" | "for 500 transfers a month", and no upsell to a tier already held |
| frontend/pricing.html, ParaSign Pro card | "Unlimited transfers - API access" | "500 ParaSend transfers a month - API access" |
| frontend/js/dashboard.js, paid-plan summary | "unlimited transfers" | "500 ParaSend transfers a month" |
| frontend/docs/paramant-ot-brief.html, Pro tier | "Unlimited transfers" / "Managed, unlimited" | "500 transfers a month" / "Managed relay" |
| docs+frontend/docs/self-hosting.md, plan table | pro/enterprise "Unlimited" uploads a day, 500 MB and unlimited file size, a fictional Priority column | the tiers.js figures: transfers a month, 5 MB, and outbound_per_hour in place of Priority |
| admin/server.js, anon-drop rate limit | "Create a free account for unlimited drops." | "Create a free account for 10 transfers a month." |

The 402 body already carried what the card needed: since #361 relay.js reports
plan and limit of the ParaSend entitlement that DECIDED, not the account's
unified plan. The card ignored both. It now reads them, falling back to the
mirrored table only for a backend older than #361.

Left standing, each true against the code: "No limit on receiving" and
"unlimited receiving" (nothing meters receiving, #359), enterprise "Unlimited
registered devices" (tiers.js devices = UNLIMITED), the licence "unlock
unlimited users" (LICENSE_MAX_KEYS really is Infinity for max_keys
"unlimited"), and vs.html on a competitor's storage.

Tests:
- tests/ui-truthfulness.test.mjs bans the claim across the whole frontend,
  scripts and served markdown included. pricing-page.test.js already forbade it
  but only on /parasign and /parasend and only in .html, which is how it
  survived in frontend/js/. Comments are stripped so an explanation may quote
  the wording it forbids.
- relay/test/quota-upgrade-render.test.js renders the real cards and compares
  every figure against tiers.js and entitlements.js, per deciding tier, and
  bans the word from the file outright.
- relay/test/pricing-page.test.js reads the ParaSign Pro card line from
  tiers.js instead of a literal.
- parasign-pro-perks.test.js keeps its FINDING: a parasign=pro grant still
  moves no ParaSend ceiling, so the card names 500 the grant does not hand
  over. Wording fixed, delivery gap still open, Mick's call.

Sabotage, all red: the phrase back on /pricing, in js/dashboard.js, in the 402
card, in the OT brief, and tiers.js pro moved to 400.

Green: ui-truthfulness, site-claims, pricing-page, quota-upgrade-render,
parasign-pro-perks, frontend-loading-contract, pricing-fold, first-screen,
seo-contract, links, navigation-shell, csp-inline, cache-bust, eslint,
static-sanity (11 checks).

Head elements untouched. quota-upgrade.js v3->v4 and dashboard.js v6->v7 on
the body script tags, since both files changed content behind an immutable
cache.
The first pass replaced "Unlimited transfers" with "500 ParaSend transfers a
month" everywhere, including on the ParaSign Pro surfaces. That fixed the wrong
half. relay/test/parasign-pro-perks.test.js already pinned why: transfers are a
ParaSEND capacity on plan_parasend, and the grant that sells ParaSign Pro
(entitlements.applyProductTier(acct,'parasign','pro'), the Mollie webhook and
the admin path) writes plan_parasign alone and deliberately leaves plan_parasend
where it was. A ParaSign Pro buyer on a free ParaSend tier keeps 10 transfers a
month, so 500 on that card is as untrue as promising no cap at all.

The line is gone from every ParaSign surface:

| Where | Was (first pass) | Now |
|---|---|---|
| frontend/pricing.html, ParaSign Pro card | "500 ParaSend transfers a month - API access" | "API access" |
| frontend/parasign.html, ParaSign Pro card | "500 ParaSend transfers a month" | line removed |
| frontend/js/quota-upgrade.js, ParaSign Pro pitch | "... up to 1,000. 500 ParaSend transfers a month. API access." | "... up to 1,000. API access." |
| frontend/js/dashboard.js, ParaSign Pro summary | "..., 500 ParaSend transfers a month, and a connection ..." | "..., and a connection ..." |

Unchanged, and correct: the real ParaSend contexts keep the number, because
there the relay does enforce it. The OT brief's own Pro tier and the
self-hosting plan table still read 500 transfers a month, and the transfer 402
card still names the deciding tier's ceiling from the relay's own 402 body.

Pinned negatively, in three places, all of which ASK the entitlement layer
rather than restate its answer:

- tests/ui-truthfulness.test.mjs walks four ParaSign scopes (the /pricing
  ParaSign grid, the /parasign plan cards, dashboard.js PRODUCT_INCLUDES
  .parasign, quota-upgrade.js freeSignHtml) and fails on any transfers figure
  while the grant does not move one.
- relay/test/pricing-page.test.js replaces the assertion that said the opposite.
  It claimed /parasign must quote the ceiling "a ParaSign Pro account actually
  derives" via derivePlanParasend, but that helper only fires on a legacy
  unified plan, never on the purchase path.
- relay/test/quota-upgrade-render.test.js pins the rendered pitch.

Each runs applyProductTier for real and compares what comes out against
PARASEND.pro. Bundle a ParaSend entitlement into ParaSign Pro and all three
flip by themselves from "must not state" to "must state", so the gate can never
hold a true line off the card.

Sabotage, all red: the figure back on the /pricing card, on the /parasign card,
in the 402 pitch and in dashboard.js, plus the inverse (applyProductTier made
to write plan_parasend='pro'), which turns all three pins the other way with the
message that the cards may now state it.

Green: ui-truthfulness, site-claims, pricing-page, quota-upgrade-render,
parasign-pro-perks, frontend-loading-contract, pricing-fold, first-screen,
seo-contract, links, navigation-shell, csp-inline, cache-bust, eslint,
static-sanity (11 checks).

Still open for Mick, now stated on the PR: bundle ParaSend Pro into ParaSign
Pro, or keep the two ladders separate as they are.
@Apolloccrypt Apolloccrypt changed the title Quota upgrade card: name the transfers ceiling instead of promising none Quota upgrade card: name the transfers ceiling, and stop selling it on ParaSign Sep 2, 2026
@Apolloccrypt
Apolloccrypt merged commit fd07ad1 into main Sep 2, 2026
11 checks passed
@Apolloccrypt
Apolloccrypt deleted the fix/quota-upgrade-copy branch September 5, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant