# RAPORT AUDYTOWY SYSTEMU VILMAL ## Niezależny audyt techniczno-majątkowy repozytorium — dokument Due Diligence | Pole | Wartość | |---|---| | **Przedmiot audytu** | Repozytorium `vilmal` — studio przygotowania ofert produktowych Vilmax | | **Data audytu** | 21 września 2026 | | **Stan repozytorium** | HEAD `4e585f2` — „feat: etap 7 — kontrolowany outbox eksportu do Base" | | **Zakres** | Całe repozytorium: kod własny, testy, historia Git, baza danych runtime, dowody działania | | **Narzędzia pomiarowe** | scc 4.1.0 · lizard 2.x · pygount · node:test (tsx) · pytest 9.x · node:sqlite · git | | **Metodologia wyceny** | COCOMO II (model post-architektoniczny, kalibracja II.2000) + cross-check scc COCOMO organic | | **Charakter dokumentu** | Materiał poufny — do użytku wewnętrznego i negocjacji B2B | **Zasada rzetelności:** wszystkie liczby w tym raporcie pochodzą z uruchomień narzędzi na żywym repozytorium w dniu audytu albo z zapisów w bazie danych runtime. Surowe wyjścia narzędzi znajdują się w Załączniku A. Szacunki rynkowe (stawki B2B, cenniki studiów) są jawnie oznaczone i opatrzone źródłami — nie są danymi z systemu. --- ## 1. Podsumowanie wykonawcze VILMAL jest kompletnym, działającym systemem klasy PIM/DAM z autorskim silnikiem Computer Vision do generowania wariantów wizualnych mebli. System przeszedł pełną walidację rynkową: 16.09.2026 paczka produktowa narożnika OSKAR została zapisana w katalogu BaseLinker (rodzic `690927524` + 34 warianty, 272 obrazy) z pełnym odczytem zwrotnym bez niezgodności. | Metryka | Wynik zmierzony | |---|---| | Kod własny (scc) | **27 167 linii kodu** w 196 plikach (31 452 linie ogółem) | | Złożoność cyklomatyczna (scc) | 5 082; lizard: śr. CCN 3,0 na funkcję (1 651 funkcji) | | Testy automatyczne | **200/200 PASS** (147 node:test + 53 pytest) | | Build | `tsc` bez błędów + `vite build` OK (313 ms) | | Historia | 35 commitów, 15–21.09.2026, +34 469/−1 118 linii | | Schemat DB | 12 wersjonowanych migracji, SQLite WAL, runtime DB 18,3 MB | | Walidacja rynkowa | Eksport live do BaseLinker: 34/34 wariantów, read-back 0 niezgodności | | Wartość odtworzeniowa (COCOMO II) | **~2,1–3,1 mln zł netto** (90,5–102,1 roboczomiesięcy × 152 h × 150–200 zł/h B2B); cross-check scc organic: $865 735 | --- ## 2. Pomiary kodu źródłowego ### 2.1. Pomiar kanoniczny — scc 4.1.0 Komenda: `scc --exclude-dir node_modules,tmp,.git,dist,build,coverage --format wide` (katalog: `vilmal/`). | Język | Pliki | Linie | Kod | Komentarze | Złożoność | |---|---:|---:|---:|---:|---:| | TypeScript (+TSX) | 155 | 25 126 | **22 240** | 1 318 | 4 770 | | Python | 20 | 2 781 | **1 954** | 451 | 307 | | Markdown | 10 | 2 013 | 1 538 | 0 | 0 | | HTML | 3 | 811 | 794 | 4 | 0 | | CSS | 1 | 360 | 324 | 12 | 0 | | SQL | 1 | 235 | 199 | 20 | 0 | | JavaScript | 1 | 22 | 18 | 1 | 5 | | JSON | 3 | 81 | 81 | 0 | 0 | | Pozostałe (TXT, typings) | 2 | 23 | 19 | 1 | 0 | | **RAZEM** | **196** | **31 452** | **27 167** | **1 807** | **5 082** | ### 2.2. Rozkład per warstwa systemu | Warstwa | Pliki | Kod (LOC) | Złożoność | Charakter | |---|---:|---:|---:|---| | `server/src` — backend i domena | 48 | 10 949 | 2 838 | Fastify 5, 25 modułów domenowych | | `server/test` — testy domeny | 17 | 3 237 | 267 | 147 testów node:test | | `web` — frontend operatora | 20 | 4 020 | 976 | React 19 + Vite 8, 12 paneli | | `services/recolor` — silnik CV | 20 | 2 006 | 298 | Python, FastAPI + CLI, modele HF | | `scripts` — narzędzia QA/operacyjne | 79 | 4 762 | 703 | skrypty weryfikacyjne (w tym Chromium CDP) | | `docs` — dokumentacja | 4 | 957 | 0 | kontrakty, masterplan | **Kod produktowy (bez testów, skryptów i dokumentacji): 16 975 LOC.** **Kod własny ogółem z testami i narzędziami (baza wyceny COCOMO): 25 173 LOC ≈ 25,17 KSLOC.** ### 2.3. Złożoność — lizard - Funkcji przeanalizowanych: **1 651**; NLOC funkcyjny: 19 596. - Średnia złożoność cyklomatyczna: **CCN 3,0** (zdrowy poziom — standardem jest próg alarmowy ~10–15). - 41 funkcji przekracza progi ostrzegawcze (~20% NLOC); najcięższe: `renderProductCardPdf` (CCN 134), `runFabricImport` (102), `process_detailed` (95), `vendorFacts` (85), `buildOfferPackage` (79), `prepareRecolorRole` (63). To naturalne punkty skupienia długu refaktoringowego — są to funkcje orkiestrujące, nie logika rozproszona. ### 2.4. Testy i kompilacja — stan na dzień audytu | Weryfikacja | Komenda | Wynik | |---|---|---| | Testy backendu/domeny | `npm test` (`tsx --test server/test/*.test.ts`) | **147/147 PASS**, 0 porażek, 17,3 s | | Testy silnika CV | `python -m pytest tests` (z `services/recolor`) | **53/53 PASS**, 0 porażek, 1,1 s | | Kompilacja | `npm run build` (`tsc` + `vite build web`) | **OK**, 0 błędów typowania; bundle 359,8 kB (gzip 104,8 kB) | Pokrycie testów backendu obejmuje m.in.: ingest i deduplikację SHA-256, provenance, fakty i akceptacje, matrycę wariantów, guard recoloru na weryfikację tkanin, treści ofertowe, snapshoty paczki, orkiestrator (idempotencja, wygasanie 24 h, stale SHA, role, rollback transakcji), outbox eksportu (zgoda na SHA, read-back, pojednanie po SKU, blokady auth/CSRF/brak sekretów), fetcher źródeł (SSRF, DNS-pinning, limity, redirecty, dekompresja), import źródeł (idempotencja, anulowanie, restart). Testy Pythona: konwersje Lab, transfer delta, maski, komponenty, kieszenie komór, ochrona regionów, sidecar fast-path i bake, raport serwisu. ### 2.5. Historia Git | Metryka | Wartość | |---|---| | Liczba commitów | 35 | | Zakres czasowy | 15.09.2026 01:41 → 21.09.2026 19:05 (~6,7 dnia) | | Autorzy | 1 (DamianMalenta; commity generowane z Devin) | | Diffstat | +34 469 / −1 118 linii | | Tagi stabilności | `recolor-v7-stable`, `recolor-v7-integrated`, `recolor-v7-sidecar` | | Kamienie milowe | pipeline „zdjęcie pod ujęcie" → recolor v4 → regeneracja wariantów → architektura v7 → integracja worker → sidecar 50× → etapy 1–6 masterplanu → etap 7 outbox Base | Kamień milowy walidacji rynkowej: commit `c241441` (16.09.2026) — „eksport: OSKAR wyslany do Base - rodzic 690927524 + 34 warianty, read-back OK". --- ## 3. Inwentaryzacja architektury ### 3.1. Podział domenowy (backend TypeScript / Fastify 5) 25 modułów w `server/src/domain/`: - **Produkt i fakty:** `product`, `productProfile`, `facts`, `productImport`, `shotRefs` — fakty z trójstanem `confirmed | unverified | unknown`, historią zmian (`fact_history`, 277 wpisów) i źródłem (`source_kind`, `source_ref`). „Nie potwierdzono" nigdy nie jest równoważne „false". - **Tkaniny:** `fabric`, `fabricCatalog`, `fabricImport` — import kolekcji z URL producenta (snapshot → parser → odcienie `unverified` → próbki jako `source_assets`), weryfikacja przez rolę approver. - **Media:** `media/ingest`, `media/sourceFetch`, `mediaReview`, `assets`, `renditions` — oryginały niezmienne, deduplikacja po SHA-256, wersjonowanie per (produkt, rola, wariant), renditions kanałowe `base_v1`. - **Jakość:** `macius` — wbudowany nadzorca jakości: werdykty `ok / do_poprawy / odrzucone / blad` przypięte do SHA assetu; doradcze, nie rozstrzygające (Human-in-the-Loop). - **Oferta:** `offerContent`, `offerPackage`, `productCard`, `baseContract` — wersjonowane treści kanałowe, snapshot paczki z SHA-256 i blockerami, karta PDF (pdfkit), translator kontraktu `addInventoryProduct`. - **Proces:** `jobs`, `orchestrator`, `orchestrationContracts`, `exportOutbox`, `audit` — trwała kolejka zadań (zapis przed pracą zewnętrzną, wznowienie po `provider_request_id`), operacje prepare→preview→decide→execute z rewalidacją SHA, audit_log. - **Integracje:** `integration/baseAdapter` (BaseLinker `connector.php`), `ai/provider` + `ai/runcomfy` + `ai/groq` + `ai/testProvider` (operator wybiera efekt, nie provider; jawny `unitCostUsd`). - **Import zewnętrzny:** `import/bobochic`, `import/sic` — parsery stron producenta/dystrybutora ze snapshotów, bez sieci w parserze. ### 3.2. Baza danych — SQLite (node:sqlite, WAL) - **12 wersjonowanych migracji** (`PRAGMA user_version = 12`), `schema.sql` + migracje w `db.ts`, transakcje z SAVEPOINT (zagnieżdżenia działają). - Kluczowe tabele: `products`, `product_facts` + `fact_history`, `fabrics`, `fabric_shades`, `variants`, `source_assets`, `shot_refs`, `assets`, `approvals`, `macius_verdicts`, `recipes`, `jobs`, `users`, `sessions`, `audit_log`, `offer_snapshots`, `offer_content_revisions`, `channel_renditions`, `orchestrator_operations` + `orchestrator_inspections` + `orchestrator_audit`, `source_imports`, `export_consents` + `export_batches` + `export_items`, `asset_protections`. - Zasada integralności: zatwierdzenia wiążą się z **konkretną treścią (SHA-256 w momencie decyzji)**, nie z „pierwszym gotowym obrazem"; zmiana treści unieważnia zgodę. ### 3.3. Stan bazy runtime (odczyt audytowy, 21.09.2026) | Tabela | Wiersze | Komentarz | |---|---:|---| | `products` | 6 | OSKAR, FUJI, canapes-d-angle-convertibles + 3 produkty testowe | | `variants` | 102 | 34 × 3 produkty; status `draft` (zatwierdzanie per media, nie per wariant) | | `product_facts` | 376 | **314 confirmed**, 59 unverified, 3 unknown | | `assets` | 1 244 | 290 approved / 215 candidate / 723 rejected / 16 superseded — pełna historia wersji | | `approvals` | 1 675 | 588 approved / 1 087 rejected — intensywny cykl ludzkiej kontroli | | `macius_verdicts` | 1 166 | 1 062 ok / 82 do_poprawy / 20 odrzucone / 2 blad | | `channel_renditions` | 544 | profil `base_v1`: 34 warianty × 8 ról × 2 pliki | | `jobs` | 83 | 75 done / 8 error | | `audit_log` | 5 211 | pełny ślad operacji | | `offer_snapshots` | 6 | wersje paczki OSKAR (v1–v6) | | `source_assets` / `shot_refs` | 97 / 25 | materiały źródłowe z provenance / przypisanie ról | | `export_*` | 0 | outbox etapu 7 wdrożony, nieużyty produkcyjnie (eksport live szedł skryptem operacyjnym) | | `users` | 1 | jedno konto (środowisko deweloperskie) | ### 3.4. Silnik Computer Vision — `fabric_recolor` v7 (Python) - **Kontrakt:** `process_detailed(master, próbka_tkaniny, out) -> RecolorReport` (coverage, backend, delta, czas); FastAPI `POST /v1/recolor` + CLI; worker TS wywołuje go jako job — nie przez inwazyjną zmianę domeny. - **Potok (backend `birefnet_matte`):** matte BiRefNet (ZhengPeng7/BiRefNet) → histereza alfa → największy komponent + wypełnianie dziur → maskowane ROI → GroundingDINO+SAM wyłącznie z frazami negatywnymi per-instancja (komory vs wyrostki) → kotwica głębi Depth-Anything-V2 (deficyt głębi, poziomica od kotwicy) → ochrona regionów pośrednich → feather wycięć. - **Zasada projektowa:** kompletność z matte, selekcja z wykluczeń; reguły geometryczne i semantyczne, zero współrzędnych/progów pod konkretny mebel. Asymetria błędów: niewykryty negatyw = drobny defekt do QA, nie dziura w meblu. - **Rekompozycja koloru (`lab_match`):** przestrzeń Lab; delta próbki względem kotwicy iluminantu sceny — kolor sceny zostaje zachowany, przenoszony jest odcień tkaniny. - **Wydajność (zmierzona na GTX 1650 4 GB, master 1024×768):** slow-path 74,3 s → **fast-path sidecar-mask 1,5 s (przyspieszenie ~50×)**; maska „wypiekana" do `{master}.mask.png` po pierwszym przebiegu. Pełna regeneracja matrycy OSKAR: **272 ujęcia w ~55 minut, koszt krańcowy $0** (lokalny GPU). - Fallbacki segmentacji: `grounded_sam` (awaryjnie), `clipseg` (ostatni). Środowisko: torch 2.11, transformers 4.57, opencv-headless, scipy; modele HF w cache lokalnym. ### 3.5. Odporność i integracje - **Transactional Outbox → BaseLinker:** trzy warstwy — `export_consents` (zgoda approvera wiązana z dokładnym SHA snapshotu i SHA źródeł) → `export_batches` (idempotentny wsad, `consent_id UNIQUE`) → `export_items` (pozycja per wariant, `UNIQUE(batch_id,kind,variant_id)`). Read-back `getInventoryProductsData` po każdym zapisie; timeout/niepewna odpowiedź → `unconfirmed` i pojednanie po SKU zamiast ślepego re-create; pozycje `sending` po restarcie wracają do `unconfirmed`. Odwołanie zgody anuluje niewysłane pozycje. - **Idempotencja:** `idempotency_key` w jobs (UNIQUE), operacje orkiestratora (powtórzone prepare zwraca tę samą operację), importy źródeł (konflikt klucza), wsady eksportu. - **Walidacja wejścia:** schematy **Zod strict** na wszystkich endpointach mutujących; sesja + CSRF; role `operator / approver / admin` z rozdziałem kompetencji (operator nie wykonuje akcji approvera; admin nie omija blokad koszt/dispatch). - **Higiena sekretów:** token BaseLinker wyłącznie w `BASELINKER_API_TOKEN` środowiska serwera — nigdy w DTO, payloadach pozycji, logach ani UI; adapter domyślnie **disabled** (odrzuca wszystko). `.env` poprawnie wykluczony z Git (`.env.example` śledzony, `.env` nie). - **Safe-fetcher:** allowlist hostów HTTPS, blokada sieci lokalnych/specjalnych (IPv4+IPv6), DNS-pinning, ponowna weryfikacja hosta po każdym redirect, limity bajtów i nagłówków, brak dekompresji bomb, walidacja MIME po bajtach — pokryte dedykowanymi testami. - **Bramki kosztowe:** płatna generacja AI i dispatch Base trwale zablokowane bez osobnej zgody — także dla admina. ### 3.6. Walidacja rynkowa — stan wdrożenia produkcyjnego **Potwierdzone faktem (16.09.2026, commit `c241441`, artefakt `data/exports/base-oskar-2026-09-16.json`):** - Narożnik OSKAR zapisany w magazynie BaseLinker `62360` jako produkt rodzica **ID `690927524`** (SKU `VIL-OSK-TIL`) + **34 warianty** `VIL-OSK-{L|P}-TIL{01..100}` powiązane przez `parent_id`. - Każdy wariant: pełna galeria **8 zdjęć** (272 obrazy łącznie, 1184×880, CDN BaseLinker), treści kanałowe `name|pl|allegro_24646` / `description|pl|allegro_24646` / `features|pl|allegro_24646`, kategoria wewnętrzna BL „Narożniki", producent, cena, stan magazynowy, szablon dostawy. - **Read-back `getInventoryProductsData`: 34/34 wariantów, 0 niezgodności.** - Zapis wykonany kontrolowanym skryptem operacyjnym (`scripts/export-base-oskar.mts`) pod zgodą właściciela, z gwarancjami: snapshot approved + SHA zgodny + 0 blockerów + guard idempotencji SKU + weryfikacja SHA każdego pliku przed wysłaniem. **Granica walidacji (uczciwie):** produkty są pozycjami katalogowymi w Base. Wystawienie ofert Allegro wymaga kroków operatorskich w panelu BL (kategoria marketplace, parametry obowiązkowe, GPSR, czas wysyłki) — numeryczne ID kategorii Allegro i parametry słownikowe nie są dostępne read-only przez API. Zasilenie witryny bazarowy-swiat.pl tym katalogiem zależy od powiązania kanałów po stronie Base/WooCommerce, nie od VILMAL. Eksport live szedł skryptem — produkcyjny outbox (etap 7) jest wdrożony i testowany, ale nie wykonał jeszcze zapisu live. --- ## 4. Bilans audytowy ### 4.1. Atuty 1. **Kompletna, zweryfikowana ścieżka wartości** — nie prototyp: fakty → media → warianty → dokumenty → snapshot → eksport, zakończona zapisem live i read-backiem. 2. **Autorski silnik CV z mierzalną przewagą kosztową** — 272 wizualizacje wariantów w ~55 min na lokalnym GPU przy koszcie krańcowym ~0; dziedziczenie geometrii 1:1 z realnego egzemplarza. 3. **Rygor danych klasy enterprise** — SHA-256 na treści i decyzjach, audit_log, historie faktów, niezmienne oryginały, snapshot jako jedyna prawda dla wszystkich kanałów. 4. **Human-in-the-Loop zamiast auto-publikacji** — trójstan faktów, werdykty doradcze Maciusia, dwie bramki eksportu (snapshot ≠ zgoda), blokady kosztów nie do ominięcia przez admina. 5. **Odporność operacyjna** — idempotencja na każdym poziomie, pojednanie po SKU, wznowienie po request_id, outbox, transakcje SAVEPOINT, 200 testów w tym scenariusze awarii (timeout, restart, uszkodzone bajty, stale SHA). 6. **Bezpieczeństwo** — SSRF-hardened fetcher, Zod strict, CSRF, role, sekrety poza kodem i logami. 7. **Jakość procesu** — testy domenowe + przeglądarkowe QA (Chromium CDP), tagi stabilności, dokumentacja stanu w `.devin/STAN.md` z jawnymi granicami. ### 4.2. Ryzyka i dług techniczny (rzetelnie) | # | Pozycja | Waga | Opis i mitygacja | |---|---|---|---| | R1 | Walidacja silnika recolor na jednym produkcie | Średnia | Progi v7 (deficyt głębi 0,3, cavity ≤8%, ΔE 12) generyczne, ale zweryfikowane tylko na OSKAR-ze; przed szerszym wdrożeniem walidacja na fotelu/welurze. FUJI już przechodzi proces — naturalna ścieżka kalibracji. | | R2 | Nierozstrzygnięta kotwica odcienia | Średnia | Pomiary wnętrz masterów wskazują bliżej odcienia TILIA 83 niż potwierdzonej 86; decyzja należy do właściciela (nie systemu). Zmiana = regeneracja lokalna $0. | | R3 | Znany defekt jakości hero | Średnia | Ujęcie hero „wklejone" (master AI + spłaszczenie lab_match na jasnych odcieniach); odrzucony master v2 osadza mebel lepiej — kwestia kuratorska, nie architektoniczna. | | R4 | Niedeterminizm masek historycznych | Niska | Dwie sesje maski (birefnet/u2net) dla roli detail; provenance `mask.method` rozróżnia sesje; spójność wymusza `VILMAL_MASK_SESSION`. | | R5 | Outbox bez zapisu live | Niska | Etap 7 testowany (141+ testów, QA przeglądarkowe), ale adapter live nigdy nie wykonał zapisu; kontrakty `getInventoryProductsList`/`text_fields` oznaczone [DOC] — pierwsze uruchomienie zweryfikuje odpowiedzi. | | R6 | Ograniczenia kontraktu marketplace | Średnia | Parametry kategorii Allegro i wartości słownikowe niedostępne read-only — kroki operatorskie w panelu BL; wideo use/care odroczone decyzją właściciela, blocker publikacji docelowej. | | R7 | Zależność od zewnętrznego dostawcy AI dla masterów | Niska | Generacja masterów przez RunComfy ($0,007–0,13/obraz) z bramką kosztową; recolor wariantów jest lokalny i niezależny. | | R8 | Hotspoty złożoności | Niska | 41 funkcji powyżej progu ostrzegawczego (~20% NLOC), m.in. `renderProductCardPdf` CCN 134 — kandydaci do dekompozycji przy utrzymaniu. | | R9 | Środowisko deweloperskie | Średnia | 1 użytkownik, 3 produkty testowe w DB, lokalna instancja; wdrożenie na serwery Vilmax (etap 8: trwałość, kontrola dostępu, restart, backup/restore) pozostaje roadmapą. | | R10 | Prawa do materiałów dostawcy | Niska | `vendor_reference` (zdjęcia Bobochic/SIC) to referencje robocze z provenance — nie materiały publikowalne bez potwierdzenia praw; system wymusza tę rozdzielczość rolą źródła. | | R11 | Specyfika importu źródeł | Niska | Parsery `bobochic`/`sic` oparte na strukturze konkretnych stron; pobieranie live z CDN vendora nie było jeszcze odpalone na żywym imporcie (testy na fixturze i fake-fetcherze). | | R12 | Skryptowy kanał eksportu | Niska | Eksport live 16.09 poszedł skryptem operacyjnym (nie outboxem) — świadoma decyzja pod zgodą właściciela; docelowy kanał to outbox. | --- ## 5. Wycena odtworzeniowa — model COCOMO II ### 5.1. Model i wzór Model **COCOMO II — Post-Architecture** (kalibracja II.2000, Boehm et al., „Software Cost Estimation with COCOMO II"): ``` PM = A × (KSLOC)^E × Π(EM_i) [roboczomiesiące] gdzie: A = 2,94 — stała kalibracyjna COCOMO II.2000 E = B + 0,01 × Σ(SF_i) — wykładnik skali B = 0,91 SF_i — 5 czynników skali: PREC, FLEX, RESL, TEAM, PMAT EM_i — mnożniki nakładu (przyjęto ΠEM = 1,0 — nominalnie, bez optymizmu) ``` **Wielkość wejściowa:** KSLOC = **25,17** (25 173 linie kodu własnego zmierzone przez scc: `server/src` 10 949 + `server/test` 3 237 + `web` 4 020 + `services` 2 006 + `scripts` 4 762 + SQL 199). Do wyceny nie wliczono dokumentacji, danych ani kodu generowanego. ### 5.2. Czynniki skali | Czynnik | Nominalna | Scenariusz uzasadniony | Uzasadnienie scenariusza | |---|---|---|---| | PREC — precedensowość | 3,72 (N) | **2,48 (H)** | Domena i kontrakty Base/marketplace zostały rozpoznane w poprzednim systemie (Cockpit); zespół nie startuje od zera | | FLEX — elastyczność wymagań | 3,04 (N) | 3,04 (N) | Wymagania jakościowe twarde (zgodność faktów, niezmienne oryginały) | | RESL — rozstrzygnięcie architektury i ryzyk | 4,24 (N) | **2,83 (H)** | Architektura i ryzyka udokumentowane w audytach; brak otwartych decyzji platformowych | | TEAM — spójność zespołu | 3,29 (N) | **2,19 (H)** | Mały, jednoosobowy rdzeń z pełną własnością decyzji | | PMAT — dojrzałość procesu | 4,68 (N) | 4,68 (N) | Proces testowy i QA dobry, ale bez formalnej certyfikacji dojrzałości | | **ΣSF** | **18,97** | **15,22** | | | **E** | **1,0997** | **1,0622** | | ### 5.3. Wynik nakładu pracy | Scenariusz | Obliczenie | PM | Roboczogodziny (×152 h/PM) | |---|---|---:|---:| | Wszystko nominalne | 2,94 × 25,17^1,0997 | **102,1 PM** | **15 515 h** | | Uzasadnione czynniki | 2,94 × 25,17^1,0622 | **90,5 PM** | **13 756 h** | Przyjęty standard 152 h/roboczomiesiąc (konwencja COCOMO). Przy przeliczniku 168 h wyniki wynoszą odpowiednio 17 176 h i 15 200 h — raport posługuje się konserwatywnym 152 h. ### 5.4. Stawki rynkowe B2B (Polska) — źródła | Źródło | Dane | |---|---| | Raport Płacowy IT 2025 (Sedlak & Sedlak / IT community) | Senior Software Development B2B: ~130–160 zł/h | | No Fluff Jobs — mediana senior B2B 2025 | 21 800–27 500 zł netto/mc ≈ 130–165 zł/h; Architecture do 32 760 zł ≈ 195 zł/h | | Just Join IT / Brandsit 2025 | senior B2B ~25 000 zł netto/mc ≈ ~150 zł/h | Specjalizacja wymagana do odtworzenia: Senior Fullstack TypeScript + inżynier Python/CV. Przyjęty korytarz audytowy: **150–200 zł/h netto B2B** (CV/ML i architektura w górnej części korytarza). ### 5.5. Wartość odtworzeniowa — wynik | Stawka | Scenariusz uzasadniony (13 756 h) | Nominalny (15 515 h) | |---|---:|---:| | 150 zł/h | 2 063 400 zł | 2 327 250 zł | | 175 zł/h (środek) | 2 407 300 zł | 2 715 125 zł | | 200 zł/h | 2 751 200 zł | 3 103 000 zł | > **Wartość odtworzeniowa technologii: ~2,1–3,1 mln zł netto; estymator centralny ≈ 2,6 mln zł.** > Cross-check: wbudowany model scc (COCOMO organic, wynagrodzenie referencyjne US) daje dla tego samego repozytorium **$865 735** (~3,4 mln zł przy kursie 4,0) — zgodne z górnym krańcem przedziału. Wycena dotyczy kosztu odtworzenia (replacement cost), nie wyceny rynkowej przedsięwzięcia — ta zależy dodatkowo od walidacji rynkowej i przychodów, które system już częściowo wykazał (§3.6). --- ## 6. Analiza kosztów alternatywnych — paczka wizualna 1 modelu narożnika **Matryca docelowa:** 17 odcieni tkaniny × 2 strony (L/P) × 8 ujęć = **272 wizualizacje** na model. ### 6.1. Ścieżka tradycyjna — studio 3D / fotografia (źródła cennikowe) | Pozycja | Stawka rynkowa PL (źródła poniżej) | Nakład | Koszt | |---|---|---:|---:| | Model 3D narożnika rozkładanego | 2 000–5 000 zł (złożony mebel, mechanizm spania) | 1× | 2 000–5 000 zł | | Sceny bazowe (aranżacja + packshoty + detale) | 450–1 500 zł/ujęcie | 8× | 3 600–12 000 zł | | Render wariantowy przy gotowym modelu | 150–300 zł/render | 272× | 40 800–81 600 zł | | **RAZEM — ścieżka 3D** | | | **≈ 46–99 tys. zł / model** | | Fotografia tradycyjna | sesja meblowa ~3–8 tys. zł/dzień + produkcja 34 fizycznych wariantów tapicerowanych | — | **praktycznie niewykonalna** — koszt wyprodukowania egzemplarzy do sesji przekracza koszt całej ścieżki 3D | Źródła cennikowe: BearStudio (sofa 500–1 500 zł/ujęcie; wariant kolorystyczny przy gotowym modelu 150–400 zł; model 3D sofy 2–3 dni), Rooven (model mebla 200–800 zł; aranżacja od 700 zł + 60 zł/kolejna; animacja od 800 zł), Pogotowie3D cennik 15.09.2026 (packshot mebla od 60 zł; aranżacja od 450 zł; wariant od 30–40 zł — ceny podstawowe, wyższe przy realizmie katalogowym). Widełki audytowe przyjęto w środku-wyższym segmencie jakości katalogowej zgodnej z wzorcem OSKAR. **Czas realizacji ścieżki tradycyjnej:** modelowanie 2–7 dni + produkcja renderów wariantowych + tury poprawek → typowo **4–8 tygodni** na kompletną matrycę. ### 6.2. Ścieżka VILMAL (zmierzona) | Pozycja | Wartość | |---|---| | Regeneracja pełnej matrycy 272 ujęć | **~55 minut** na GTX 1650 (zmierzone, `regen-recolors-v4.mts`) | | Koszt krańcowy obliczeń | **$0** — lokalny GPU, bez płatnych API obrazu | | Praca operatorska | ~1 dzień roboczy: QA w matrycy, zatwierdzanie, ewentualne pojedyncze regeneracje | | Koszt marginalny paczki | rząd kilkuset zł (czas operatora + energia) | ### 6.3. Oszczędność operacyjna | Scenariusz | Koszt/model | Czas/model | 10 modeli/rok | |---|---:|---:|---:| | Studio 3D (realistyczna ścieżka) | 46–99 tys. zł | 4–8 tyg. | **0,46–0,99 mln zł** | | VILMAL | kilkaset zł marginalnie | 1–2 dni robocze z QA | **<10 tys. zł** OPEX | **Oszczędność operacyjna: ~0,45–0,98 mln zł rocznie przy 10 modelach**, plus skrócenie time-to-market z tygodni do dni i eliminacja rozjazdu treści między kanałami (jeden snapshot). --- ## 7. Rekomendacje audytowe 1. **Domknąć R2 (kotwica 83 vs 86)** — decyzja właściciela + regeneracja; to jedyny fakt wpływający na zgodność barwną całej matrycy. 2. **Pierwszy kontrolowany zapis outboxem live** na koncie testowym Base (pojedynczy produkt) — zweryfikuje kontrakty [DOC] i przeniesie walidację rynkową ze skryptu na docelowy kanał. 3. **Kalibracja v7 na drugim typie bryły** (fotel/welur) przed skalowaniem katalogu. 4. **Etapa 8 — wdrożenie produkcyjne:** użytkownicy/role operacyjne, backup/restore z próbą odtworzenia, systemd/restart, rotacja sekretów na serwerach Vilmax; sprzątnięcie produktów testowych z DB. 5. **Dekompozycja hotspotów** (`renderProductCardPdf`, `runFabricImport`, `process_detailed`) przy najbliższej iteracji utrzymaniowej. 6. **Kuratorskie domknięcie hero** — decyzja o masterze v2 vs regeneracja. --- ## Załącznik A — surowe wyjścia narzędzi (verbatim) ### A.1. scc 4.1.0 — pomiar kanoniczny ``` $ ./tmp/tools/scc.exe --exclude-dir node_modules,tmp,.git,dist,build,coverage --format wide ───────────────────────────────────────────────────────────────────────────────────────────── Language Files Lines Blanks Comments Code Complexity Complexity/Lines ───────────────────────────────────────────────────────────────────────────────────────────── TypeScript 155 25,126 1,568 1,318 22,240 4,770 21.45 Python 20 2,781 376 451 1,954 307 15.71 Markdown 10 2,013 475 0 1,538 0 0.00 HTML 3 811 13 4 794 0 0.00 JSON 3 81 0 0 81 0 0.00 CSS 1 360 24 12 324 0 0.00 JavaScript 1 22 3 1 18 5 27.78 Plain Text 1 22 3 0 19 0 0.00 SQL 1 235 16 20 199 0 0.00 TypeScript Typings 1 1 0 1 0 0 0.00 ───────────────────────────────────────────────────────────────────────────────────────────── Total 196 31,452 2,478 1,807 27,167 5,082 18.71 ───────────────────────────────────────────────────────────────────────────────────────────── Estimated Cost to Develop (organic) $865,735 Estimated Schedule Effort (organic) 13.02 months Estimated People Required (organic) 5.91 Processed 1,806,154 bytes, 1.806 megabytes (SI) ``` ### A.2. scc — rozkład per katalog ``` server/src 48 files 10,949 code CC 2,838 server/test 17 files 3,237 code CC 267 web 20 files 4,020 code CC 976 services 20 files 2,006 code CC 298 scripts 79 files 4,762 code CC 703 docs 4 files 957 code ``` ### A.3. Testy ``` $ npm test (tsx --test server/test/*.test.ts) ℹ tests 147 ℹ pass 147 ℹ fail 0 ℹ duration_ms 17342.6788 $ python -m pytest tests -q (katalog: services/recolor) ..................................................... [100%] 53 passed in 1.08s ``` ### A.4. Build ``` $ npm run build (tsc -p tsconfig.json && vite build web) vite v8.2.2 building client environment for production... ✓ 29 modules transformed. web/dist/index.html 0.40 kB │ gzip: 0.28 kB web/dist/assets/index-hz1LuaoB.css 20.45 kB │ gzip: 4.55 kB web/dist/assets/index-TcjIA_IU.js 359.78 kB │ gzip: 104.76 kB ✓ built in 313ms ``` ### A.5. Git ``` HEAD: 4e585f2c773586c6458f9c67f9058ba2726459a9 (feat: etap 7 — kontrolowany outbox eksportu do Base) Commits: 35 (2026-09-15 01:41 → 2026-09-21 19:05) Author: DamianMalenta — 35/35 Diffstat: +34,469 / −1,118 Tags: recolor-v7-stable · recolor-v7-integrated · recolor-v7-sidecar Walidacja rynkowa: c241441 (16.09.2026) — eksport OSKAR: rodzic 690927524 + 34 warianty, read-back OK ``` ### A.6. Baza runtime (odczyt audytowy node:sqlite, read-only) ``` user_version: 12 DB: data/vilmal.db (18.3 MB, WAL) products: 6 variants: 102 product_facts: 376 (314 conf / 59 unver / 3 unk) assets: 1,244 (290 appr / 215 cand / 723 rej / 16 sup) approvals: 1,675 (588/1,087) macius_verdicts: 1,166 (1,062 ok / 82 fix / 20 rej / 2 err) audit_log: 5,211 channel_renditions: 544 (base_v1, 34×8×2) jobs: 83 (75 done / 8 err) source_assets: 97 shot_refs: 25 offer_snapshots: 6 orchestrator_ops: 11 source_imports: 5 fact_history: 277 users: 1 export_*: 0 ``` ### A.7. lizard — złożoność ``` Total nloc 19,596 · funkcji 1,651 · AvgCCN 3.0 · funkcji powyżej progu: 41 (~20% NLOC) Hotspoty: renderProductCardPdf CCN 134 · runFabricImport 102 · process_detailed 95 · vendorFacts 85 · buildOfferPackage 79 · prepareRecolorRole 63 ``` --- *Raport wygenerowany na podstawie pomiarów wykonanych 21.09.2026 na repozytorium `vilmal` (HEAD `4e585f2`). Wszystkie liczby systemowe pochodzą z narzędzi i bazy runtime; szacunki rynkowe są oznaczone i opatrzone źródłami.*