Add dashboard launch readiness status
This commit is contained in:
parent
5bb8b31ef9
commit
88e795abd3
7 changed files with 68 additions and 5 deletions
|
|
@ -102,6 +102,7 @@ Protected browser dashboard routes now expose:
|
|||
- desktop-link token generation
|
||||
- download/release posture
|
||||
- billing and entitlement state
|
||||
- launch-readiness configuration posture
|
||||
- browser-access boundary explanation
|
||||
- notices review
|
||||
|
||||
|
|
@ -111,6 +112,13 @@ That auth/server health surface now also reports:
|
|||
- the reported core API version when reachable
|
||||
- whether fallback posture is currently active and why
|
||||
|
||||
The protected dashboard now also has a first-party launch-readiness panel for:
|
||||
|
||||
- public download URL presence by platform
|
||||
- Paddle checkout-link presence by plan
|
||||
- corresponding-source and open-source notices URL presence
|
||||
- backend webhook-secret and billing-map configuration posture
|
||||
|
||||
This is browser-based user access for the operator/account surface.
|
||||
|
||||
It is **not** a claim that the simulator itself is now browser-owned.
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ repo.
|
|||
| Feature | Status | Primary authority | Notes |
|
||||
|---|---|---|---|
|
||||
| Public `hypertwist.app` marketing shell | Implemented now | first-party `website/` app + feature registry/roadmap authority | HyperTwist now has a dedicated first-party public web surface for homepage, about, resources, pricing, download, support, and legal routes. This lane is separate from the embedded Unreal browser runtime under `Content/Browser/` and does not claim browser-simulator parity. |
|
||||
| Browser-based operator/account dashboard | Implemented now | first-party `website/` app + shared auth/dashboard packet | A protected browser dashboard is now live for operator access, account state, download posture, browser-access boundary explanation, notices review, and bounded billing/entitlement status. It reuses the shared SuperTokens auth posture proven in FamiliarOS and ScriptoriumAI while remaining HyperTwist-specific in product content and boundary claims, and the current auth-health surface now truthfully distinguishes configured versus reachable or ready shared-core posture while exposing fallback-active reason instead of hardcoding readiness. |
|
||||
| Browser-based operator/account dashboard | Implemented now | first-party `website/` app + shared auth/dashboard packet | A protected browser dashboard is now live for operator access, account state, download posture, browser-access boundary explanation, notices review, and bounded billing/entitlement status. It reuses the shared SuperTokens auth posture proven in FamiliarOS and ScriptoriumAI while remaining HyperTwist-specific in product content and boundary claims, the current auth-health surface now truthfully distinguishes configured versus reachable or ready shared-core posture while exposing fallback-active reason instead of hardcoding readiness, and the same dashboard now also surfaces launch-readiness truth for download URLs, checkout links, source/notices URLs, and billing-secret/map configuration. |
|
||||
| Desktop download posture and browser-to-desktop pairing | Implemented now | first-party `website/` app + `website/server` desktop-link endpoints | Public download targets, dashboard-side release posture, and short-lived desktop-link token generation/verification are now first-party owned. The current server posture now enforces exact website-origin matching, bounded per-user issuance, one-time token consumption, and billing-backed plan/download entitlement resolution with focused `website/server` tests green on `2026-06-22`, and the verify handshake now returns the same resolved download-entitlement posture the dashboard sees instead of only identity plus plan/role. The public `/download` page now keeps raw download URLs behind the protected dashboard instead of exposing them directly. Actual release URLs remain deployment configuration rather than hardcoded product truth. |
|
||||
| Paddle-ready pricing and billing webhook seam | Implemented now | first-party `website/` app + `website/server` billing endpoint | The public pricing surface now exists with plan structure, checkout-link configuration seams, and the same `/api/billing/paddle/webhook` endpoint family used by the broader product website lane. The current server now verifies `Paddle-Signature` against `PADDLE_WEBHOOK_SECRET` using the documented raw-body HMAC flow, persists a bounded first-party billing state file, and applies verified Paddle events into account/download entitlement state that the browser dashboard consumes, with focused `website/server` tests green on `2026-06-22`. Production checkout URLs, secret management, and broader operator/admin billing workflows remain deployment/application tasks, not shipped-code omissions. |
|
||||
| Public open-source notices and corresponding-source surface | Implemented now | first-party `website/` app + `HYPERTWIST_MPL_DISTRIBUTION_PLACEMENT_CHECKLIST_2026-05-25.md` | HyperTwist now has a stable public `Open Source Notices` route linked from pricing, download, and footer surfaces, satisfying the requirement that public distribution surfaces expose notice and corresponding-source guidance when shipped builds contain `MPL`-covered material. The exact public corresponding-source URL still must be configured before external launch. |
|
||||
|
|
|
|||
|
|
@ -207,7 +207,9 @@ Current consolidated milestone snapshot:
|
|||
and the bounded auth-health probe now truthfully distinguishes configured
|
||||
versus reachable or ready shared SuperTokens core posture while reflecting
|
||||
fallback-active reason back into the protected dashboard rather than
|
||||
hardcoding readiness,
|
||||
hardcoding readiness, and the protected dashboard now also carries a
|
||||
first-party launch-readiness panel for download/check-out/legal configuration
|
||||
posture using the existing site-config and auth-health seams,
|
||||
persists a bounded first-party billing-state file, applies verified Paddle
|
||||
events into account/download entitlement state, and surfaces that resolved
|
||||
billing/download posture back through `/api/auth/me`, the protected browser
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ First-party `hypertwist.app` surface for HyperTwist:
|
|||
- shared SuperTokens auth posture reused from the FamiliarOS and ScriptoriumAI website lane
|
||||
- desktop download posture and desktop-link handshake endpoints
|
||||
- Paddle-ready pricing/check-out wiring
|
||||
- dashboard-side launch-readiness surface for download, checkout, auth, and notice configuration
|
||||
- public open-source notices surface required by HyperTwist's MPL distribution doctrine
|
||||
|
||||
## Why this app exists
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ export interface AuthHealthPayload {
|
|||
active?: boolean
|
||||
reason?: string | null
|
||||
}
|
||||
billing: {
|
||||
statePath: string
|
||||
processedEventCount: number
|
||||
pricePlanMapConfigured: boolean
|
||||
productPlanMapConfigured: boolean
|
||||
webhookSecretConfigured: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export interface ApiBootstrapUserPayload {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useMemo } from 'react'
|
|||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { buildAuthApiBaseUrls, createDesktopLinkToken, getAuthHealth } from '../auth/auth-api'
|
||||
import { usePlatformAuth } from '../auth/platform-auth'
|
||||
import { downloadTargets, mplSourceUrl } from '../site-config'
|
||||
import { downloadTargets, launchReadiness, mplSourceUrl } from '../site-config'
|
||||
import { roadmapHonestyCards } from '../site-data'
|
||||
|
||||
function Panel({
|
||||
|
|
@ -42,6 +42,16 @@ export function DashboardOverviewPage() {
|
|||
return `${baseUrl}/api/auth/desktop-link/verify?token=${encodeURIComponent(token)}`
|
||||
}, [desktopLinkMutation.data?.token])
|
||||
|
||||
const launchReadinessIssues = useMemo(() => {
|
||||
const issues: string[] = []
|
||||
if (!launchReadiness.windowsDownloadConfigured) issues.push('Windows download URL missing')
|
||||
if (!launchReadiness.operatorCheckoutConfigured) issues.push('Operator checkout URL missing')
|
||||
if (!launchReadiness.mplSourceConfigured) issues.push('MPL corresponding-source URL missing')
|
||||
if (!launchReadiness.openSourceRepoConfigured) issues.push('Open-source repository/notices URL missing')
|
||||
if (healthQuery.data && !healthQuery.data.billing.webhookSecretConfigured) issues.push('Paddle webhook secret missing')
|
||||
return issues
|
||||
}, [healthQuery.data])
|
||||
|
||||
return (
|
||||
<div className="panel-grid">
|
||||
<Panel title="Account state" kicker="Live session">
|
||||
|
|
@ -105,6 +115,28 @@ export function DashboardOverviewPage() {
|
|||
</ul>
|
||||
</Panel>
|
||||
|
||||
<Panel title="Launch readiness" kicker="Public release configuration">
|
||||
<ul className="list">
|
||||
<li>Windows download URL: {launchReadiness.windowsDownloadConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>macOS download URL: {launchReadiness.macDownloadConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>Linux download URL: {launchReadiness.linuxDownloadConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>Operator checkout URL: {launchReadiness.operatorCheckoutConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>Studio checkout URL: {launchReadiness.studioCheckoutConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>MPL corresponding-source URL: {launchReadiness.mplSourceConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>Open-source repo/notices URL: {launchReadiness.openSourceRepoConfigured ? 'configured' : 'missing'}</li>
|
||||
<li>Paddle webhook secret: {!healthQuery.data ? 'checking' : (healthQuery.data.billing.webhookSecretConfigured ? 'configured' : 'missing')}</li>
|
||||
<li>Billing product map: {!healthQuery.data ? 'checking' : (healthQuery.data.billing.productPlanMapConfigured ? 'configured' : 'missing')}</li>
|
||||
<li>Billing price map: {!healthQuery.data ? 'checking' : (healthQuery.data.billing.pricePlanMapConfigured ? 'configured' : 'missing')}</li>
|
||||
</ul>
|
||||
{launchReadinessIssues.length > 0 ? (
|
||||
<p className="form-error">
|
||||
Public launch is not fully configured yet: {launchReadinessIssues.join('; ')}.
|
||||
</p>
|
||||
) : (
|
||||
<p>Core public release configuration is present for the current bounded website lane.</p>
|
||||
)}
|
||||
</Panel>
|
||||
|
||||
<Panel title="Product boundary" kicker="Roadmap honesty">
|
||||
<ul className="list">
|
||||
{roadmapHonestyCards.map((item) => (
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ export const brandConfig = {
|
|||
},
|
||||
}
|
||||
|
||||
const operatorCheckoutUrl = readTrimmedEnv('VITE_PADDLE_CHECKOUT_URL_OPERATOR')
|
||||
const studioCheckoutUrl = readTrimmedEnv('VITE_PADDLE_CHECKOUT_URL_STUDIO')
|
||||
|
||||
export const planCatalog = [
|
||||
{
|
||||
key: 'explorer',
|
||||
|
|
@ -37,7 +40,7 @@ export const planCatalog = [
|
|||
key: 'operator',
|
||||
name: 'Operator',
|
||||
price: readTrimmedEnv('VITE_PLAN_PRICE_OPERATOR', 'Launch pricing via Paddle'),
|
||||
ctaLabel: readTrimmedEnv('VITE_PADDLE_CHECKOUT_URL_OPERATOR') ? 'Open Paddle checkout' : 'Request operator access',
|
||||
ctaLabel: operatorCheckoutUrl ? 'Open Paddle checkout' : 'Request operator access',
|
||||
ctaHref: readTrimmedEnv('VITE_PADDLE_CHECKOUT_URL_OPERATOR', '/pricing'),
|
||||
notes: 'Desktop-first recognition, replay, training, and higher-dimensional runtime ownership for active training operators.',
|
||||
features: [
|
||||
|
|
@ -51,7 +54,7 @@ export const planCatalog = [
|
|||
key: 'studio',
|
||||
name: 'Studio',
|
||||
price: readTrimmedEnv('VITE_PLAN_PRICE_STUDIO', 'Contact for launch readiness'),
|
||||
ctaLabel: readTrimmedEnv('VITE_PADDLE_CHECKOUT_URL_STUDIO') ? 'Open Paddle checkout' : 'Talk to HyperTwist',
|
||||
ctaLabel: studioCheckoutUrl ? 'Open Paddle checkout' : 'Talk to HyperTwist',
|
||||
ctaHref: readTrimmedEnv('VITE_PADDLE_CHECKOUT_URL_STUDIO', '/support'),
|
||||
notes: 'Higher-dimensional families, operator deployment support, and packaging/validation coordination for production lanes.',
|
||||
features: [
|
||||
|
|
@ -89,5 +92,15 @@ export const releaseNotesUrl = readTrimmedEnv('VITE_RELEASE_NOTES_URL')
|
|||
export const mplSourceUrl = readTrimmedEnv('VITE_MPL_SOURCE_URL')
|
||||
export const openSourceRepoUrl = readTrimmedEnv('VITE_OPEN_SOURCE_REPO_URL')
|
||||
|
||||
export const launchReadiness = {
|
||||
operatorCheckoutConfigured: Boolean(operatorCheckoutUrl),
|
||||
studioCheckoutConfigured: Boolean(studioCheckoutUrl),
|
||||
windowsDownloadConfigured: Boolean(downloadTargets.find((target) => target.platform === 'Windows')?.href),
|
||||
macDownloadConfigured: Boolean(downloadTargets.find((target) => target.platform === 'macOS')?.href),
|
||||
linuxDownloadConfigured: Boolean(downloadTargets.find((target) => target.platform === 'Linux')?.href),
|
||||
mplSourceConfigured: Boolean(mplSourceUrl),
|
||||
openSourceRepoConfigured: Boolean(openSourceRepoUrl),
|
||||
} as const
|
||||
|
||||
export const paddleReadyDescription =
|
||||
'HyperTwist is a desktop-first training environment for classic cube, recognition-assisted reconstruction, replay explanation, coaching, higher-dimensional runtime ownership, and browser-based operator access. Delivery is digital-only through authenticated account access and desktop downloads. Pricing and checkout are wired for Paddle, while public legal surfaces stay responsible for open-source notices and corresponding-source disclosure when shipped builds contain MPL-covered components.'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue