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
- Czy migrować bms-1 na Vercel teraz?
- Czy przepisać aplikację od nowa zamiast migrować?
- Jaki model danych dla nowego systemu? (Mongo / Supabase / JSONB hybrid)
- Co analizować dalej?
1. Czy migrować bms-1 na Vercel teraz?
Argumenty ZA migracją teraz
| Argument | Waga |
|---|---|
| bms-1 Ubuntu 20.04 EOL — brak security patches | Wysoka |
v41-prod Angular frontend — lokalny untagged image, nieodtwarzalny po restarcie | Krytyczna |
| Brak docker-compose w git — konfiguracja istnieje tylko w pamięci działających kontenerów | Wysoka |
| GitLab runner broken (403 od 2026-06-29) — CD pipeline zepsuty | Wysoka |
| Vercel = automatyczne deploys, zero-downtime, CDN dla Angular SPA | Umiarkowana |
Argumenty PRZECIW migracji teraz
| Argument | Waga |
|---|---|
| 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 kodu | Wysoka |
| Jeśli i tak planujemy przepisać app od nowa → migracja starego kodu = zmarnowana praca | Krytyczna |
| wkhtmltopdf, WebSocket — wymagają alternatyw (dodatkowy czas + koszt) | Umiarkowana |
| MongoDB rs0 zostaje na bms serwerach — nie eliminuje konieczności utrzymania infra | Umiarkowana |
Rekomendacja dla Vercel
NIE migruj teraz — ale zabezpiecz się natychmiast przed krytycznymi ryzykami:
| Akcja | Czas | Cel |
|---|---|---|
Wyeksportuj v41-prod image do Wasabi | 2h | Eliminuje ryzyko utraty frontendu |
| MongoDB dump → Wasabi (automatyczny cron) | 4h | PR #2371 już otwarty |
docker inspect wszystkich kontenerów → commit do repo | 2h | Backup konfiguracji |
| Re-rejestracja GitLab runnera | 1h | Przywró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:
| Produkt | Klienci | Funkcje |
|---|---|---|
| W3 / RESO | RESO EUROPA (data feed), Gratus | Rejestry dokumentów, import Excel, postbook (książka nadawcza) |
| W4 | Keller, ZPK, MOW Malbork, Bibus Menos, Zhonghua, Valmont | Rejestry (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
| Pole | w3_db | w4_db | Znaczenie |
|---|---|---|---|
clientId | ✅ ObjectId | ❌ brak | W3 ma dodatkową warstwę tenancy pod officeId |
workspaceId / workspaceSlug | ❌ brak | ✅ String + ObjectId | W4 dodał workspace jako grupę klientów |
responsibleEmail / responsibleId | ❌ brak | ✅ | W4 dodał osobę odpowiedzialną per rekord |
instanceId, processId, processStatusId, processStatusLabel, psTrans, statusInitTime | ✅ | ❌ brak | W3 ma silnik workflow/procesowy, W4 go usunął |
deletedTime | ✅ Date | ❌ (tylko deleted: Boolean) | W3 loguje kiedy usunięto |
modificatorDate / modificatorDateTime | String (nie Date!) | String | Bug 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:
| regId | w3_db records | w4_db records |
|---|---|---|
5d36d905903f5002cca1e57e | 625 436 | 627 700 |
64faf16888863301c2d53fc7 | 258 582 | 258 582 |
5d40392915ec4a5764c2fc02 | 136 048 | 136 168 |
5d36d91c903f5002cca1e581 | 116 291 | 117 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.)
| Ranking | regId | Łączne rekordy | Biura |
|---|---|---|---|
| 1 | 58f5f38e... | 3 565 975 | 2 (RESO + inne) |
| 2 | 5d36d905... | 625 436 | 1 |
| 3 | 5f200a16... | 427 027 | 1 |
| 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ę:
- Dane W3 → transformuj do nowego schematu (jednorazowy ETL script)
- Dane W4 → w razie potrzeby, ta sama ścieżka
- Wasabi S3 → Supabase Storage lub zostaje Wasabi (kompatybilne API)
- 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.
| Temat | Co zbadać |
|---|---|
| Struktura rejestrów | w3_db.regRecords grouped by regId — ile rejestrów, ile rekordów każdy |
| Modele formularzy | Kolekcja registries/forms w w3_db — schemat każdego rejestru |
| Import Excel | Kolekcja importSchemas — jak są zdefiniowane schematy kolumn |
| Postbook | Jak jest oznaczana korespondencja wychodząca, jakie statusy, jak generowany raport |
| Gratus — sprawy prawne | regRecords z regId dla spraw, podrejestry (terminy), powiązania przez zmienną |
| Gratus — kalendarz | Skąd dane kalendarza, czy to regRecords czy osobna kolekcja |
| Gratus — korespondencja | Rejestry przychodzącej i wychodzącej — osobne regId? osobna kolekcja? |
| Frontend Angular W3 | Jak zbudowany dity table (lista rekordów), formularz rejestru, widok kalendarza |
Sesja architektury nowego systemu (po sesji RESO)
Cel: projekt techniczny nowej aplikacji.
| Temat | Co projektować |
|---|---|
| Stack | Next.js 14 App Router + Supabase vs. Next.js + MongoDB Atlas |
| Schema Supabase | Tabele: offices, registers, records, import_schemas, correspondences |
| Migracja danych W3 → nowy model | ETL script: w3_db.regRecords → Supabase records |
| Import Excel | API endpoint: POST /import + schemat mapowania kolumn |
| Postbook | Logika oznaczania + generowanie raportu PDF |
| Wieloklientowość | RLS per office_id, czy SaaS czy multi-tenant |
| Hosting | Vercel (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