Pinbox24 — Decyzje strategiczne 2026-07

Autor: Claude Code (p24-infra admin) Data: 2026-07-01 Kontekst: Po zakończeniu analizy infrastruktury i bazy klientów — patrz system-analysis.md


Pytania do rozstrzygnięcia

  1. Czy migrować bms-1 na Vercel teraz?
  2. Czy przepisać aplikację od nowa zamiast migrować?
  3. Jaki model danych dla nowego systemu? (Mongo / Supabase / JSONB hybrid)
  4. Co analizować dalej?

1. Czy migrować bms-1 na Vercel teraz?

Argumenty ZA migracją teraz

ArgumentWaga
bms-1 Ubuntu 20.04 EOL — brak security patchesWysoka
v41-prod Angular frontend — lokalny untagged image, nieodtwarzalny po restarcieKrytyczna
Brak docker-compose w git — konfiguracja istnieje tylko w pamięci działających kontenerówWysoka
GitLab runner broken (403 od 2026-06-29) — CD pipeline zepsutyWysoka
Vercel = automatyczne deploys, zero-downtime, CDN dla Angular SPAUmiarkowana

Argumenty PRZECIW migracji teraz

ArgumentWaga
3–4 miesiące pracy przy małej bazie klientów (7 W4 + 2 W3)Wysoka
Backend v42-prod nie nadaje się na serverless bez refaktoryzacji — wymaga audytu koduWysoka
Jeśli i tak planujemy przepisać app od nowa → migracja starego kodu = zmarnowana pracaKrytyczna
wkhtmltopdf, WebSocket — wymagają alternatyw (dodatkowy czas + koszt)Umiarkowana
MongoDB rs0 zostaje na bms serwerach — nie eliminuje konieczności utrzymania infraUmiarkowana

Rekomendacja dla Vercel

NIE migruj teraz — ale zabezpiecz się natychmiast przed krytycznymi ryzykami:

AkcjaCzasCel
Wyeksportuj v41-prod image do Wasabi2hEliminuje ryzyko utraty frontendu
MongoDB dump → Wasabi (automatyczny cron)4hPR #2371 już otwarty
docker inspect wszystkich kontenerów → commit do repo2hBackup konfiguracji
Re-rejestracja GitLab runnera1hPrzywrócenie CD pipeline

Koszt: ~1 dzień pracy. Eliminuje P1 ryzyka bez 3–4 miesięcznej migracji.

Wyjątek: Fronteny Angular (W4 + W3) → Vercel warto zrobić teraz — to 1 tydzień, zero ryzyka, natychmiastowy benefit (CDN, zero downtime deploys, eliminacja untagged image problemu).


2. Czy przepisać aplikację od nowa?

Skala problemu

Aktywni klienci to faktycznie dwa produkty:

ProduktKlienciFunkcje
W3 / RESORESO EUROPA (data feed), GratusRejestry dokumentów, import Excel, postbook (książka nadawcza)
W4Keller, ZPK, MOW Malbork, Bibus Menos, Zhonghua, ValmontRejestry (regRecords), procesy, pliki (Wasabi)

W3 klienci korzystają ze starego Angular 7 na silniku który ma broken MongoDB driver i jest nieodtwarzalny po restarcie. To jest tykająca bomba.

Opcje

Opcja A — Patch & Survive (status quo +)

  • Napraw krytyczne ryzyka (backup, image export, runner)
  • Zostaw kod w spokoju
  • Kiedy: Gdy nie ma zasobów developerskich

Pro: 0 nowej pracy na kod. Con: Dług techniczny rośnie; W3 może przestać działać w każdej chwili; bms-1 EOL.

Opcja B — Migracja na Vercel (istniejący kod)

  • Przenieś Angular frontendy na Vercel Static (1 tydz.)
  • Refaktoryzuj Node.js backend do Vercel Functions (4–8 tygodni)
  • Zostaw MongoDB rs0 na bms

Pro: Eliminuje bms-1 ryzyko operacyjne. Con: 3–4 miesiące pracy na kod który być może piszemy od nowa.

Opcja C — Przepisanie dedykowanej aplikacji dla W3 (RESO + Gratus)

  • Next.js (App Router) + nowa baza (MongoDB lub Supabase)
  • Tylko funkcje których faktycznie używa RESO i Gratus
  • Migracja danych W3 → nowy model

Pro: Czysty kod, nowoczesny stack, eliminuje legacy całkowicie. Con: Wymaga głębokiej analizy funkcji (osobna sesja), trudno oszacować czas bez znajomości zakresu.

Opcja D — SaaS: jedna platforma dla wszystkich klientów (W3 + W4)

  • Jeden Next.js app który obsługuje wszystkich 9 klientów
  • Wspólna baza z rozdzieleniem po officeId
  • Ujednolicony model danych

Pro: Eliminuje dualność W3/W4; jeden deployment; skalowalność. Con: Scope znacznie większy niż opcja C; model danych W3 i W4 różny (wymaga konwersji).

Rekomendacja wstępna

Opcja C jako pierwszy krok, z otwartą ścieżką do D.

Uzasadnienie:

  • RESO EUROPA i Gratus to klienci W3 o najwyższym ryzyku (broken stack, EOL server)
  • Zakres funkcji W3 jest ograniczony: rejestry + import + postbook + kalendarz Gratus
  • Przepisanie W3 jest możliwe bez głębokiej wiedzy o W4
  • Po przepisaniu W3 → łatwiejsza decyzja czy wciągnąć W4 do tej samej platformy

Dla W4: W4 backend działa stabilnie (Keller, ZPK, MOW Malbork niezmienne przez 18 miesięcy). Nie wymaga natychmiastowej akcji — zrób Vercel frontend + backup, resztę zostaw.


3. Model danych dla nowego systemu

Obecny model W3 vs W4 — wyniki z MongoDB (2026-07-01)

Różnice na poziomie dokumentu regRecords

Polew3_dbw4_dbZnaczenie
clientId✅ ObjectId❌ brakW3 ma dodatkową warstwę tenancy pod officeId
workspaceId / workspaceSlug❌ brak✅ String + ObjectIdW4 dodał workspace jako grupę klientów
responsibleEmail / responsibleId❌ brakW4 dodał osobę odpowiedzialną per rekord
instanceId, processId, processStatusId, processStatusLabel, psTrans, statusInitTime❌ brakW3 ma silnik workflow/procesowy, W4 go usunął
deletedTime✅ Date❌ (tylko deleted: Boolean)W3 loguje kiedy usunięto
modificatorDate / modificatorDateTimeString (nie Date!)StringBug w obu — data jako string

Kluczowy wniosek: W3 → W4 to nie ewolucja modelu — to usunięcie silnika procesowego i dodanie workspace. Zawartość recordData (dane formularza) jest strukturalnie taka sama w obu wersjach.

Architektura rejestrów — dynamiczny silnik formularzy

Znalezione kolekcje w w3_db: registries, forms, formsTemplates, formsData, tmp.registries, tmp.forms

registries — lekkie metadane:

_id, name, type, regAccess, slug
actions[]: { default_label, translations, sort, placement, module, application, access_level }

forms — schemat pól per biuro:

_id, officeId, title, formTemplate
treeStructure[]: { id, title, tabRows, nodes }   ← układ zakładek/wierszy
fields[]: {
  control_type, label, title, id,
  regId,           ← link do rejestru
  type, sort, tabRow, tabColumn,
  options[], formVisibility{}, gridVisibility{}
}

To jest silnik formularzy no-code: biuro ma własne forms (per officeId) które definiują pola i układ. Pola odsyłają do regId — jeden formularz może obejmować wiele rejestrów. Dane formularza lądują jako recordData w regRecords.

KRYTYCZNE odkrycie: wspólny katalog rejestrów W3 i W4

Te same regId ObjectIds pojawiają się w obu bazach z porównywalną liczbą rekordów:

regIdw3_db recordsw4_db records
5d36d905903f5002cca1e57e625 436627 700
64faf16888863301c2d53fc7258 582258 582
5d40392915ec4a5764c2fc02136 048136 168
5d36d91c903f5002cca1e581116 291117 191

Implikacja: w3_db i w4_db to nie oddzielne produkty — dzielą ten sam katalog rejestrów. Klienci W3 i W4 korzystają z tych samych definicji rejestrów (registries collection), prawdopodobnie z jednej wspólnej bazy metadanych. Największy rejestr (58f5f38e...) ma 3,56M rekordów łącznie — to RESO EUROPA jako integracja danych nieruchomości.

Skala danych W3 (całkowita, nie ostatnie 6 mies.)

RankingregIdŁączne rekordyBiura
158f5f38e...3 565 9752 (RESO + inne)
25d36d905...625 4361
35f200a16...427 0271
Top 20 łącznie~6M+

W3_db ma łącznie ~1500+ unikalnych regId — większość to małe rejestry (1 rekord), ale kilkadziesiąt to główne rejestry operacyjne.

Trzy opcje modelu dla nowego systemu

Model A — MongoDB (nowy kolekcja, nowy schemat)

registers (definicje rejestrów, formularzy, schematów importu)
records (wszystkie rekordy — wszystkich klientów, wszystkich rejestrów)
  - officeId: ObjectId (tenant isolation)
  - registerId: ObjectId (do którego rejestru)
  - data: { ...pola zdefiniowane przez formularz... }
  - createdAt, updatedAt, deletedAt
importSchemas (mapowania kolumn Excel → pola formularza)

Pro: Brak migracji storage, MongoDB już istnieje na bms-2/3. Con: Brak relacji (trudne zapytania cross-record), brak pełnoprawnego RLS.

Model B — Supabase (PostgreSQL + JSONB)

-- Tabela rekordów z JSONB dla danych formularza
CREATE TABLE records (
  id uuid PRIMARY KEY,
  office_id uuid NOT NULL,
  register_id uuid NOT NULL,
  data jsonb NOT NULL,           -- cała zawartość formularza
  -- szybkie indeksy na najczęstsze pola:
  record_number text,            -- sygnatura/numer
  status text,
  created_at timestamptz,
  source_version text,           -- 'w3' | 'w4' (skąd pochodzi rekord)
  CONSTRAINT fk_office FOREIGN KEY (office_id) REFERENCES offices(id)
);
CREATE INDEX records_data_gin ON records USING gin(data);
CREATE INDEX records_office_register ON records(office_id, register_id);

Pro: SQL joins, RLS per-tenant, pełnotekstowe wyszukiwanie, Supabase Auth, Supabase Storage dla plików (Wasabi można zastąpić). Con: Migracja MongoDB → Postgres; team uczy się nowego storage.

Model C — Hybrid JSONB (propozycja użytkownika)

Jeden model dla W3 i W4:
- Wyekstrahuj "szybkie indeksy" jako kolumny (record_number, status, date, officeId, registerId)
- Całą resztę wrzuć jako jsonb/data
- Pole source_version: 'w3' | 'w4' pozwala parsować różnie
- Backend wie jak czytać w zależności od source_version

Zaleta: migracja historycznych danych bez transformacji — wgrywamy as-is,
        backend obsługuje parsowanie przy odczycie
Wada: złożoność w warstwie odczytu; dwie ścieżki parsowania na zawsze

Ocena hybrydowego modelu C:

Pomysł jest dobry pod warunkiem, że “szybkie indeksy” obejmą 90% zapytań. Ryzyko: jeśli business logic zależy od specyficznych pól w jsonb (np. filtry po statusie korespondencji w postbooku), dostajemy data->>'field' wszędzie w SQL — trudniejsze do utrzymania. Rekomendacja: zdefiniuj najpierw jakie są zapytania (raporty, filtry, wyszukiwanie) a dopiero potem wybierz co idzie jako kolumna a co do jsonb.

Rekomendacja modelu

Supabase (Model B) dla nowej aplikacji, z migracją danych przez transformację:

  1. Dane W3 → transformuj do nowego schematu (jednorazowy ETL script)
  2. Dane W4 → w razie potrzeby, ta sama ścieżka
  3. Wasabi S3 → Supabase Storage lub zostaje Wasabi (kompatybilne API)
  4. MongoDB rs0 → zostaje dla W4 klientów dopóki nie zostaną zmigrowane

Dlaczego nie MongoDB dla nowego systemu:

  • Supabase daje RLS, Auth, Storage, Realtime out-of-the-box
  • PostgreSQL + JSONB = elastyczność + SQL joins
  • Już mamy Supabase (projekt mwkqmgadqnkkihjdeqsi) i wiedzę w zespole

4. Co analizować dalej — plan sesji

Sesja RESO (odrębna, dedykowana)

Cel: pełne zrozumienie funkcjonalności W3 dla RESO EUROPA i Gratus.

TematCo zbadać
Struktura rejestróww3_db.regRecords grouped by regId — ile rejestrów, ile rekordów każdy
Modele formularzyKolekcja registries/forms w w3_db — schemat każdego rejestru
Import ExcelKolekcja importSchemas — jak są zdefiniowane schematy kolumn
PostbookJak jest oznaczana korespondencja wychodząca, jakie statusy, jak generowany raport
Gratus — sprawy prawneregRecords z regId dla spraw, podrejestry (terminy), powiązania przez zmienną
Gratus — kalendarzSkąd dane kalendarza, czy to regRecords czy osobna kolekcja
Gratus — korespondencjaRejestry przychodzącej i wychodzącej — osobne regId? osobna kolekcja?
Frontend Angular W3Jak zbudowany dity table (lista rekordów), formularz rejestru, widok kalendarza

Sesja architektury nowego systemu (po sesji RESO)

Cel: projekt techniczny nowej aplikacji.

TematCo projektować
StackNext.js 14 App Router + Supabase vs. Next.js + MongoDB Atlas
Schema SupabaseTabele: offices, registers, records, import_schemas, correspondences
Migracja danych W3 → nowy modelETL script: w3_db.regRecords → Supabase records
Import ExcelAPI endpoint: POST /import + schemat mapowania kolumn
PostbookLogika oznaczania + generowanie raportu PDF
WieloklientowośćRLS per office_id, czy SaaS czy multi-tenant
HostingVercel (Next.js) + Supabase cloud

5. Decyzja do podjęcia teraz

Zanim zaczniemy pisać kod lub planować architekturę, potrzebna jest decyzja:

Pytanie 1: Czy przepisujemy W3 (RESO + Gratus) jako pierwszą fazę, zostawiając W4 na bms-1? → Tak / Nie / Potrzeba więcej analizy

Pytanie 2: Supabase czy MongoDB dla nowego systemu? → Supabase (rekomendacja) / MongoDB / Potrzeba analizy modelu danych

Pytanie 3: SaaS (jeden system dla wszystkich) czy dedykowana apka dla W3? → SaaS / Dedykowana / Zdecydujemy po analizie RESO+Gratus

Pytanie 4: Angular W4 fronteny → Vercel teraz (niezależnie od reszty)? → Tak (1 tydzień, niskie ryzyko) / Nie


Dokument żywy — uzupełnić po wynikach analizy RESO/Gratus i decyzji o modelu danych. Powiązane: system-analysis.md · docs/evaluation/04-pinbox24-map-dr-audit.md