v0.2.0:11 + v0.2.0:12 — Archive, Settings, agent surface, machines redesign
Two release cycles prepared together: v0.2.0:11 (policy archive + safe- delete cleanup + brand-consistent confirm modals) and v0.2.0:12 (Settings tab + agent-friendly operator API + machines tab redesign + buyer-facing copy alignment). Highlights: - Migration 0015: policies.archived_at column. Archive button on tier cards; safe-delete relaxed to ignore revoked-license tombstones; renewal worker refuses archived policies. - Migration 0016: scoped_api_keys table. Four roles (read-only, license-issuer, support, full-admin) with bounded scopes. Master admin_api_key still works on every endpoint; scoped keys gated on endpoints wired through require_scope(). - New /v1/openapi.json — public, no auth. Curated OpenAPI 3.1 spec for agent / SDK discovery. - New Settings tab: Operator name + Payment providers panel + API keys management. Replaces 8 StartOS Actions (Zaprite all, BTCPay all, operator name, switch-provider). StartOS Actions pruned to 4 install-time essentials. - Machines tab rewritten: global default view grouped by product, filter pills with counts, quick-stats row, drill-down via new "Machines" button on each Licenses-tab row. New repo helper list_machines_admin joins machines x licenses x products server-side. - Branded confirmModal replaces every native window.confirm() call in the admin UI (7 callsites). - Enforce mode killed: KEYSAT_LICENSE_ENFORCE compile-time flag retired; daemon always boots; missing self-license -> Creator (free) tier. "Unlicensed" label gone from admin UI. - Zaprite gated on the new zaprite_payments entitlement (renamed from card_payments to reflect the broader gateway). - Creator code cap 5 -> 10. - KEYSAT_AGENT_GUIDE.md: auth, role-to-scope mapping, error envelope, webhook events, worked recipes. - Buyer-facing copy aligned with new positioning: "Bitcoin-native self-hosted software licensing" everywhere on production surfaces. - Cross-product safety section (Section 9a) added to KEYSAT_INTEGRATION.md. - 5 new API integration smoke tests covering OpenAPI, scoped API keys CRUD, role-elevation guard, and Zaprite-tier gating. Test count: 83 passing (was 78). All migration tests pass against 0015 and 0016 applied to populated DBs.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
-- Migration 0015: policies.archived_at
|
||||
--
|
||||
-- Adds a soft-archive flag to policies. An archived policy is hidden
|
||||
-- from the admin grid (unless the operator opts to show archived) and
|
||||
-- from the public /buy/<slug> page. Existing licenses keep validating
|
||||
-- because their entitlements are signed into the LIC1 payload; the
|
||||
-- policy row is not consulted at validate time. Active recurring
|
||||
-- subscriptions tied to an archived policy stop renewing — the renewal
|
||||
-- worker treats archived as a hard stop and surfaces a clear event.
|
||||
--
|
||||
-- Why a column instead of a status TEXT enum? Policies already have
|
||||
-- two boolean toggles (active, public). A nullable timestamp is the
|
||||
-- minimum-information shape: NULL = live, timestamp = when archived.
|
||||
-- Useful for sorting "Archived (most recent first)" without an extra
|
||||
-- column.
|
||||
|
||||
ALTER TABLE policies ADD COLUMN archived_at TEXT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_policies_archived_at ON policies(archived_at);
|
||||
Reference in New Issue
Block a user