NOVERA.Software

09 · Inżynieria

Jak zmiana trafia do produkcji.

Prace są dostarczane w numerowanych rundach; w bieżącej serii jest ich 454. Każda jest wyspecyfikowana, uzgodniona, zbudowana w całości, udowodniona i udokumentowana.

Rozstrzygnięcie

Macierz uzgodniona

Stan bazowy

Najpierw skróty

Budowa

Cała runda

Dowód

4 przeglądy · 37 bramek

Zatwierdzenie i weryfikacja

Skróty porównane po obu stronach

Stałe reguły

  • Sekrety znajdują się wyłącznie w systemowych zmiennych środowiskowych, nigdy w pliku, który może udostępnić serwer WWW.
  • Nie wolno dodać żadnego nowego pakietu. Dlatego Web Push, generator PDF i parser zaproszeń kalendarzowych są napisane ręcznie.
  • Żadnej zmiany schematu bez zgody, łącznie z indeksem. Każdy skrypt jest zabezpieczony, możliwy do ponownego uruchomienia i uruchamiany przez właściciela dla każdego katalogu.
  • Zaksięgowane dane księgowe nigdy nie są zmieniane w celu skompensowania problemu z prezentacją.

Co jest dokumentowane

Każda runda pozostawia notatkę opisującą, co się zmieniło i dlaczego, oraz rejestr założeń, w którym każdy osąd mogący okazać się błędny jest ponumerowany, opatrzony oceną ryzyka, oznaczony w kodzie obok wiersza, którego dotyczy, i opatrzony zapytaniem, które by go rozstrzygnęło.

Gdy decyzja odwraca wcześniejszą, wcześniejsze rozstrzygnięcie jest przekreślane i opatrywane adnotacją zamiast usuwania, dzięki czemu historia decyzji pozostaje czytelna nawet po latach.

Opis platformy

Środowisko programistyczne

Prace programistyczne odbywają się na dwóch maszynach, celowo utrzymywanych jako nierówne: pełnym środowisku na stacji roboczej programisty, na której znajduje się baza danych, oraz jednorazowym kontenerze w chmurze, w którym kod jest pisany i testowany zupełnie bez bazy danych.

Stacja robocza phoenix-dev26.

  • Rozwiązanie jest otwierane w Visual Studio z katalogu głównego projektu i uruchamiane pod Kestrel za pomocą profilu uruchomieniowego projektu pod adresem https://localhost:51880, z dodatkowym portem zwykłego HTTP, w środowisku Development.
  • Aplikacja łączy się bezpośrednio z SQL Server. Zgodnie z rozstrzygnięciem właściciela łączy się z katalogami produkcyjnymi zamiast z odtworzoną kopią deweloperską, za pomocą ciągu połączenia przechowywanego w systemowej zmiennej środowiskowej.
  • W pliku projektu istnieje identyfikator user secrets, lecz w praktyce nie jest używany; konfiguracja pochodzi ze środowiska.
  • Jedna znana pułapka: widoki Razor kompilują się do tego samego zestawu co modele stron, więc gdy zmiana w pliku .cs jest widoczna, a zmiana w pliku .cshtml nie, kompilacja przyrostowa ponownie używa nieaktualnego widoku. Rozwiązaniem jest usunięcie folderów obj i bin i ponowne zbudowanie.
  • Skrypty schematu są uruchamiane przez właściciela ręcznie, dla każdego katalogu, z jego własnego klienta SQL.
  • Jedno polecenie, verify.cmd, buduje rozwiązanie, uruchamia cztery sondy, startuje izolowaną instancję na własnym porcie, loguje się, otwiera wszystkie szesnaście stron raportów i pobiera każdą z nich jako PDF. Jego tryb przykładowy wykonuje ten sam przebieg na danych testowych (fixtures), zupełnie bez bazy danych.

Kontener w chmurze ma .NET 8 SDK, drzewo kompilacji i żadnej bazy danych.

  • Brak ciągu połączenia wybiera tryb przykładowy, w którym implementacje testowe magazynów danych finansowych, raportów, kalendarza, VAT i dokumentów odpowiadają na każde zapytanie; program uruchamiający odmawia startu, jeśli ciąg połączenia jest obecny.
  • Dane testowe są zbudowane z własnych dokumentów i liczb spółki, więc test może weryfikować wyniki względem liczb, które są już na papierze.
  • Przeglądarka bezgłowa (headless) steruje działającą aplikacją na potrzeby sond, zrzutów ekranu i renderowania PDF.
  • Lokalny zamiennik odpowiada w miejsce punktu końcowego AI oraz źródeł notowań rynkowych i kursów walut dokładnie przygotowanymi odpowiedziami, dzięki czemu arytmetykę można udowodnić bez udziału modelu.

Bramki. Dla każdej rundy uruchamianych jest trzydzieści siedem skryptów bramek i cztery przeglądy kodu źródłowego.

  • Niektóre są skanami statycznymi, które weryfikują właściwość kodu źródłowego, na przykład brak nienazwanej projekcji wewnątrz CTE albo brak długiego literału szesnastkowego w pliku konfiguracyjnym.
  • Cenniejsze są te, które sterują działającą aplikacją. Najkosztowniejsza lekcja tego projektu: test, który nigdy nie uruchamia tego, co uruchamia użytkownik, nie może wykryć błędu wykonania.
  • Bramki weryfikują regułę ustaloną w danej rundzie, a nie wyrażenie, które zostało wydane, i przed weryfikacją usuwają komentarze; tę poprawkę trzeba było wprowadzać czterokrotnie.

Przejście między maszynami. Pliki przechodzą przez mostek plików pulpitu według stałej procedury:

  • przed pierwszą edycją w rundzie dla każdego pliku, którego runda może dotyczyć, obliczany jest skrót na dysku stacji roboczej;
  • przed zatwierdzeniem te same pliki są ponownie przygotowywane i porównywane pod względem treści;
  • po zatwierdzeniu po obu stronach ponownie obliczane są skróty i porównywany jest łączny skrót.

"Wydane" to stwierdzenie dotyczące dysku stacji roboczej, nigdy kontenera kompilacji.

Wdrożenie kopiuje na serwer produkcyjny dokładnie cztery elementy: cały statyczny folder WWW, zestaw aplikacji, jego symbole i plik wykonywalny. Pliki konfiguracyjne nie są kopiowane, więc ustawienia i sekrety produkcyjne przetrwają wydanie. Po skopiowaniu pula aplikacji jest odświeżana, a lista kontrolna przed publikacją czyści token kondycji i potwierdza usunięcie klasy diagnostycznej.

Jak prace są specyfikowane, budowane i dowodzone

Prace są dostarczane w numerowanych rundach. Bieżąca wersja to v31.454, co pokazuje sposób prowadzenia projektu: wiele małych, kompletnych, zweryfikowanych dostaw zamiast długich gałęzi. Runda zaczyna się od prośby właściciela, jest przekształcana w macierz rozstrzygnięć, które właściciel akceptuje lub zmienia, a następnie jest wydawana w całości. Rundę dzieli się wyłącznie z powodu prac, których nie można jeszcze wykonać, na przykład nierozstrzygniętej diagnostyki lub decyzji, którą może podjąć tylko właściciel.

Każda runda pozostawia pisemny zapis.

  • Notatka rundy w dokumentacji projektu opisuje, co się zmieniło i dlaczego.
  • Rejestr założeń odnotowuje każdy osąd mogący okazać się błędny: ponumerowany, oznaczony w kodzie obok wiersza, którego dotyczy, opatrzony oceną ryzyka oraz zapytaniem SQL, które by go rozstrzygnęło.
  • Gdy decyzja odwraca wcześniejszą, wcześniejsze rozstrzygnięcie jest przekreślane i opatrywane adnotacją zamiast usuwania, dzięki czemu historia decyzji pozostaje czytelna.

Cztery stałe reguły określają, co można zrobić bez pytania:

  • Sekrety znajdują się wyłącznie w systemowych zmiennych środowiskowych, nigdy w pliku, który może udostępnić serwer WWW, i nigdy nie są wklejane do rozmowy.
  • Do projektu nie wolno dodać żadnego nowego pakietu, i dlatego implementacja Web Push, generator PDF oraz parser zaproszeń kalendarzowych są w całości napisane ręcznie.
  • Żadna zmiana schematu, łącznie z nowym indeksem, nie jest wprowadzana bez zgody właściciela, a każdy skrypt jest pisany tak, aby był zabezpieczony i możliwy do ponownego uruchomienia, i jest uruchamiany przez właściciela dla każdego katalogu.
  • Zaksięgowane dane księgowe nigdy nie są zmieniane w celu skompensowania problemu z prezentacją, a zapisy historyczne nigdy nie są masowo korygowane jako skutek uboczny poprawki.

Dowód ma charakter warstwowy.

  • Kompilacja musi być czysta.
  • Przeglądy sprawdzają kod źródłowy pod kątem znanych klas błędów.
  • Bramki weryfikują reguły.
  • Sondy sterują działającą aplikacją.
  • Ostatecznym sprawdzeniem jest zawsze porównanie skrótów z dyskiem stacji roboczej.

Gdy środowisko izolowane czegoś nie widzi, raport to stwierdza. Najwyraźniejszym przykładem jest SQL: w kontenerze kompilacji nie jest wykonywane żadne zapytanie, więc zmiana zapytania jest dowodzona statycznie i przez inspekcję, dopóki nie zostanie uruchomiona na katalogach produkcyjnych, i raport z rundy to odnotowuje.