Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
3.4 KiB
3.4 KiB
09 — Admin billing plans UI (agent 9/20)
Owns: Admin → Billing → Plans tab (table, filters, badges), create/edit plan dialogs, assign-plan UX, companies-tab assign shortcuts.
Does not own: Permissions tab / PlanPermissionsPanel (agent 8).
Entry: /admin/billing (gate: requirePlatformAdmin).
Delivered
- Plans table — search + visibility filters (All / Public / Legacy / Custom) with counts.
- Badges — Public (ladder Free–Enterprise), Legacy (A1, Basic, Professional, Mini, Merkur…), Custom (other client deals). Public +
is_customalso shows “Custom package flag” (Enterprise). - Create / edit — polished dialog: name, description, monthly/yearly credits, max products, term, custom flag; preview of visibility kind. Wired to
POST /api/admin/plans(upsert withidfor edit). - Assign plan — dialog with company + plan selects, optional trial + trial credits; row actions from Plans and Companies.
POST /api/admin/plans/assign. - Link to permissions — Plans row → Permissions tab with that plan selected (
PlanPermissionsPanel). - Companies polish — search, has/no active plan filter, Assign plan + Add credits actions; summary card for companies without a plan.
Source files
| File | Intent |
|---|---|
apps/web/src/routes/admin/billing/+page.svelte |
Host page: stats, tabs, dialogs, companies table |
apps/web/src/lib/components/admin/AdminPlansPanel.svelte |
Plans table + filters + row actions |
apps/web/src/lib/admin-billing-plans.ts |
Visibility classify/filter, upsert/assign API helpers |
API contract (existing)
| Method | Path | Use |
|---|---|---|
GET |
/api/admin/plans |
List all plans (ladder + deals) |
POST |
/api/admin/plans |
Upsert plan (id optional); body: name, description, monthly_credits, yearly_credits, max_products, is_custom, term |
POST |
/api/admin/plans/assign |
{ company_id, plan_id, is_trial?, trial_credits? } |
GET |
/api/admin/companies |
Companies + has_active_plan |
POST |
/api/admin/credits |
Adjust balance |
POST |
/api/admin/billing/run-cycles |
Due renewals |
Visibility rules (UI)
| Kind | Rule |
|---|---|
| Public | Name ∈ Free, Starter, Growth, Business, Enterprise (isDefaultPublicPlanName) |
| Legacy | Known migrated names: A1 (+ a1 … prefix), Basic, Professional, Mini, Merkur*, Meur, or name contains legacy |
| Custom | Everything else (client deals / is_custom non-ladder) |
ASSUMPTION: Backend may later expose an explicit is_legacy / profile field; until then UI classifies by name (aligned with IsPublicProductPlan + migrated deal set).
Manual verify
- Platform admin →
/admin/billing→ Plans. - Filter Public / Legacy / Custom; search by name.
- Create a custom plan; edit credits/description; confirm row badges.
- Assign plan to a company (from Plans row or Companies → Assign plan); optional trial.
- Click Permissions on a plan → Permissions tab opens with that plan selected.
- Companies filter “No active plan”; Add credits still works.
Coordination
- Agent 8 owns Permissions panel styling/profiles — do not rewrite
PlanPermissionsPanel. - Agent 5/19 may add explicit legacy profile on plans; when present, prefer API flag over name heuristics (additive).
- Agent 10 may deepen org/company management; this page only adds assign/credits filters needed for billing ops.