CluPilotCloud/resources/views
nexxo b3081a544b
tests / pest (push) Failing after 7m35s Details
tests / assets (push) Successful in 21s Details
tests / release (push) Has been skipped Details
Let the export have as many destinations as somebody wants
One path and one exported_at could not say "on the office NAS, not yet on the
off-site box" — which is the only interesting question once there is more than
one destination, and the reason for a second is precisely that any single one
can fail. A row per destination now, and a row per (invoice, destination) pair.

Two kinds, and the difference is where the protocol lives. 'local' is a
directory this machine can already write to: a NAS mounted over NFS 4.1, a bind
mount, a disk. The application knows nothing about the protocol, the target
changes without code changing with it, and the whole thing stays testable
against a temporary directory. 'sftp' is for something reachable with
credentials — a Hetzner Storage Box being the obvious one — and the password
goes into the secret vault with only its key on the row, because a credential
in a settings table is a credential in every database dump. An empty password
field on an existing target means unchanged, not cleared: the field cannot show
what is stored, so blank-means-delete would wipe it on every unrelated edit.

One job per pair rather than one per invoice. A job writing to both would retry
the one that worked every time the other did not, and report one outcome for
two different things.

The ordering fix the tests found: Laravel's local adapter creates its root when
it is CONSTRUCTED, so the "never create the root" guard was checking a
directory the disk had just made for it. It runs before the disk is built now.
That guard is the difference between an archive and a hole in the ground — mkdir
on an absent mountpoint succeeds, writes onto the container's own disk and
reports success, and an archive that silently is not the archive is worse than
none.

The single path from the previous commit is migrated into a destination called
"Archiv" rather than dropped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 02:43:15 +02:00
..
components List issued invoices in the console, with no way to change one 2026-07-29 02:21:15 +02:00
errors Refuse a portal login for an address that already belongs to an operator 2026-07-28 14:42:16 +02:00
layouts Answer a check at once, start an update at once, and count down to neither 2026-07-28 22:25:07 +02:00
livewire Let the export have as many destinations as somebody wants 2026-07-29 02:43:15 +02:00
mail Send the invoice with the invoice attached 2026-07-29 02:13:41 +02:00
pdf Issue an invoice from what somebody bought, and freeze it there 2026-07-29 02:09:05 +02:00
vendor/wire-elements-modal fix(admin): no admin lockout (is_admin fallback); centered modal width; datacenter edit modal + country dropdown 2026-07-25 18:09:17 +02:00
coming-soon.blade.php One design system for every surface 2026-07-27 16:03:47 +02:00
landing.blade.php Say EU and stop there, as the approved template does 2026-07-28 09:19:24 +02:00
legal.blade.php feat(landing): public marketing homepage at / (+ legal placeholders) 2026-07-25 08:59:39 +02:00
status.blade.php Show times on the operator's clock, keep storing them in UTC 2026-07-27 17:32:21 +02:00
welcome.blade.php feat(portal): design foundation — Tailwind v3, tokens, self-hosted fonts 2026-07-25 00:43:01 +02:00