summaryrefslogtreecommitdiff
path: root/internal/adminui/assets/index.html
diff options
context:
space:
mode:
authorChia <Chia@93.nz>2026-08-05 22:01:29 +1200
committerChia <Chia@93.nz>2026-08-05 22:07:50 +1200
commiteadb2ffe85c43cf6fc741c9823cd28eedb4a844c (patch)
tree1aba2536d57360da403aa35c9ced58b615c7064e /internal/adminui/assets/index.html
parentcd0dd91ab93653631904f2ea0e574ccde6d60339 (diff)
feat: harden prepaid billing and commercial operations
Diffstat (limited to 'internal/adminui/assets/index.html')
-rw-r--r--internal/adminui/assets/index.html18
1 files changed, 11 insertions, 7 deletions
diff --git a/internal/adminui/assets/index.html b/internal/adminui/assets/index.html
index 95ab153..04b4e87 100644
--- a/internal/adminui/assets/index.html
+++ b/internal/adminui/assets/index.html
@@ -46,14 +46,14 @@
<form class="auth-pane" id="reset-complete-pane">
<div><span class="eyebrow">ACCOUNT RECOVERY</span><h1>Choose a new password</h1></div>
<input name="token" id="reset-token" type="hidden">
- <input class="visually-hidden" autocomplete="username" aria-hidden="true" tabindex="-1">
+ <input class="visually-hidden" name="username" autocomplete="username" aria-hidden="true" tabindex="-1">
<label>New password<input name="new_password" type="password" minlength="12" maxlength="128" required autocomplete="new-password"></label>
<button class="button primary" type="submit">Update password</button>
</form>
<form class="auth-pane" id="invite-pane">
<div><span class="eyebrow">TEAM ACCESS</span><h1>Accept invitation</h1></div>
<input name="token" id="invite-token" type="hidden">
- <input class="visually-hidden" autocomplete="username" aria-hidden="true" tabindex="-1">
+ <input class="visually-hidden" name="username" autocomplete="username" aria-hidden="true" tabindex="-1">
<label>Name<input name="display_name" required autocomplete="name"></label>
<label>Password<input name="password" type="password" minlength="12" maxlength="128" required autocomplete="new-password"></label>
<button class="button primary" type="submit">Join workspace</button>
@@ -124,18 +124,18 @@
<section id="providers" class="section">
<div class="section-heading"><div><span class="eyebrow">UPSTREAMS</span><h1>Providers</h1></div></div>
- <form class="panel form-grid" id="provider-form" data-permission="platform.write"><input class="visually-hidden" autocomplete="username" value="aigw-provider" aria-hidden="true" tabindex="-1"><label>Name<input name="name" required placeholder="openai-primary"></label><label>Protocol<select name="protocol"><option value="openai">OpenAI</option><option value="anthropic">Anthropic</option></select></label><label>Base URL<input name="base_url" type="url" required placeholder="https://api.example.com/v1"></label><label>API key<input name="api_key" type="password" required autocomplete="new-password" placeholder="Stored encrypted"></label><button class="button primary" type="submit">Add provider</button></form>
+ <form class="panel form-grid" id="provider-form" data-permission="platform.write"><input class="visually-hidden" name="username" autocomplete="username" value="aigw-provider" aria-hidden="true" tabindex="-1"><label>Name<input name="name" autocomplete="off" required placeholder="openai-primary"></label><label>Protocol<select name="protocol"><option value="openai">OpenAI</option><option value="anthropic">Anthropic</option></select></label><label>Base URL<input name="base_url" type="url" autocomplete="off" required placeholder="https://api.example.com/v1"></label><label>API key<input name="api_key" type="password" required autocomplete="new-password" placeholder="Stored encrypted"></label><button class="button primary" type="submit">Add provider</button></form>
<div class="panel table-wrap"><table><thead><tr><th>Name</th><th>Protocol</th><th>Base URL</th><th>Routes</th><th>Status</th><th></th></tr></thead><tbody id="providers-body"></tbody></table></div>
</section>
<section id="models" class="section">
<div class="section-heading"><div><span class="eyebrow">ROUTING</span><h1>Models & routes</h1></div></div>
- <form class="panel form-grid" id="model-form" data-permission="platform.write"><label>Public model ID<input name="public_id" required placeholder="openai/gpt-4.1-mini"></label><label>Owned by<input name="owned_by" placeholder="openai"></label><label>Input price / 1M<input name="input_price" inputmode="decimal" value="0" required></label><label>Output price / 1M<input name="output_price" inputmode="decimal" value="0" required></label><label>Cache read / 1M<input name="cache_read_price" inputmode="decimal" value="0" required></label><label>Cache write / 1M<input name="cache_write_price" inputmode="decimal" value="0" required></label><div class="route-editor" id="route-editor"></div><button class="button subtle" type="button" id="add-route">Add route</button><button class="button primary" type="submit">Create model</button></form>
+ <form class="panel form-grid" id="model-form" data-permission="platform.write"><label>Public model ID<input name="public_id" required placeholder="openai/gpt-4.1-mini"></label><label>Display name<input name="display_name" placeholder="GPT 4.1 mini"></label><label>Owned by<input name="owned_by" placeholder="openai"></label><label>Lifecycle<select name="lifecycle"><option value="preview">Preview</option><option value="active" selected>Active</option><option value="deprecated">Deprecated</option><option value="retired">Retired</option></select></label><label>Description<input name="description" placeholder="Fast general-purpose text model"></label><label>Context window<input name="context_window" type="number" min="0" value="0"></label><label>Max output tokens<input name="max_output_tokens" type="number" min="0" value="0"></label><label>Capabilities<input name="capabilities" value="chat,streaming" placeholder="chat,streaming,tools,json"></label><label>Input modalities<input name="input_modalities" value="text" placeholder="text,image"></label><label>Output modalities<input name="output_modalities" value="text" placeholder="text,image"></label><label>Regions<input name="regions" placeholder="us-east,nz"></label><label>Deprecated aliases<input name="aliases" placeholder="old/model-id"></label><label>Tenant allowlist IDs<input name="allowed_tenant_ids" placeholder="UUIDs, blank is public"></label><label>API key allowlist IDs<input name="allowed_key_ids" placeholder="UUIDs, blank is unrestricted"></label><label>Input price / 1M<input name="input_price" inputmode="decimal" value="0" required></label><label>Output price / 1M<input name="output_price" inputmode="decimal" value="0" required></label><label>Cache read / 1M<input name="cache_read_price" inputmode="decimal" value="0" required></label><label>Cache write / 1M<input name="cache_write_price" inputmode="decimal" value="0" required></label><div class="route-editor" id="route-editor"></div><button class="button subtle" type="button" id="add-route">Add route</button><button class="button primary" type="submit">Create model</button></form>
<div class="panel table-wrap"><table><thead><tr><th>Public ID</th><th>Owner</th><th>Routes</th><th>Status</th><th></th></tr></thead><tbody id="models-body"></tbody></table></div>
</section>
<section id="billing" class="section">
- <div class="section-heading"><div><span class="eyebrow">REVENUE</span><h1>Balances & ledger</h1></div><span class="currency-label" id="billing-currency"></span></div>
+ <div class="section-heading"><div><span class="eyebrow">REVENUE</span><h1>Balances & ledger</h1></div><div class="form-actions"><button class="button secondary" id="billing-portal" data-permission="billing.topup">Customer portal</button><button class="button subtle" id="billing-export" data-permission="billing.read">Export CSV</button><button class="button subtle" id="billing-reconcile" data-permission="billing.adjust">Reconcile Stripe</button><span class="currency-label" id="billing-currency"></span></div></div>
<div class="billing-actions">
<form class="panel form-grid compact-form" id="topup-form" data-permission="billing.topup"><label>Tenant<select name="tenant_id" id="topup-tenant" required></select></label><label>Amount<input name="amount" inputmode="decimal" min="0" required placeholder="25.00"></label><button class="button primary" type="submit">Open Stripe Checkout</button></form>
<form class="panel form-grid compact-form" id="adjustment-form" data-permission="billing.adjust"><label>Tenant<select name="tenant_id" id="adjustment-tenant" required></select></label><label>Signed amount<input name="amount" inputmode="decimal" required placeholder="10.00 or -5.00"></label><label>Reference<input name="description" maxlength="240" placeholder="Support credit"></label><button class="button secondary" type="submit">Post adjustment</button></form>
@@ -143,6 +143,10 @@
<div class="panel table-wrap"><table><thead><tr><th>Tenant</th><th>Balance</th><th>Reserved</th><th>Available</th><th>Updated</th></tr></thead><tbody id="billing-accounts-body"></tbody></table></div>
<div class="section-heading ledger-heading"><div><span class="eyebrow">AUDIT</span><h2>Recent ledger entries</h2></div></div>
<div class="panel table-wrap"><table><thead><tr><th>Time</th><th>Tenant</th><th>Kind</th><th>Amount</th><th>Balance after</th><th>Reference</th></tr></thead><tbody id="billing-ledger-body"></tbody></table></div>
+ <div class="section-heading ledger-heading"><div><span class="eyebrow">PAYMENTS</span><h2>Top-ups, invoices & refunds</h2></div></div>
+ <div class="panel table-wrap"><table><thead><tr><th>Created</th><th>Amount</th><th>Status</th><th>Reconciliation</th><th>Documents</th><th>Action</th></tr></thead><tbody id="billing-orders-body"></tbody></table></div>
+ <div class="panel table-wrap"><table><thead><tr><th>Created</th><th>Order</th><th>Amount</th><th>Status</th><th>Failure</th></tr></thead><tbody id="refunds-body"></tbody></table></div>
+ <div class="panel table-wrap"><table><thead><tr><th>Updated</th><th>Amount</th><th>Status</th><th>Reason</th><th>Due</th></tr></thead><tbody id="disputes-body"></tbody></table></div>
</section>
<section id="limits" class="section">
@@ -160,9 +164,9 @@
<div class="section-heading"><div><span class="eyebrow">SECURITY</span><h1>Account</h1></div></div>
<form class="panel form-grid compact-form" id="password-form"><input class="visually-hidden" name="username" autocomplete="username" aria-hidden="true" tabindex="-1"><label>Current password<input name="current_password" type="password" required autocomplete="current-password"></label><label>New password<input name="new_password" type="password" required minlength="12" maxlength="128" autocomplete="new-password"></label><button class="button primary" type="submit">Change password</button></form>
<div class="account-grid">
- <form class="panel form-grid compact-form" id="totp-begin-form"><h2>Authenticator app</h2><input class="visually-hidden" autocomplete="username" aria-hidden="true" tabindex="-1"><label>Current password<input name="current_password" type="password" required autocomplete="current-password"></label><label class="hidden" id="totp-disable-code">Authenticator code<input name="code" inputmode="numeric" autocomplete="one-time-code"></label><button class="button secondary" id="totp-action" type="submit">Set up TOTP</button></form>
+ <form class="panel form-grid compact-form" id="totp-begin-form"><h2>Authenticator app</h2><input class="visually-hidden" name="username" autocomplete="username" aria-hidden="true" tabindex="-1"><label>Current password<input name="current_password" type="password" required autocomplete="current-password"></label><label class="hidden" id="totp-disable-code">Authenticator code<input name="code" inputmode="numeric" autocomplete="one-time-code"></label><button class="button secondary" id="totp-action" type="submit">Set up TOTP</button></form>
<form class="panel form-grid compact-form hidden" id="totp-confirm-form"><h2>Confirm authenticator</h2><img id="totp-qr" alt="TOTP QR code"><code id="totp-secret"></code><label>Code<input name="code" inputmode="numeric" autocomplete="one-time-code" required></label><button class="button primary" type="submit">Enable TOTP</button></form>
- <form class="panel form-grid compact-form" id="passkey-form"><h2>Passkey</h2><input class="visually-hidden" autocomplete="username" aria-hidden="true" tabindex="-1"><label>Current password<input name="current_password" type="password" required autocomplete="current-password"></label><label>Passkey name<input name="name" value="This device" required></label><button class="button secondary" type="submit">Add passkey</button></form>
+ <form class="panel form-grid compact-form" id="passkey-form"><h2>Passkey</h2><input class="visually-hidden" name="username" autocomplete="username" aria-hidden="true" tabindex="-1"><label>Current password<input name="current_password" type="password" required autocomplete="current-password"></label><label>Passkey name<input name="name" autocomplete="off" value="This device" required></label><button class="button secondary" type="submit">Add passkey</button></form>
</div>
<div class="panel table-wrap"><div class="section-heading"><h2>Devices</h2><button class="button subtle" id="revoke-other-sessions" type="button">Sign out other devices</button></div><table><thead><tr><th>Device</th><th>IP</th><th>Method</th><th>Last seen</th><th></th></tr></thead><tbody id="sessions-body"></tbody></table></div>
<div class="panel table-wrap"><div class="section-heading"><h2>Passkeys</h2></div><table><thead><tr><th>Name</th><th>Created</th><th>Last used</th><th></th></tr></thead><tbody id="passkeys-body"></tbody></table></div>