Fix admin SPA gold-fill design-contract violations; bump to 0.2.0:59
The featured-pill on-state and the sidebar upgrade CTA filled with gold, which the brand contract and the admin-UI pill convention forbid (gold is a marketing accent, never a button fill). The Featured toggle is now navy-filled with a cream pip; the upgrade CTA is cream-filled with navy text and aligned to the 8px button radius. CSS / inline-style only in the embedded web/index.html — no schema, no SDK, no behavior change.
This commit is contained in:
@@ -415,16 +415,16 @@ hr.div { border:none; border-top:1px solid var(--border-1); margin:18px 0; }
|
||||
border:1px solid var(--border-1);
|
||||
}
|
||||
.featured-pill-toggle.on {
|
||||
background:var(--gold-500); color:var(--navy-950);
|
||||
border-color:var(--gold-500);
|
||||
box-shadow:0 2px 6px rgba(191,160,104,0.25);
|
||||
background:var(--navy-800); color:var(--cream-50);
|
||||
border-color:var(--navy-800);
|
||||
box-shadow:0 2px 6px rgba(14,31,51,0.18);
|
||||
}
|
||||
.featured-pill-toggle.on .state {
|
||||
background:var(--navy-950); color:var(--gold-500);
|
||||
border-color:var(--navy-950);
|
||||
background:var(--cream-50); color:var(--navy-900);
|
||||
border-color:var(--cream-50);
|
||||
}
|
||||
.featured-pill-toggle.on:hover {
|
||||
background:var(--gold-400);
|
||||
background:var(--navy-900);
|
||||
}
|
||||
|
||||
/* Tier-card drag affordance — cursor signals draggability on hover,
|
||||
@@ -534,12 +534,12 @@ hr.div { border:none; border-top:1px solid var(--border-1); margin:18px 0; }
|
||||
<div id="tier-banner-msg" style="margin-bottom:8px;"></div>
|
||||
<a id="tier-banner-cta" target="_blank" rel="noopener" style="
|
||||
display:inline-block; padding:5px 10px;
|
||||
background:var(--gold-500); color:var(--navy-950);
|
||||
background:var(--cream-50); color:var(--navy-900);
|
||||
font-weight:700; font-size:11px;
|
||||
border-radius:5px; text-decoration:none;
|
||||
border-radius:8px; text-decoration:none;
|
||||
transition:background 120ms;
|
||||
" onmouseover="this.style.background='var(--gold-400)'"
|
||||
onmouseout="this.style.background='var(--gold-500)'"></a>
|
||||
" onmouseover="this.style.background='var(--cream-200)'"
|
||||
onmouseout="this.style.background='var(--cream-50)'"></a>
|
||||
</div>
|
||||
<div class="footer" id="sidebar-footer">
|
||||
<span class="dot warn"></span>
|
||||
|
||||
@@ -39,6 +39,8 @@ const RELEASE_NOTES = [
|
||||
// in RELEASE_NOTES above (the milestone). Subsequent revisions
|
||||
// append here.
|
||||
const ROUTINE_NOTES = [
|
||||
'0.2.0:59 — **Admin UI: drop the gold button-fill design-contract violations.** Two admin-SPA controls filled with gold, which the brand contract (`design/DESIGN.md`) and the admin-UI pill convention forbid (gold is a marketing accent, never a button fill): the "Featured" tier toggle\'s on-state and the sidebar tier-upgrade CTA. Both now follow the convention — the Featured toggle is navy-filled with a cream pip when on; the upgrade CTA is cream-filled with navy text (the on-brand high-contrast treatment for a primary action on the navy sidebar), and its corner radius is aligned to the 8px button spec. CSS / inline-style only in the embedded `web/index.html` — no schema, no SDK, no behavior change. Straight drop-in over :58. (The matching public-landing fix — the Buy button\'s pill radius set to 8px — ships in the keysat-xyz-landing repo, deployed separately.)',
|
||||
'',
|
||||
'0.2.0:58 — **Agent-delegable BTCPay connect, gated to sandbox + non-mainnet.** Makes Keysat fully agent-operable for *dev/test setup*: an operator can hand an agent a scoped key that connects a BTCPay payment provider over the API — no master key, no browser click — but only on a sandbox daemon and only for a non-mainnet (regtest/testnet/signet) store. On a production daemon, or for a mainnet store, connecting a provider stays master-only, and disconnect is always master-only. The reasoning: a credential that can repoint where settlement lands is a fund-redirection key, so the capability is deliberately narrow and fails closed. **Gated in three layers:** (1) a daemon-level `KEYSAT_SANDBOX_MODE` flag, read at boot and never settable via any API, is the outer gate — scoped connect is disabled entirely on a production box; (2) `payment_providers:write` is an à-la-carte per-key scope that belongs to no role (not even full-admin), granted explicitly when an operator mints a key; (3) at OAuth-callback time the daemon resolves the target store\'s Bitcoin network from its on-chain receive address and refuses anything not provably non-mainnet, failing closed to mainnet on any ambiguity (no on-chain wallet, unreachable BTCPay, unrecognized address) — it denies rather than guesses. Migrations 0024 (`scoped_api_keys.extra_scopes`) and 0025 (`btcpay_authorize_state.scoped_initiator` + actor hash, to carry the initiator across the browser round-trip) are additive — straight drop-in over :57. The served OpenAPI spec now documents the BTCPay connect/callback/status/disconnect paths and the key-creation `scopes` field, and `/v1/admin/tier` surfaces a read-only `sandbox` flag. Also hardened: the GET authorize-callback now returns the real HTTP status on a denied connect (was a misleading 200 with an error page). Validated end-to-end against a live regtest BTCPay; the docs-onboarding harness (a fresh agent integrating from the published docs alone) converged completed-clean on the full buyer-pays journey. Daemon api test suite is at 65, up from 57. Zaprite connect stays master-only. No SDK change.',
|
||||
'',
|
||||
'0.2.0:57 —**New `merchant-onboard` scoped-API-key role for least-privilege self-serve onboarding.** A fifth scoped-key role sits between `license-issuer` and `full-admin`, granting read access plus `products:write` + `policies:write` + `licenses:write` — the minimum a merchant (or an integrating agent) needs to stand up a catalog end-to-end over the API: create a product, define its policies/tiers, and issue licenses against them, all without holding the master key. The catalog write *scopes* already existed and were enforced on the endpoints since :55; only a role that expands to them was missing, so this is a `Role`-variant addition, not a scope-model change. `Role::grants` matches the write scopes explicitly (never by `:write` suffix), so the role can never widen into settings / payment-provider / merchant-profile / webhook writes, and every master-only operation (signing-key rotation, payment connect, web-admin password, API-key management, server settings, per-license tier change, DB introspection) stays behind `require_admin` and is structurally unreachable from any scoped key. Existing Creator-tier caps still bound it (5 products / 5 policies per product / 10 active codes). **Caveat:** the role covers catalog setup + manual license issuance fully, but connecting a BTCPay/Zaprite payment provider stays master-only by design, so the buyer-paid purchase flow still needs a one-time operator step. Migration 0023 rebuilds `scoped_api_keys` to widen the role CHECK constraint (SQLite can\'t alter a CHECK in place; the table has no foreign keys, so it\'s a plain copy/drop/rename) — additive, a straight drop-in over :56. Daemon api test suite is at 57, up from 56. No SDK change.',
|
||||
@@ -532,7 +534,7 @@ const ROUTINE_NOTES = [
|
||||
].join('\n\n')
|
||||
|
||||
export const v0_2_0 = VersionInfo.of({
|
||||
version: '0.2.0:58',
|
||||
version: '0.2.0:59',
|
||||
releaseNotes: { en_US: ROUTINE_NOTES },
|
||||
// No on-disk transformation needed — v0.2.0:0 is a label change.
|
||||
// SQLite-level migrations live separately under
|
||||
|
||||
Reference in New Issue
Block a user