refactor(licensing): replace Pro branding with Community/Skipper/Admiral tiers (#375)

Eliminate all references to "Pro" across backend, frontend, and docs.
Internal tier value renamed from 'pro' to 'paid'; user-facing text now
uses the thematic tier names (Community, Skipper, Admiral).

- Rename LicenseTier 'pro' to 'paid' in backend and frontend types
- Rename requirePro guard to requirePaid, error code PRO_REQUIRED to PAID_REQUIRED
- Rename ProGate.tsx to PaidGate.tsx with updated copy
- Fix: trial users can now see upgrade/purchase cards in Settings
- Update all docs and openapi.yaml to use correct tier names
This commit is contained in:
Anso
2026-04-05 05:59:36 -04:00
committed by GitHub
parent a1804c8fbe
commit f516275834
33 changed files with 304 additions and 281 deletions
+5 -5
View File
@@ -2,12 +2,12 @@ import crypto from 'crypto';
import axios from 'axios';
import { DatabaseService } from './DatabaseService';
export type LicenseTier = 'community' | 'pro';
export type LicenseTier = 'community' | 'paid';
export type LicenseStatus = 'community' | 'trial' | 'active' | 'expired' | 'disabled';
export type LicenseVariant = 'personal' | 'team' | null;
const VALID_TIERS: readonly string[] = ['community', 'pro'] satisfies readonly LicenseTier[];
const VALID_TIERS: readonly string[] = ['community', 'paid'] satisfies readonly LicenseTier[];
const VALID_VARIANTS: readonly string[] = ['personal', 'team'] satisfies readonly LicenseVariant[];
export function isLicenseTier(value: unknown): value is LicenseTier {
@@ -141,7 +141,7 @@ export class LicenseService {
trialEnd.setDate(trialEnd.getDate() + TRIAL_DURATION_DAYS);
db.setSystemState('license_status', 'trial');
db.setSystemState('license_valid_until', trialEnd.toISOString());
console.log(`[License] 14-day Pro trial started. Expires: ${trialEnd.toISOString()}`);
console.log(`[License] 14-day Skipper trial started. Expires: ${trialEnd.toISOString()}`);
}
this.startPeriodicValidation();
@@ -160,7 +160,7 @@ export class LicenseService {
if (status === 'trial') {
const validUntil = db.getSystemState('license_valid_until');
if (validUntil && new Date(validUntil) > new Date()) {
return 'pro';
return 'paid';
}
// Trial expired - update status
db.setSystemState('license_status', 'community');
@@ -186,7 +186,7 @@ export class LicenseService {
return 'community';
}
return 'pro';
return 'paid';
}
return 'community';
+3 -3
View File
@@ -49,9 +49,9 @@ export class SchedulerService {
this.isProcessing = true;
try {
const ls = LicenseService.getInstance();
const isPro = ls.getTier() === 'pro';
const isAdmiral = isPro && ls.getVariant() === 'team';
if (!isPro) return; // No scheduled tasks for non-Pro tiers
const isPaid = ls.getTier() === 'paid';
const isAdmiral = isPaid && ls.getVariant() === 'team';
if (!isPaid) return; // No scheduled tasks for unpaid tiers
const db = DatabaseService.getInstance();
const now = Date.now();