nexxo
406f753311
fix(admin): remove is_admin self-heal — RBAC is the only console boundary (no revocation bypass)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:35:14 +02:00
nexxo
22cbe9ac39
fix(auth/admin): atomic user+customer signup; Rule::in for country validation (comma-safe)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:33:09 +02:00
nexxo
6ca1e3fba5
fix(auth): create + link a Customer on public signup so the portal works pre-purchase
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:31:08 +02:00
nexxo
39a1f708a1
fix(auth): reject signup with an existing customer email (account-claim guard)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:29:35 +02:00
nexxo
507ab485a0
fix(admin): derive legacy datacenter location allowlist from DB, not client property
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:27:41 +02:00
nexxo
3a794b05dd
fix(admin): promote only role-less legacy admins; allow editing datacenters with legacy free-form location
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:26:09 +02:00
nexxo
fd7cba7403
fix(admin): authorize datacenter modal mounts; stale threshold uses step maxDuration
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:23:44 +02:00
nexxo
2b73a895c9
fix(admin): don't flag scheduled-backoff runs as stale; edit-datacenter country validation from config
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:21:22 +02:00
nexxo
8304f2e7dc
fix(admin): self-heal legacy is_admin into Owner (no RBAC bypass); validate datacenter country server-side
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:19:24 +02:00
nexxo
88957f8f57
feat(auth): enterprise split login + signup (Fortify registration) via frontend-design
...
- login/register redesigned as a split brand-panel + clean form (Apple-ish
enterprise look), cross-linked; brand panel uses accent gradient + tokens
- Fortify registration enabled; /register full-page Livewire + RegisterTest
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:16:27 +02:00
nexxo
be99f413f7
feat(admin): provisioning liveness — per-run progress bar, last-activity, stale warning
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:11:17 +02:00
nexxo
b50f97568f
fix(admin): no admin lockout (is_admin fallback); centered modal width; datacenter edit modal + country dropdown
...
- isOperator()/EnsureAdmin/broadcast fall back to is_admin so a legacy admin is
never locked out by a stale permission cache
- published modal: centered max-w-lg card (dynamic modalWidth class was purged
by Tailwind → full-width)
- datacenter edit moved to a modal (no row-height jump); location is now a
country dropdown (config/countries.php) instead of free text
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:09:17 +02:00
nexxo
87a81f5f40
fix(admin): read-only send-time guard (never drop mail on retry); document exactly-once residual for real-mail outbox
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:40:44 +02:00
nexxo
e09965f918
fix(admin): in-flight claim (claimed_at) for exactly-once maintenance send; scope permission rollback
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:38:44 +02:00
nexxo
28221549d1
fix(admin): defer maintenance sent_at to real delivery; read-only send-time dedup (no lost mail)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:35:52 +02:00
nexxo
0cc5be5479
fix(admin): atomic send-time delivery claim so backlog duplicates ship exactly once
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:34:02 +02:00
nexxo
5b85806605
fix(admin): catch racing ledger insert and re-fetch (idempotent under concurrency)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:31:43 +02:00
nexxo
72731112f4
fix(admin): atomically claim maintenance notification retries under a row lock
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:30:17 +02:00
nexxo
8bb93137a3
refactor(admin): extract MaintenanceNotifier; atomic provisioning retry; catch-up cancellation for race-delivered announcements
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:28:02 +02:00
nexxo
ae1f78f534
fix(admin): shown-once temp password for invited staff; suppress announcements for cancelled windows at send time
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:23:21 +02:00
nexxo
718e8568c1
fix(admin): require host on any maintenance save; cancel-notify only delivered announcements
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:19:44 +02:00
nexxo
62b4d85ef7
fix(admin): release notification claim on dispatch failure so retries aren't blocked
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:17:44 +02:00
nexxo
ab5ba2b169
fix(admin): dedup pending maintenance notifications (updated_at claim + staleness threshold)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:16:15 +02:00
nexxo
493b81aadf
fix(admin): confirm maintenance delivery via MessageSent (retryable until sent); guard resend/cancel on derived state; fix flaky non-unique host wg_ip
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:14:01 +02:00
nexxo
52fa7a34a2
feat(admin): email affected customers when maintenance is cancelled (ledger-guarded)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:07:21 +02:00
nexxo
6593dae946
fix(admin): retry path for missed maintenance emails; lock Owner role to serialize last-owner guard
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:04:31 +02:00
nexxo
bc2e95ba18
fix(admin): block role escalation of non-staff; validate maintenance host ids atomically; rollback ledger on dispatch failure
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 16:01:45 +02:00
nexxo
e5c74c6bdd
fix(admin): reject customer email on operator account update; do not claim mail delivery on dispatch
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:58:24 +02:00
nexxo
d68d8e1f25
fix(rbac/mail): migrate legacy is_admin users to Owner in-migration; send maintenance mail in customer locale
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:56:22 +02:00
nexxo
eff8c08258
feat(admin): maintenance windows — schedule once, assign many hosts, notify
...
- maintenance_windows + host pivot + notification ledger; derived state (never
stored); affected-customer + banner queries live off instances
- admin /maintenance: create draft/publish, multi-host select, impact counts,
cancel; capability-gated (maintenance.manage)
- publish emails affected customers once (queued Mailable, ledger-idempotent)
- customer portal maintenance banner (upcoming <=72h + active) merged per window
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:53:50 +02:00
nexxo
c5d60340b7
feat(admin): staff RBAC (spatie) + admin settings page
...
- 5 operator roles (Owner/Admin/Support/Billing/Read-only) seeded via migration
with a capability catalogue; app checks capabilities via Gate, never role names
- every mutating admin action authorizes server-side (hosts/datacenters/customers/
impersonate/provisioning); is_admin reads migrated to console.view / isOperator()
- admin /settings: own account + Owner-only staff invite/role/revoke with
last-owner, self-role and customer-collision guards (transactional)
- sidebar 'zum Kundenportal' link replaced with Settings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:47:42 +02:00
nexxo
4336c3bb3f
feat(brand): CluPilot logo mark + SVG favicon across layouts
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:31:33 +02:00
nexxo
08f61b43f5
fix(ui): modal above sidebar (z-index); datacenter edit buttons stay right; toast slides from bottom; provisioning retry action
...
- modal wrapper z-10 -> z-[70] (was behind the z-40 sidebar); toasts slide up/down
- datacenter inline-edit colspan fix so save/cancel stay right-aligned
- admin provisioning: retry a failed run (table + panel), mirrors host-detail retry
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:29:37 +02:00
nexxo
99081284a4
fix(portal): delete old logo only after the branding update commits
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:04:27 +02:00
nexxo
f6efa4f200
fix(portal): allow closure after failed provisioning; serialize last-owner guard
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:02:37 +02:00
nexxo
8bcb5ec268
fix(admin): enforce hosts.datacenter FK (restrictOnDelete) — no deactivation side-effect
...
The DB now refuses to orphan a host; datacenter delete pre-checks for a friendly
message and catches the constraint as the race backstop.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 15:00:38 +02:00
nexxo
249efa0553
fix: serialize datacenter delete (lock+deactivate+recheck); store logo before deleting old
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:58:07 +02:00
nexxo
01383e7e5e
fix(portal): race-safe owner-seat initialization (firstOrCreate + catch)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:55:09 +02:00
nexxo
3bf0dfb548
fix: seat limit + suspend guard per Codex; harden factory email uniqueness
...
- seat limit follows the active/cancelling package, not a newer inactive record
- suspend/reactivate toggle refuses closed accounts (terminal); closed shown in list
- factory emails use a large unique numeric space (safeEmail pool could collide
late in a full suite run)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:53:15 +02:00
nexxo
cbbb523f9c
fix(portal): cancel the active instance explicitly, not just the newest record
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:48:57 +02:00
nexxo
c011a11b48
fix(portal): atomic seat-limit (row lock) + billing-day-anchored cancellation date
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:47:04 +02:00
nexxo
074b0c041b
fix(portal): enforce customer lifecycle per Codex review
...
- EnsureCustomerActive middleware: suspended/closed customers lose portal
access (admins + active impersonation exempt)
- cancellation: reject non-active instances; service-end anchored on the
subscription start date, not calendar month-end
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:45:03 +02:00
nexxo
3b288486cd
feat(portal): seats management — invite/role/revoke against plan limit
...
- seats table + model; Users page manages team members (owner auto-created)
- invite respects plan seat allowance + dedupe; role change + revoke guarded
so the last owner can never be removed or demoted
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:40:18 +02:00
nexxo
df10448e5d
feat(portal): settings page — company profile, branding (logo+colors), cancel package, close account
...
- customers gain profile + branding + closed_at; instances gain cancellation
fields; branding resolver (NULL -> CluPilot defaults) snapshotted into the
provisioning run context
- cancel package: term-end, irreversible, typed-confirm modal (R5)
- close account: guarded (no active package), typed-confirm modal (R5)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:36:52 +02:00
nexxo
ef110b06db
feat(admin): host reserve edit + maintenance drain; customer suspend/reactivate
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:30:21 +02:00
nexxo
d3d686e575
feat(admin): scalable host list (search/filter/health) + host detail redesign
...
- host list: search + datacenter/status filters, dense table with heartbeat
health dot, instance count, capacity meter
- host detail: health hero (last_seen), storage/compute breakdown, technical
facts, hosted-instances table
- Host model: usedPct() + healthState() helpers
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:27:53 +02:00
nexxo
b44d25404d
test: widen DatacenterFactory code space (fix faker unique() pool exhaustion)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:23:49 +02:00
nexxo
54d9a05235
feat(admin): datacenter edit+delete (guarded); MRR chart fills card; host-load as meters
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:22:15 +02:00
nexxo
e3ab3cb501
feat(portal): service framing + gradient line charts + billing button fix
...
- plans gain seats + performance class; customer views show storage/seats/
performance/features, no raw vCPU/RAM (admin keeps specs)
- billing: scoped wire:target + wire:key so one purchase no longer spins all
- chart island: line-colour->transparent gradient for filled line datasets;
MRR / backups / invoices bar charts converted to gradient line
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:18:08 +02:00
nexxo
a3423a2cee
docs: Phase D spec — service framing, redesign & CRUD completeness
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 14:13:23 +02:00