Files
greeneclipse 8580c996c3 Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
2026-08-09 22:47:43 +02:00

71 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
1. **Plans table** — search + visibility filters (All / Public / Legacy / Custom) with counts.
2. **Badges** — Public (ladder FreeEnterprise), Legacy (A1, Basic, Professional, Mini, Merkur…), Custom (other client deals). Public + `is_custom` also shows “Custom package flag” (Enterprise).
3. **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 with `id` for edit).
4. **Assign plan** — dialog with company + plan selects, optional trial + trial credits; row actions from Plans and Companies. `POST /api/admin/plans/assign`.
5. **Link to permissions** — Plans row → Permissions tab with that plan selected (`PlanPermissionsPanel`).
6. **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
1. Platform admin → `/admin/billing` → Plans.
2. Filter Public / Legacy / Custom; search by name.
3. Create a custom plan; edit credits/description; confirm row badges.
4. Assign plan to a company (from Plans row or Companies → Assign plan); optional trial.
5. Click Permissions on a plan → Permissions tab opens with that plan selected.
6. 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.