CluPilotCloud/lang/de
nexxo f00cbf18d3
tests / pest (push) Failing after 7m59s Details
tests / assets (push) Successful in 23s Details
tests / release (push) Has been skipped Details
Let an operator correct a customer's details
The console could show them and not touch them, so a moved office or a new
contact person meant impersonating the customer or editing the database by
hand. Both are worse than a form. R20: a modal, opened from the Stammdaten
tab, authorising again and reading the record itself rather than trusting
anything the browser hydrated.

Most of the work is in what saving must NOT quietly do.

The customer type is never reset to "nobody asked". The field opens on
"leave unchanged" precisely so that saving an address correction cannot
undo it — that answer decides whether a withdrawal right exists, and losing
it silently would be the expensive kind of quiet.

A changed VAT number is unverified from the moment it is stored — the
verification is bound to the value, so that happens by itself — but
`vat_id_verified_value` is left alone: it is the record of what WAS checked,
and clearing it would destroy the evidence rather than the claim.

The address is also the sign-in address and the key inbound mail is matched
by, so changing it moves the linked portal login in the same transaction and
puts it back to unverified, which is what Laravel's own profile update does
for the same reason: nobody has shown they can read the new address. No mail
is sent from here — the portal asks for the confirmation at the next
sign-in, and a mail an operator did not knowingly send is a surprise.

Three addresses are refused: one belonging to an operator (R21 — no index
spans the two tables, so it is checked), one belonging to another customer,
and one belonging to somebody else's user row, which can outlive or predate
a matching customer.

Not offered here, each for its own reason: `status`, because suspending has
consequences for access and a lifecycle switch hidden among address fields
is one somebody flips by accident; `stripe_customer_id`, because a wrong one
does not move a contract, it points our records at somebody else's payments;
the brand fields, because the customer sets those for themselves and an
operator overwriting a logo is not a correction. There is a test that fails
if any of them appears — with the comments stripped first, since the class
documents at length why they are absent and that documentation is not the
offence. This repository has fallen into that trap three times.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 23:18:46 +02:00
..
admin.php Show the customer, and write the answers once 2026-07-29 22:37:30 +02:00
admin_incidents.php Let an incident be deleted, and start measuring whether the hosts answer 2026-07-29 15:16:48 +02:00
admin_settings.php Quote what a person pays, and tab the settings page 2026-07-29 19:18:10 +02:00
auth.php Ask whether they are a consumer, and let one change their mind 2026-07-29 21:06:06 +02:00
backups.php feat(portal): full sidebar — Cloud, Users, Backups, Invoices, Support 2026-07-25 08:08:33 +02:00
billing.php Ask whether they are a consumer, and let one change their mind 2026-07-29 21:06:06 +02:00
capacity.php Take the order, park it, and say when it will be delivered 2026-07-29 18:50:46 +02:00
checkout.php Charge the price the website shows, and hand a withdrawal back in full 2026-07-29 22:42:02 +02:00
cloud.php Restart a machine, enforce the quota that was sold, end a route that ended 2026-07-29 18:28:28 +02:00
coming_soon.php Say EU, and stop promising to fix somebody else's deleted folder 2026-07-29 14:17:30 +02:00
common.php Recover silently from an expired session, and show a connection banner when offline 2026-07-28 21:36:21 +02:00
customer_detail.php Let an operator correct a customer's details 2026-07-29 23:18:46 +02:00
customer_message.php Show the customer, and write the answers once 2026-07-29 22:37:30 +02:00
dashboard.php Let the customer buy it themselves, and tab the integrations page 2026-07-29 19:42:28 +02:00
datacenters.php Let a datacenter code be corrected while nothing depends on it, and say which building 2026-07-28 22:25:21 +02:00
delivery.php Quote what a person pays, and tab the settings page 2026-07-29 19:18:10 +02:00
devices.php Recognise the devices an account signs in from, and warn about a new one 2026-07-28 23:28:34 +02:00
domain.php Serve the custom domain, not just announce it 2026-07-29 16:44:52 +02:00
edit_customer.php Let an operator correct a customer's details 2026-07-29 23:18:46 +02:00
errors.php Refuse a portal login for an address that already belongs to an operator 2026-07-28 14:42:16 +02:00
finance.php Quote what a person pays, and tab the settings page 2026-07-29 19:18:10 +02:00
hosts.php Show WireGuard tunnel state per host in the hosts list 2026-07-29 00:10:15 +02:00
impersonate.php feat(admin): impersonate customer portal — session login + return banner 2026-07-25 13:46:48 +02:00
inbox.php Read the support mailbox into the console 2026-07-29 21:41:29 +02:00
instances.php Pin the sidebar header and footer so only the nav list scrolls, and shorten two action labels that wrapped 2026-07-28 20:52:12 +02:00
integrations.php Read the support mailbox into the console 2026-07-29 21:41:29 +02:00
invoice.php Ask whether they are a consumer, and let one change their mind 2026-07-29 21:06:06 +02:00
invoice_mail.php Send the invoice with the invoice attached 2026-07-29 02:13:41 +02:00
invoices.php feat(portal): full sidebar — Cloud, Users, Backups, Invoices, Support 2026-07-25 08:08:33 +02:00
invoices_admin.php Write an invoice for work that came off no price list 2026-07-29 20:12:26 +02:00
mail.php Put customer instances on their own domain, and say which domains are ours 2026-07-29 16:03:13 +02:00
mail_log.php Keep a register of what was sent, and answer the customer from here 2026-07-29 21:02:36 +02:00
mail_settings.php Bound the mail test-send and real send to a timeout instead of hanging 2026-07-28 16:36:14 +02:00
maintenance.php Put every mail in one design, and confirm an order when the money arrives 2026-07-29 00:14:04 +02:00
new_invoice.php Write an invoice for work that came off no price list 2026-07-29 20:12:26 +02:00
order.php Let the customer buy it themselves, and tab the integrations page 2026-07-29 19:42:28 +02:00
orders.php Keep the shop window off the portal's front door 2026-07-29 00:26:22 +02:00
plans.php Paketversionen: Verkauf wieder aufnehmen und saubere Übergabe 2026-07-29 14:58:11 +02:00
provisioning.php Deliver the storage a customer actually buys 2026-07-29 19:13:10 +02:00
reset_password.php Give people a way back in, and put the URL in English 2026-07-29 16:50:29 +02:00
secrets.php Read the support mailbox into the console 2026-07-29 21:41:29 +02:00
security.php Put customer instances on their own domain, and say which domains are ours 2026-07-29 16:03:13 +02:00
sessions.php Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
settings.php Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
status.php Let an incident be deleted, and start measuring whether the hosts answer 2026-07-29 15:16:48 +02:00
support.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
templates.php Show the customer, and write the answers once 2026-07-29 22:37:30 +02:00
two_factor_setup.php Let a half-finished two-factor enrolment be cancelled, and rework the setup page 2026-07-28 22:25:27 +02:00
updating.php Stop root workers breaking every page, and let the panel be closed 2026-07-29 15:43:54 +02:00
users.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
verify_email.php Require a confirmed address before an account can use anything 2026-07-28 23:43:20 +02:00
vpn.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
withdrawal.php Charge the price the website shows, and hand a withdrawal back in full 2026-07-29 22:42:02 +02:00