5.3 KiB
5.3 KiB
Phase D — Service framing, redesign & CRUD completeness
Status: approved (brainstorming + Codex consultation 2026-07-25).
Branch: feat/portal-design. Rules R1–R17 apply.
Follow-up to the second UX review. Codex consultation stored decisions; user confirmed:
- Plans keep current storage (Start 100 GB / Team 500 GB / Business 1 TB / Enterprise 2 TB); hide vCPU/RAM from customers; add seats (5 / 25 / 100 / 500 — Enterprise is limited too) and a performance class (Standard/Enhanced/High/Dedicated) + feature list.
- Cancellation: effective at end of billing term, no grace period, irreversible once set; at term end the customer receives a finished data export, then deprovision. Account closure only when no active packages.
- Build D1 then D2 straight through; report each phase when green.
D1 — Fixes & redesign (low-risk, mostly UI)
- Billing button bug.
wire:loading.attr="disabled"lackswire:target, so any purchase spins/disables all buttons. Fix: scopewire:targetper button + addwire:keyon loop items. - Service framing.
config/provisioning.phpplans gainseats(5/25/100/500) andperformance(standard/enhanced/high/dedicated). Customer views (Billing, Dashboard, Cloud) show storage · seats · performance · features — never vCPU/RAM. A "Technische Infos" block may show Nextcloud/PHP version, region, service URL, backup location. Admin views keep raw specs. - Charts → gradient line. Extend the chart island (
resources/js/app.js) to build a canvas linear gradient (line colour → transparent) forfillline datasets. Convert the three time-series bar charts (Admin Overview MRR, Backups 14-day, Invoices spend) to gradient line. Admin Overview "Host-Auslastung" is categorical (per-host) — redesigned as capacity bars inside the host section, not a misleading line. - Dashboard/MRR layout. Chart must fill its card (min-height / aspect) so the box is not larger than the chart; intuitive ordering.
/frontend-design. - Host list scaling. Replace the fixed cards with a dense, searchable/filterable (by datacenter + status) table/grid that scales to many hosts.
/frontend-design. - Host detail redesign. Show health from
last_seen_at(online/stale/offline), status, capacity breakdown (committed/available/reserve), RAM, CPU, hosted-instances list, version, node, mgmt/WG IP, current run + events./frontend-design. - Datacenter edit + delete (guarded). Edit name/location (code immutable once referenced); delete only when 0 hosts, else block; activate/deactivate already exists.
- Admin CRUD audit fixes. Host: edit
reserve_pct+ maintenance/drain toggle. Customer: edit profile + suspend. Instances/orders/runs stay guarded/append-only.
D2 — Customer self-service (new pages)
- Settings (
/settings): edit company/billing profile (company name, contact, billing address, VAT ID, phone); cancel package (typed-confirm modal → schedules at term end, irreversible, statuscancellation_scheduled, export produced at term end — mocked); close account (guarded: no active packages; setsclosed_at; retains financial records). - Branding (in Settings): logo upload (PNG/WebP, MIME-validated, ≤2 MB), display name, primary + accent colour; stored at customer level,
NULL→ CluPilot defaults via a resolver; snapshot resolved branding into the provisioning run context at start so retries stay deterministic. Live preview. - Users/seats (
/users): invite / edit role / revoke / resend against the plan seat limit; guard: cannot revoke the last owner. Seats are portal-managed records (invites mocked).
Data model (additive migrations)
customers:billing_address(text, null),vat_id(null),phone(null),contact_name(null),brand_display_name(null),brand_logo_path(null),brand_primary_color(null),brand_accent_color(null),closed_at(timestamp, null).instances:cancel_requested_at(null),service_ends_at(null); status gainscancellation_scheduled.seatstable:id,customer_idfk,email,name(null),role(owner/admin/member/readonly),status(invited/active/revoked),invited_at, timestamps; unique(customer_id,email).- Provisioning:
StartCustomerProvisioningwritescontext['branding']= resolved snapshot.
CRUD verdicts (Codex-guided)
| Entity | Verdict |
|---|---|
| Datacenters | create · edit · activate/deactivate · delete only if unused |
| Hosts | create · edit (reserve, drain/maintenance) · delete only if no instances/active runs |
| Customers | edit profile · suspend · close (guarded) — no routine hard-delete |
| Instances | cancel (scheduled) · deprovision via lifecycle — identity/history immutable |
| Orders/invoices | orders cancellable before fulfilment; finalized invoices immutable |
| Seats | invite · edit role · revoke · resend — cannot remove last owner |
| Provisioning runs | append-only; pending cancellable, failed retryable (new attempt) |
| Addons/subscriptions | add · schedule change · cancel — preserve price snapshots |
Verification (per phase + final)
Pest green · DE+EN key parity (R16) · R12 Puppeteer 0 console errors on new/changed pages (production build) · R15 Codex loop --base 80348d6 until clean · migrate/seed dev · push.