Sechs Folgepunkte aus den heutigen Pruefungen ins Register
Sie standen bisher nur in Arbeitsdateien unter .superpowers/, und die sind nicht Teil des Repos — beim naechsten Aufraeumen waeren sie weg. Das Register ist der Ort, an dem der Betreiber sie sieht. Zwei davon sind echte Fehler im laufenden Betrieb: Die Zahlungssperre ruft shutdownVm() unbedingt, ohne zu fragen, ob der Gast laeuft. Ein Kunde, dessen Maschine aus anderem Grund steht, bekommt seine Sperre nie — der Lauf wirft, jede Nacht neu, und die Nachricht geht nie hinaus. Gefunden, als eine geschaerfte Proxmox-Attrappe aufdeckte, dass neun Mahnwesen-Pruefungen nur deshalb gruen waren, weil die alte Attrappe die Bitte gegen eine stehende Maschine klaglos annahm. Und ein abgebrochener vzdump laeuft nach dem Wurf weiter und schreibt sein Vollarchiv fertig — auf dieselbe Ablage, auf der die naechtlichen Sicherungen aller anderen Kunden dieses Hosts liegen. Damit stehen zwoelf Punkte im Register, aber KEINER mehr in der Gruppe "verkauft und nicht geliefert". Das war heute Morgen anders.feat/versandtakt
parent
100bc7e2f6
commit
8c1985d924
|
|
@ -77,6 +77,48 @@ final class OpenWork
|
|||
'missing' => 'Zu jedem Modul soll ein Modal erklären, warum es das Modul gibt und worauf es aufbaut, damit „mal dabei, mal dazubuchbar" keine Frage mehr aufwirft. Sinnvoll erst, wenn die zwei nicht gelieferten Module etwas tun.',
|
||||
'risk' => 'Ohne die Erklärung bleibt die Preistafel an der Stelle missverständlich, an der sie am meisten kostet.',
|
||||
],
|
||||
[
|
||||
'title' => 'Die Zahlungssperre fällt über eine Maschine, die schon steht',
|
||||
'state' => self::PARTIAL,
|
||||
'where' => 'App\\Actions\\SuspendInstance',
|
||||
'missing' => 'Sie ruft `shutdownVm()` unbedingt, ohne vorher zu fragen, ob der Gast überhaupt läuft. `ShutDownVirtualMachine` macht an derselben Stelle genau das Gegenteil und steigt bei einer stehenden Maschine sauber aus. Gefunden, als eine geschärfte Proxmox-Attrappe im Abbau-Vorhaben aufdeckte, dass neun Mahnwesen-Prüfungen nur deshalb grün waren, weil die alte Attrappe die Bitte gegen eine stehende Maschine klaglos annahm.',
|
||||
'risk' => 'Ein Kunde, dessen Maschine aus einem anderen Grund steht, bekommt seine Sperre nie — der Lauf wirft, jede Nacht neu, und die Sperr-Nachricht geht nie hinaus. AdvanceDunning fängt je Fall ab, also stirbt still genau dieser eine.',
|
||||
],
|
||||
[
|
||||
'title' => 'Ein abgebrochener vzdump läuft weiter und füllt die Ablage',
|
||||
'state' => self::PARTIAL,
|
||||
'where' => 'App\\Actions\\ArchiveAndTearDown → awaitTask()',
|
||||
'missing' => 'Reisst die Sicherung beim Abbau die Zeitgrenze, wirft awaitTask() — bricht den Auftrag auf dem Knoten aber nicht ab (kein DELETE /nodes/{node}/tasks/{upid}). Der Dump schreibt sein Vollarchiv fertig, und die nächste Nacht fängt von vorn an.',
|
||||
'risk' => 'Auf derselben Ablage liegen die nächtlichen Sicherungen ALLER anderen Kunden dieses Hosts. Eine einzige grosse gekuendigte Instanz kann sie nach ein paar Nächten volllaufen lassen, und dann scheitern die Sicherungen zahlender Kunden.',
|
||||
],
|
||||
[
|
||||
'title' => 'nc_synced_at vermerkt die Antwort des Gastes, nicht den Zustand der Nextcloud',
|
||||
'state' => self::PARTIAL,
|
||||
'where' => 'App\\Provisioning\\Jobs\\SyncSeatToNextcloud, App\\Livewire\\Users → queueSync()',
|
||||
'missing' => 'Geht die Antwort nach einem geglückten `user:add` verloren (Zeitüberlauf, Verbindungsabbruch), existiert das Konto und der Zeitstempel bleibt leer. queueSync() weigert sich danach dauerhaft, ein `disable` zu schicken. Der richtige Weg wäre, den Gast per `user:info` zu fragen, statt der eigenen Buchführung zu glauben.',
|
||||
'risk' => 'Ein Inhaber entzieht einen Zugang, die Zeile sagt "entzogen", und das Nextcloud-Konto bleibt offen. Niemand sieht es.',
|
||||
],
|
||||
[
|
||||
'title' => 'Sitzaufträge teilen sich den einen Arbeiter mit der bezahlten Bereitstellung',
|
||||
'state' => self::PLANNED,
|
||||
'where' => 'App\\Provisioning\\Jobs\\SyncSeatToNextcloud, docker/provisioning-worker.sh',
|
||||
'missing' => 'Beide laufen auf der `provisioning`-Warteschlange, die von genau einem seriellen Arbeiter bedient wird. Ein haengender Gast kann ihn bis zu 35 Minuten belegen. Eine eigene Schlange (`seats`) mit einem zweiten queue:work im selben Container löste es — der Tunnel hängt am Container, nicht am Schlangennamen.',
|
||||
'risk' => 'Zehn Einladungen je Kunde und Stunde sind erlaubt. Bei zwanzig Kunden können zweihundert Aufträge vor einer frisch bezahlten Bestellung in derselben Reihe stehen.',
|
||||
],
|
||||
[
|
||||
'title' => 'Der Aufräumlauf für abgelaufene Archive fehlt',
|
||||
'state' => self::PLANNED,
|
||||
'where' => 'App\\Livewire\\Admin\\Instances → ARCHIVE_MONTHS',
|
||||
'missing' => 'Die zugesagte Aufbewahrung beträgt zwölf Monate. Der Abschnitt in der Konsole blendet nach Ablauf aus, was noch dasteht — gelöscht wird nichts. Es gibt keinen Lauf, der die Frist durchsetzt.',
|
||||
'risk' => 'Das Archiv bleibt auf der Ablage liegen, und archive_volid — die einzige Angabe, mit der man es wiederfindet — ist ab dann nirgends mehr sichtbar. Der Speicher wächst still weiter.',
|
||||
],
|
||||
[
|
||||
'title' => 'Ein nie eingeladener Sitz steht auf "eingeladen"',
|
||||
'state' => self::PARTIAL,
|
||||
'where' => 'App\\Livewire\\Users → addSeat()',
|
||||
'missing' => 'Anlegen schreibt `status = invited`, obwohl niemand eingeladen wurde. In der Anzeige überdeckt nc_state das; in der Datenbank steht eine Unwahrheit. Ein eigener Status `added` braucht die Wanderung UND die Anpassung von fünf Lesestellen: Users::usedSeats(), Dashboard::seats(), Dashboard::seatBreakdown(), DowngradeCheck und EditSeat::addressEditable.',
|
||||
'risk' => 'Heute tragend, nicht kosmetisch: genau weil `invited` dasteht, stimmen Dashboard-Zähler, Downgrade-Sperre und Benutzerseite überein. Wer den Status ändert, ohne alle fünf Stellen mitzunehmen, lässt die Zahlen auseinanderlaufen.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue