feat(billing): add billing_mode to providers (postpaid support) & UI/migration
Some checks failed
CI / Check (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Formatting (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Release Build (push) Has been cancelled

This commit is contained in:
2026-03-03 15:37:19 -05:00
parent 75b68521c8
commit 1453e64d4b
4 changed files with 77 additions and 35 deletions

View File

@@ -70,6 +70,10 @@ class ProvidersPage {
<span>Balance: ${provider.id === 'ollama' ? 'FREE' : window.api.formatCurrency(provider.credit_balance)}</span>
${isLowBalance ? '<i class="fas fa-exclamation-triangle" title="Low Balance"></i>' : ''}
</div>
<div class="meta-item">
<i class="fas fa-exchange-alt"></i>
<span>Billing: ${provider.billing_mode ? provider.billing_mode.toUpperCase() : 'PREPAID'}</span>
</div>
<div class="meta-item">
<i class="fas fa-clock"></i>
<span>Last used: ${provider.last_used ? window.api.formatTimeAgo(provider.last_used) : 'Never'}</span>
@@ -163,16 +167,23 @@ class ProvidersPage {
<label for="provider-api-key">API Key (Optional / Overwrite)</label>
<input type="password" id="provider-api-key" placeholder="••••••••••••••••">
</div>
<div class="grid-2">
<div class="form-control">
<label for="provider-balance">Current Credit Balance ($)</label>
<input type="number" id="provider-balance" value="${provider.credit_balance}" step="0.01">
<div class="grid-2">
<div class="form-control">
<label for="provider-balance">Current Credit Balance ($)</label>
<input type="number" id="provider-balance" value="${provider.credit_balance}" step="0.01">
</div>
<div class="form-control">
<label for="provider-threshold">Low Balance Alert ($)</label>
<input type="number" id="provider-threshold" value="${provider.low_credit_threshold}" step="0.50">
</div>
</div>
<div class="form-control">
<label for="provider-threshold">Low Balance Alert ($)</label>
<input type="number" id="provider-threshold" value="${provider.low_credit_threshold}" step="0.50">
<label for="provider-billing-mode">Billing Mode</label>
<select id="provider-billing-mode">
<option value="prepaid" ${!provider.billing_mode || provider.billing_mode === 'prepaid' ? 'selected' : ''}>Prepaid</option>
<option value="postpaid" ${provider.billing_mode === 'postpaid' ? 'selected' : ''}>Postpaid</option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" onclick="this.closest('.modal').remove()">Cancel</button>
@@ -187,17 +198,19 @@ class ProvidersPage {
const enabled = modal.querySelector('#provider-enabled').checked;
const baseUrl = modal.querySelector('#provider-base-url').value;
const apiKey = modal.querySelector('#provider-api-key').value;
const balance = parseFloat(modal.querySelector('#provider-balance').value);
const threshold = parseFloat(modal.querySelector('#provider-threshold').value);
const balance = parseFloat(modal.querySelector('#provider-balance').value);
const threshold = parseFloat(modal.querySelector('#provider-threshold').value);
const billingMode = modal.querySelector('#provider-billing-mode').value;
try {
await window.api.put(`/providers/${id}`, {
enabled,
base_url: baseUrl || null,
api_key: apiKey || null,
credit_balance: isNaN(balance) ? null : balance,
low_credit_threshold: isNaN(threshold) ? null : threshold
});
await window.api.put(`/providers/${id}`, {
enabled,
base_url: baseUrl || null,
api_key: apiKey || null,
credit_balance: isNaN(balance) ? null : balance,
low_credit_threshold: isNaN(threshold) ? null : threshold,
billing_mode: billingMode || null,
});
window.authManager.showToast(`${provider.name} configuration saved`, 'success');
modal.remove();