CluPilotCloud/app/Models
nexxo 4e3beca759 Close the domain page to packages that may not have one
The rule was decided in CustomDomainAccess but nothing asked it on the way
in: /domain answered every customer on every package, so the entry package
could set a domain it is not sold and cannot keep.

The guard sits in mount(), not on the route. A Livewire component answers
POSTs to /livewire/update by itself, so a route-only check would have left
save() and the rest reachable to exactly the customers it was meant to stop.

The sidebar asks the same question through a gate rather than a second copy
of the rule — a customer holds no permissions at all (R21 puts all seventeen
on the operator guard), so can() had nothing to filter on and the tab was
shown to everyone, leading straight into the 403 the page now raises.

Customer::forUser() carries the resolution the Livewire concern used to own,
because the gate has to answer outside any component and a second copy of
its email fallback is how the two would drift apart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 16:20:21 +02:00
..
Builders feat(billing): a proof register, and modules frozen at their booked price 2026-07-26 13:07:34 +02:00
Concerns feat(engine): core provisioning data model + hosts 2026-07-25 09:49:43 +02:00
Backup.php feat(engine-b): customer domain models + migrations 2026-07-25 11:38:01 +02:00
Customer.php Close the domain page to packages that may not have one 2026-07-29 16:20:21 +02:00
Datacenter.php Let a datacenter code be corrected while nothing depends on it, and say which building 2026-07-28 22:25:21 +02:00
DnsRecord.php feat(engine-b): customer domain models + migrations 2026-07-25 11:38:01 +02:00
ExportTarget.php Let a destination say how it is laid out and how long anything stays 2026-07-29 03:08:27 +02:00
Host.php Read VPN host state from the synced peer table, not a live hub call 2026-07-29 00:18:21 +02:00
Incident.php Rebuild the status page as a status page 2026-07-29 12:45:18 +02:00
IncidentUpdate.php Rebuild the status page as a status page 2026-07-29 12:45:18 +02:00
Instance.php Prove a custom domain before serving it, and keep proving it 2026-07-29 14:47:51 +02:00
InstanceMetric.php Measure availability, and let a customer move down again 2026-07-27 16:41:15 +02:00
InstanceTraffic.php feat(traffic): meter the monthly allowance, show it, throttle instead of blocking 2026-07-25 23:33:47 +02:00
Invoice.php Let the export have as many destinations as somebody wants 2026-07-29 02:43:15 +02:00
InvoiceExport.php Let the export have as many destinations as somebody wants 2026-07-29 02:43:15 +02:00
InvoiceSeries.php Lay the foundation for self-issued invoices: series, numbers, frozen documents 2026-07-29 00:57:06 +02:00
LoginSession.php Recognise the devices an account signs in from, and warn about a new one 2026-07-28 23:28:34 +02:00
Mailbox.php Clear every mailbox's verification when the shared server config changes 2026-07-28 06:36:06 +02:00
MaintenanceNotification.php fix(admin): in-flight claim (claimed_at) for exactly-once maintenance send; scope permission rollback 2026-07-25 16:38:44 +02:00
MaintenanceWindow.php fix(portal): scope the per-instance maintenance badge to that instance's host 2026-07-25 19:12:33 +02:00
MonitoringTarget.php Move the console off /admin, give the status page its own address, and measure monitoring 2026-07-27 06:05:40 +02:00
OnboardingTask.php feat(engine-b): customer domain models + migrations 2026-07-25 11:38:01 +02:00
Operator.php Give the people who run CluPilot a table of their own 2026-07-28 09:20:54 +02:00
Order.php Let a subscription or add-on be opened for free, with who and why on the row 2026-07-29 12:41:06 +02:00
PlanFamily.php Let the owner mark one plan as recommended, from the console 2026-07-29 14:22:22 +02:00
PlanPrice.php feat(billing): the plan catalogue becomes three tables, and config stops selling 2026-07-26 12:05:56 +02:00
PlanVersion.php feat(billing): the plan catalogue becomes three tables, and config stops selling 2026-07-26 12:05:56 +02:00
ProvisioningRun.php feat(engine): core provisioning data model + hosts 2026-07-25 09:49:43 +02:00
ProvisioningStepEvent.php feat(engine): core provisioning data model + hosts 2026-07-25 09:49:43 +02:00
RunResource.php feat(engine): core provisioning data model + hosts 2026-07-25 09:49:43 +02:00
Seat.php feat(portal): settings page — company profile, branding (logo+colors), cancel package, close account 2026-07-25 14:36:52 +02:00
StatusDay.php Rebuild the status page as a status page 2026-07-29 12:45:18 +02:00
StripePendingEvent.php feat(billing): Stripe owns the billing cycle, we own capability 2026-07-26 13:36:28 +02:00
Subscription.php Let a subscription or add-on be opened for free, with who and why on the row 2026-07-29 12:41:06 +02:00
SubscriptionAddon.php Let a subscription or add-on be opened for free, with who and why on the row 2026-07-29 12:41:06 +02:00
SubscriptionRecord.php feat(billing): Stripe owns the billing cycle, we own capability 2026-07-26 13:36:28 +02:00
SupportRequest.php Editing in modals, an update button that is not gated on a stale reading, and a support page that is real 2026-07-27 17:55:49 +02:00
User.php Require a confirmed address before an account can use anything 2026-07-28 23:43:20 +02:00
UserDevice.php Repair two comment blocks the admin-hosts edit ran together 2026-07-28 23:20:43 +02:00
VpnPeer.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00