RESO + Gratus — Brief analizy (sesja dedykowana)

Przygotowano: 2026-07-01 Cel sesji: Zinwentaryzować funkcjonalności RESO EUROPA i Gratus na W3 tak, żeby podjąć decyzję o architekturze nowego systemu (Next.js + Supabase / Next.js + MongoDB). Kontekst strategiczny: strategic-decisions-2026-07.md Dane klientów: system-analysis.md


Co już wiemy (nie powtarzać w sesji)

Architektura Pinbox24 (znana)

  • Silnik formularzy: kolekcja registries (metadane) + forms (schemat pól per biuro)
  • Dane: regRecords — jeden dokument per rekord, recordData zawiera dane formularza
  • Shared registry catalog: te same regId ObjectIds w w3_db i w4_db — klienci W3 i W4 dzielą definicje rejestrów
  • W3 vs W4 różnica: W3 ma silnik procesowy (instanceId, processId, processStatusId) którego W4 nie ma; W4 dodał workspaceId, responsibleEmail
  • Skala w3_db: ~6M+ rekordów łącznie, największy rejestr (58f5f38e...) — 3,56M rekordów

Znane klienty W3

KlientofficeIdRekordy/6 mies.
RESO EUROPA590c6d334704d811efc9fd5a35 150
Gratus5bae738807770e585186308b409

Wstępna wiedza o funkcjach (od użytkownika)

RESO EUROPA:

  • Rejestry dokumentów (regRecords z regId)
  • Import z Excela: plik → wybór schematu kolumn → mapowanie kolumn na pola → wybrany rejestr
  • Postbook (książka nadawcza): status korespondencji wychodzącej, batch-dodawanie do raportu

Gratus:

  • Rejestry spraw prawnych (jeden formularz dla wszystkich, ale złożony)
  • Podrejestry: łączenie rekordów zmienną (powiązane wpisy, podsprawy = terminy)
  • Kalendarz (prawdopodobnie osobna kolekcja lub regRecords z specjalnym regId)
  • Korespondencja przychodząca i wychodząca (osobne rejestry)
  • Książka adresowa skojarzona ze sprawami

Plan sesji — co zbadać krok po kroku

Blok 1: Inwentaryzacja rejestrów RESO i Gratus

Cel: Które regId należą do RESO, które do Gratus, co każdy rejestr robi.

// Wszystkie unikalne regId dla RESO EUROPA w w3_db
db.w3_db.regRecords.aggregate([
  { $match: { officeId: ObjectId("590c6d334704d811efc9fd5a") } },
  { $group: { _id: "$regId", count: { $sum: 1 }, formIds: { $addToSet: "$formId" } } },
  { $sort: { count: -1 } }
])
 
// Dla Gratus
db.w3_db.regRecords.aggregate([
  { $match: { officeId: ObjectId("5bae738807770e585186308b") } },
  { $group: { _id: "$regId", count: { $sum: 1 }, formIds: { $addToSet: "$formId" } } },
  { $sort: { count: -1 } }
])

Następnie dla każdego regId — lookup w registries:

db.w3_db.registries.find({ _id: ObjectId("...") })

→ Wynik: nazwa rejestru, typ, dostępne akcje, slug

Blok 2: Schemat formularzy (forms collection)

Cel: Jakie pola ma formularz każdego rejestru, jakie typy kontrolek.

// Formularze RESO
db.w3_db.forms.find({ officeId: ObjectId("590c6d334704d811efc9fd5a") })
 
// Formularze Gratus
db.w3_db.forms.find({ officeId: ObjectId("5bae738807770e585186308b") })

Dla każdego formularza zmapować:

  • Liczba pól
  • Typy kontrolek (control_type): text, date, select, lookup, richtext, file, etc.
  • Pola z regId (cross-registry references)
  • Układ (liczba zakładek, wierszy)

→ Wynik: schemat każdego rejestru jako lista pól z typami — to fundament pod projektowanie nowego modelu danych

Blok 3: Próbne rekordy RESO — co ląduje w recordData

Cel: Zobaczyć rzeczywistą strukturę danych jednego rekordu RESO (i Gratus).

// Ostatni rekord RESO w największym rejestrze
db.w3_db.regRecords.find(
  { 
    officeId: ObjectId("590c6d334704d811efc9fd5a"),
    regId: ObjectId("<top-regId-RESO>")
  }
).sort({ createdAt: -1 }).limit(2)

→ Wynik: co dokładnie jest w recordData, jakie klucze, jakie typy wartości

Blok 4: Import Excel — schemat importu

Cel: Jak jest zdefiniowany schemat importu (mapowanie kolumn Excel → pola rejestru).

Szukać kolekcji: importSchemas, importConfigs, excelImports, importTemplates

db.w3_db.getCollectionNames().filter(n => n.includes('import') || n.includes('Import'))

Próbny dokument schematu importu dla RESO:

db.w3_db.<importCollection>.find({ officeId: ObjectId("590c6d334704d811efc9fd5a") }).limit(2)

→ Wynik: struktura schematu importu — jak zdefiniowane kolumny, jak mapowanie na pola, jak wybór rejestru

Blok 5: Postbook — książka nadawcza

Cel: Jak jest obsługiwana korespondencja wychodząca i postbook.

Szukać w kolekcjach: postbooks, postBook, correspondences, outgoing lub specjalny regId w regRecords.

db.w3_db.getCollectionNames().filter(n => 
  n.includes('post') || n.includes('Post') || 
  n.includes('corr') || n.includes('book')
)

Jeśli postbook to regId w regRecords — zbadać które regId ma signature z prefixem sugerującym korespondencję (np. KW/, PO/):

db.w3_db.regRecords.find(
  { officeId: ObjectId("590c6d334704d811efc9fd5a"), signature: /^(KW|PO|KB)\// }
).limit(3)

→ Wynik: czy postbook to osobna kolekcja czy rejestr w regRecords, jakie statusy, jak generowany raport

Blok 6 (Gratus specific): Sprawy prawne i podrejestry

Cel: Zrozumieć model sprawy z podsprawami/terminami i powiązaniem z książką adresową.

// Jak wyglądają powiązania rekordów — co łączy sprawę z terminem
// Szukać pól: parentId, caseId, relatedId, linkedId w recordData
db.w3_db.regRecords.findOne(
  { officeId: ObjectId("5bae738807770e585186308b") },
  { "recordData": 1, "regId": 1, "signature": 1 }
)

Szukać kolekcji: businessAddressbook, contacts, addressbook

→ Wynik: jak powiązane rekordy, czy przez osobną kolekcję czy przez pole w recordData

Blok 7 (Gratus specific): Kalendarz

Cel: Skąd dane kalendarza — czy to regRecords z datą czy osobna kolekcja.

db.w3_db.getCollectionNames().filter(n => 
  n.includes('calendar') || n.includes('Calendar') || n.includes('event')
)

Jeśli kalendarz to regRecords — zbadać regId z największą liczbą rekordów dla Gratus, porównać z datami i sygnaturami.

→ Wynik: model danych kalendarza

Blok 8: Frontend Angular W3 — kluczowe komponenty

Cel: Zidentyfikować w kodzie GitLab jak zbudowany dity-table i formularz, żeby wiedzieć co przepisać.

Repo GitLab: gitlab.com/pinbox24/ — znaleźć główne repo frontendowe (Angular 7).

Szukać w kodzie:

  • dity-table lub podobny komponent do wyświetlania listy rekordów
  • Formularz dodawania rekordu — jak generuje pola z forms collection
  • Widok kalendarza (Gratus) — jaka biblioteka, jakie dane

→ Wynik: lista komponentów Angular które trzeba przepisać, biblioteki UI


Pytania do rozstrzygnięcia w sesji

Po zebraniu danych — odpowiedzieć na:

  1. Ile unikalnych schematów pól ma RESO (łącznie we wszystkich rejestrach)? → określa złożoność nowego modelu
  2. Czy import Excel jest prosty (stałe kolumny) czy elastyczny (użytkownik definiuje mapowanie)? → czy implementujemy konfigurator czy hardcode
  3. Postbook: czy to tylko flagowanie rekordów + PDF, czy jest złożona logika? → wycena modułu
  4. Gratus sprawy: czy podrejestry to osobna kolekcja czy parentId w regRecords? → model danych
  5. Kalendarz: czy terminy to po prostu rekordy z datą, czy pełnoprawny event system? → biblioteka UI
  6. Czy RESO i Gratus dzielą jakieś rejestry? (te same regId?) → jeden tenant czy izolacja

Decyzja architektoniczna do podjęcia po sesji

Na podstawie zebranych danych — wybrać jeden z modeli:

Wariant 1: Next.js + Supabase (PostgreSQL + JSONB)

registers (id, office_id, name, slug, type)
forms     (id, office_id, register_id, fields jsonb)
records   (id, office_id, register_id, data jsonb, 
           signature text, status text, record_date date,
           source text -- 'w3'|'w4'|'new')
import_schemas (id, office_id, register_id, column_mappings jsonb)

RLS per office_id. Migracja: ETL script MongoDB → Postgres.

Wariant 2: Next.js + MongoDB (nowa kolekcja, nowy schemat)

// registers collection
{ _id, officeId, name, slug, type, fields: [...] }
 
// records collection  
{ _id, officeId, registerId, data: {...}, 
  signature, status, recordDate,
  source: 'w3'|'w4'|'new' }

Migracja: transform regRecords → new schema w tej samej bazie.

Wariant 3: Hybrid JSONB z szybkimi indeksami (propozycja użytkownika)

Zachowuje dane as-is z w3/w4, dodaje kolumny-indeksy, backend parsuje wg source.

Rekomendacja wstępna: Wariant 1 (Supabase) — ale decyzja po poznaniu rzeczywistej złożoności formularzy.


Checklist dla sesji RESO/Gratus

  • Lista wszystkich rejestrów RESO z nazwami i liczbami rekordów
  • Lista wszystkich rejestrów Gratus z nazwami i liczbami rekordów
  • Schemat pól (fields[]) każdego głównego rejestru RESO
  • Schemat pól każdego rejestru Gratus (sprawy, korespondencja, kalendarz)
  • Struktura schematu importu Excel
  • Jak działa postbook — kolekcja czy regId
  • Jak powiązane podrekordy w Gratus (parentId czy osobna kolekcja)
  • Jak działa kalendarz w Gratus
  • Które komponenty Angular przepisać (dity-table, form renderer, calendar)
  • Czy RESO i Gratus dzielą rejestry
  • Wycena złożoności: ile roboczodni na nową aplikację dla W3

Sesja RESO/Gratus to osobna sesja Claude Code z dostępem do MongoDB (przez SSH na bms-4) i GitLab (GITLAB_ADMIN_PAT w secrets/administration.env.sops). Załadować ten brief na początku sesji.