Skip to content

[Feat] Add self-hosted license purchase entry points - #937

Merged
brunobergher merged 8 commits into
developfrom
feature/self-hosted-license-purchase-0gyjcumvkkxa0
Aug 3, 2026
Merged

[Feat] Add self-hosted license purchase entry points#937
brunobergher merged 8 commits into
developfrom
feature/self-hosted-license-purchase-0gyjcumvkkxa0

Conversation

@roomote-roomote

Copy link
Copy Markdown
Contributor

Created by Roomote. Follow up by mentioning @roomote, in the web UI, or in Slack.

What changed

  • Added a persistent Roomote Cloud purchase CTA to the self-hosted License settings, promoted it beside the warning when only one or no seats remain, and tracked clicks with seat and license context.
  • Added a renewal warning for purchased self-hosted keys that expire within 30 days.
  • Extended daily Ping reports with the active license ID and a users-only reporting path for licensed deployments that opt out of anonymous analytics, while keeping full instance statistics behind the existing opt-out and environment gates.
  • Moved deployment license resolution into the shared server data layer so the web app and scheduled worker use the same offline key verification path.
  • Updated public documentation with the Cloud purchase path, annual key refresh, and licensed usage-reporting terms.

Why this change was made

Self-hosted operators need a direct path to purchase and renew licenses without contacting maintainers, and licensed usage needs to reach the shared billing pipeline without turning anonymous analytics back on.

Impact

Self-hosted admins can move from seat-limit warnings to Roomote Cloud purchase, see when purchased keys need refreshing, and keep applying keys through Settings or R_LICENSE_KEY. License verification and expiry enforcement remain offline, expired keys still fall back to the free 10-seat limit, and only the license ID plus current user total bypasses the analytics opt-out.

Targeted web, BullMQ, telemetry, type, lint, Knip, and docs checks passed. The full test sweep passed 357 of 358 web test files; the remaining pre-existing automation-settings test failed during database cleanup because a seeded environment still referenced its user.

Screenshots

Desktop License settings with the Roomote Cloud purchase CTA and helper guidance

Mobile License settings stacked without clipping

One-seat-remaining warning with the purchase CTA promoted inline

@roomote-roomote

roomote-roomote Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

1 issue outstanding. See task

  • packages/telemetry/src/server/license-cloud.ts:156-166 In-flight syncs can overwrite a newer activation lease: a report that read the old key before an admin changes it still writes its old licenseCloudState after the new key is stored. The effective seat-limit check then sees a license-ID mismatch and falls back to 10 seats until a later sync succeeds. Guard the update against the currently configured license or serialize it with the key update.
  • packages/telemetry/src/server/license-cloud.ts:161-179 Interactive activations are still unconditional. If two admins submit different keys concurrently, the second activation can write its new key and lease first, then the delayed response from the earlier request overwrites both with the old selection. Apply the same compare-and-set guard to interactive activations, based on the key snapshot read before sending the request.
  • packages/telemetry/src/server/license-cloud.ts:174-181 The compare-and-set result is ignored. With two concurrent manual activations that both snapshot the same stored key, the later update can match zero rows but still return synced; setLicenseKeyCommand then tells that admin the new key was saved even though the other activation remains configured. Return a row from the guarded update and treat an empty result as a failed/stale activation (with a regression test).

Reviewed 6794c0a

@brunobergher
brunobergher force-pushed the feature/self-hosted-license-purchase-0gyjcumvkkxa0 branch from 069c008 to 8a7b902 Compare August 3, 2026 09:17
@brunobergher
brunobergher marked this pull request as ready for review August 3, 2026 11:35
@brunobergher
brunobergher merged commit e0ff87f into develop Aug 3, 2026
18 checks passed
@brunobergher
brunobergher deleted the feature/self-hosted-license-purchase-0gyjcumvkkxa0 branch August 3, 2026 11:35
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.

2 participants