Setup commercial launch: licenze + backend Cloudflare Worker
Client (Python/JS):
- core/license.py: attivazione, validazione, deactivate (HTTP client + JWT decode)
- core/config.py: campi license_* + URL endpoint + costanti grace/revalidate
- api/bridge.py: get_init_data ritorna license status; activate_license/
deactivate_license/revalidate_license/open_purchase_page
- check_update riscritto: punta a musictools.djluza.com/api/latest con
Bearer token, URL di download firmato dal server solo se licensed
- webui: schermata di attivazione bloccante all'avvio; sezione Licenza
in Impostazioni con verifica/disattiva
Backend (server/):
- Cloudflare Worker + D1 + R2 (vedi server/README.md)
- Endpoints: /api/license/{activate,validate,deactivate}, /api/latest,
/api/webhook/lemonsqueezy, /api/health
- JWT HS256 con rotazione; max 3 attivazioni/licenza
- Generazione licenze via webhook Lemon Squeezy + email Resend
- Schema D1 in migrations/0001_init.sql
Memory: nuova musictools-commercial-launch.md, rimosso pending obsoleto
NON taggare finche backend non e' deployato (l'app e' bloccante)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
05a2a58ace
commit
5202b2c586
19 files changed
+1572
-31
No files matched your search
@@ -0,0 +1,42 @@
|
||||
-- Schema iniziale licenze MusicTools
|
||||
|
||||
CREATE TABLE IF NOT EXISTS licenses (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
license_key TEXT NOT NULL UNIQUE,
|
||||
email TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active', -- active | revoked | refunded
|
||||
source TEXT, -- es. 'lemonsqueezy', 'manual'
|
||||
order_id TEXT, -- id dell'ordine LS
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_licenses_email ON licenses(email);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
license_id INTEGER NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
|
||||
device_id TEXT NOT NULL,
|
||||
device_name TEXT,
|
||||
app_version TEXT,
|
||||
activated_at INTEGER NOT NULL,
|
||||
last_seen_at INTEGER NOT NULL,
|
||||
revoked_at INTEGER,
|
||||
UNIQUE (license_id, device_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_activations_license ON activations(license_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS releases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
version TEXT NOT NULL,
|
||||
platform TEXT NOT NULL, -- macos | windows
|
||||
r2_key TEXT NOT NULL, -- chiave dentro il bucket R2
|
||||
size_bytes INTEGER,
|
||||
sha256 TEXT,
|
||||
notes TEXT,
|
||||
published_at INTEGER NOT NULL,
|
||||
UNIQUE (version, platform)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_releases_platform_pub ON releases(platform, published_at DESC);
|
||||
Reference in new issue
Block a user