Files
orderPRO/.paul/phases/113-fakturownia-integration/113-01-SUMMARY.md
Jacek Pyziak 2382018739 feat(113): fakturownia integration foundation
Phase 113 complete (v3.7 Invoices):
- DB: invoices, invoice_configs, invoice_number_counters, fakturownia_integration_settings + orders.invoice_requested
- FakturowniaIntegrationRepository (multi-account via integrations.type='fakturownia')
- FakturowniaApiClient (testConnection; createInvoice/downloadPdf STUBs)
- IntegrationsRepository::updateTestResult() (reusable test-result writer)
- /settings/integrations/fakturownia (list + edit + test + delete)
- Karta Fakturownia w hubie /settings/integrations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 22:11:55 +02:00

14 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, started, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration started completed
113-fakturownia-integration 01 integrations
fakturownia
invoices
settings
integration
api
encryption
phase provides
08-receipts-foundation receipt_configs/receipts/receipt_number_counters schema patterns mirrored for invoices
phase provides
35-inpost-settings IntegrationsRepository + IntegrationSecretCipher patterns
DB
invoices, invoice_configs, invoice_number_counters, fakturownia_integration_settings, orders.invoice_requested
FakturowniaIntegrationRepository (multi-account CRUD)
FakturowniaApiClient (testConnection + STUBs for createInvoice/downloadPdf)
IntegrationsRepository::updateTestResult() (reusable test-result writer)
/settings/integrations/fakturownia (list + edit + test + delete UI)
Fakturownia card in integrations hub
114-invoice-configs
115-invoice-issuance
116-invoice-list
importers Allegro/shopPRO (invoice_requested flag)
added patterns
Fakturownia REST API (app.fakturownia.pl)
Multi-account integration via integrations.type='fakturownia' + dedicated settings table with UNIQUE integration_id
Local snapshot pattern reused: seller/buyer/items as JSON in invoices (mirroring receipts)
is_delegated flag in invoice_configs - local-vs-API generation toggle
created modified
database/migrations/20260510_000104_create_invoices_tables.sql
database/migrations/20260510_000105_add_invoice_requested_to_orders.sql
database/migrations/20260510_000106_seed_fakturownia_integration_type.sql
src/Modules/Settings/FakturowniaIntegrationRepository.php
src/Modules/Settings/FakturowniaApiClient.php
src/Modules/Settings/FakturowniaIntegrationController.php
resources/views/settings/fakturownia.php
resources/views/settings/fakturownia-edit.php
src/Modules/Settings/IntegrationsHubController.php
src/Modules/Settings/IntegrationsRepository.php
routes/web.php
.paul/codebase/db_schema.md
.paul/codebase/architecture.md
.paul/codebase/tech_changelog.md
Multi-account przez integrations.type='fakturownia' (zamiast singletona jak InPost/Apaczka) - spojnosc z shopPRO + przyszla obsluga wielu marek/oddzialow
is_delegated flag w invoice_configs - default lokalna numeracja+PDF, opcjonalnie delegacja do Fakturowni
Brak osobnego eventu invoice.created - receipt.created pozostaje wylacznie dla paragonow (zero ryzyka cross-matching regul automatyzacji)
orders.invoice_requested z importera + manual override (UI checkbox w kolejnym planie)
Migracja 106 jako DDL no-op (ALTER TABLE COMMENT) zamiast SELECT 1 - SELECT zwraca result set i blokuje kolejne zapytania pod PDO unbuffered
Token API szyfrowany przez IntegrationSecretCipher; integrations.api_key_encrypted = zrodlo prawdy, settings.api_token_encrypted = cache
ApiClient::testConnection() zwraca array ['ok', 'http_code', 'message']; controller mapuje na IntegrationsRepository::updateTestResult()
Widoki list integracji: section.card + table-wrap + table.table + badge.badge--{success,muted,info}; usun przez js-confirm-delete + js-delete-btn (window.OrderProAlerts)
STUB-y metod API rzucaja RuntimeException z czytelnym komunikatem 'Not implemented in Phase X' zamiast cichego no-op
90min 2026-05-10T19:00:00Z 2026-05-10T20:30:00Z

Phase 113 Plan 01: Fakturownia Integration Foundation Summary

Fundament v3.7 Invoices gotowy: schema DB (4 tabele + kolumna orders.invoice_requested), CRUD kont Fakturowni z testem polaczenia API i kartą w hubie integracji. Numeracja lokalna z opcja delegacji do Fakturowni (flag is_delegated w invoice_configs).

Performance

Metric Value
Duration ~90min
Started 2026-05-10T19:00:00Z
Completed 2026-05-10T20:30:00Z
Tasks 3 completed (auto, inline)
Files created 8
Files modified 6

Acceptance Criteria Results

Criterion Status Notes
AC-1: Schema DB dla faktur i Fakturowni Pass 4 nowe tabele + orders.invoice_requested, FK + UNIQUE wlasciwe. Migracje przeszly po naprawie AFTER notes (kolumna nie istnieje w orders) i zamianie SELECT 1; na ALTER TABLE ... COMMENT w migracji 106.
AC-2: Repozytorium i klient API Fakturowni Pass FakturowniaIntegrationRepository::save() szyfruje token przez IntegrationSecretCipher przed zapisem. FakturowniaApiClient::testConnection() wykonuje GET account.json z cURL + SslCertificateResolver. IntegrationsRepository::updateTestResult() (nowa metoda) zapisuje wynik testu.
AC-3: UI ustawien integracji Fakturownia Pass Lista /settings/integrations/fakturownia + edycja /edit + nowy /new + test + delete; CSRF _token; flash fakturownia.save/.test/.error; karta w hubie /settings/integrations z agregowanym statusem. Po pierwszej iteracji widok przepisany w stylu istniejacych list (table.table + table-wrap + badge).

Accomplishments

  • Schema DB v3.7 Invoices gotowe: invoices/invoice_configs/invoice_number_counters/fakturownia_integration_settings plus orders.invoice_requested (multi-account przez integrations.type='fakturownia').
  • Pelen flow CRUD kont Fakturowni z szyfrowanym tokenem API i testem polaczenia (GET account.json) - operator moze dodawac/edytowac/usuwac konta i weryfikowac credentialsy bez restartu aplikacji.
  • IntegrationsRepository::updateTestResult() jako reusable wzorzec dla przyszlych integracji (eliminuje inline UPDATE w kazdym controllerze).
  • Dokumentacja techniczna zaktualizowana: db_schema.md (total tables 55 -> 59), architecture.md (sekcja Phase 113), tech_changelog.md (wpis 2026-05-10).

Task Commits

Inline execution (delegation: off) - bez atomowych commits per task. Calosc do jednego git commit:

Task Status Type Description
Task 1: Migracje DB Done feat 3 migracje SQL + db_schema.md (4 nowe tabele, kolumna orders.invoice_requested)
Task 2: Repository + ApiClient + updateTestResult Done feat FakturowniaIntegrationRepository, FakturowniaApiClient, IntegrationsRepository::updateTestResult, architecture.md
Task 3: Controller + views + routes + hub Done feat FakturowniaIntegrationController, 2 widoki, 6 routes, hub card, tech_changelog.md

Files Created/Modified

File Change Purpose
database/migrations/20260510_000104_create_invoices_tables.sql Created 4 tabele v3.7 Invoices
database/migrations/20260510_000105_add_invoice_requested_to_orders.sql Created Kolumna orders.invoice_requested + index
database/migrations/20260510_000106_seed_fakturownia_integration_type.sql Created DDL no-op stamp dla type='fakturownia'
src/Modules/Settings/FakturowniaIntegrationRepository.php Created CRUD kont Fakturowni (multi-account)
src/Modules/Settings/FakturowniaApiClient.php Created testConnection + STUB createInvoice/downloadPdf
src/Modules/Settings/FakturowniaIntegrationController.php Created Index/edit/save/test/delete
resources/views/settings/fakturownia.php Created Lista integracji (table.table + badge)
resources/views/settings/fakturownia-edit.php Created Form edycji integracji
src/Modules/Settings/IntegrationsHubController.php Modified Nowy param konstruktora + buildFakturowniaRow()
src/Modules/Settings/IntegrationsRepository.php Modified Nowa metoda updateTestResult()
routes/web.php Modified 3 use'y + DI wiring + 6 routes
.paul/codebase/db_schema.md Modified Sekcja Invoices + fakturownia_integration_settings + orders.invoice_requested
.paul/codebase/architecture.md Modified Sekcja Phase 113 + reorg Phase 108 + Module Inventory bump
.paul/codebase/tech_changelog.md Modified Wpis 2026-05-10

Decisions Made

Decision Rationale Impact
Multi-account przez integrations.type='fakturownia' (nie singleton) Klient moze miec wiele kont Fakturowni (rozne marki/oddzialy); spojne z shopPRO FakturowniaIntegrationRepository::findAll() zwraca liste; hub agreguje status; invoice_configs.integration_id wskazuje konkretne konto
is_delegated flag w invoice_configs (zamiast osobnej tabeli invoice_delegations) Jeden config = jeden tryb (lokalny vs delegowany); operator wybiera per config Kolejny plan: w InvoiceService::generate() rozgalez logike po config.is_delegated
Brak eventu invoice.created (decyzja z clarifications) receipt.created pozostaje czysty - regula wysylki paragonu mailem nie zostanie odpalona dla faktury Bezpieczenstwo automatyzacji; mozliwe rozszerzenie w przyszlosci jako osobny plan
Migracja 106 jako ALTER TABLE ... COMMENT (nie SELECT 1) SELECT 1; zwraca result set i blokuje kolejne zapytania pod PDO unbuffered (SQLSTATE[HY000] 2014) Wzorzec: migracje no-op zawsze jako DDL (ALTER COMMENT) - nie SELECT
AFTER notes usuniete z migracji 105 Kolumna notes w orders nie istnieje (notatki w osobnej tabeli order_notes); db_schema.md byl stale Naprawione + dodana adnotacja w db_schema.md
Widoki list - table.table + table-wrap + badge.badge--* (po feedbacku) Spojnosc z email-mailboxes.php/integrations.php; brak inline styles strukturalnych Wzorzec dla przyszlych list integracji

Deviations from Plan

Summary

Type Count Impact
Auto-fixed 3 Drobne, naprawione w czasie APPLY
Scope additions 1 Reusable helper (updateTestResult) - korzysc dla przyszlych integracji
Deferred 0 -

Total impact: Bez scope creep. Trzy drobne fixy w czasie APPLY (kolumna notes, SELECT 1, styl widoku), wszystkie naprawione w jednym przebiegu.

Auto-fixed Issues

1. [Migration] Brak kolumny notes w orders

  • Found during: Task 1 verify (pierwsze uruchomienie php bin/migrate.php)
  • Issue: Migracja 105 uzywala ADD COLUMN ... AFTER notes. Kolumna notes byla zadeklarowana w pierwotnej migracji 18, ale w nieznanym momencie zostala usunieta (notatki migrowane do order_notes). db_schema.md byl stale i pokazywal notes jako kolumne orders.
  • Fix: Usunieto AFTER notes z migracji 105 (kolumna trafia na koniec tabeli). Zaktualizowano db_schema.md (usunieto wiersz notes, dodano notke "Order notes are stored in the separate order_notes table").
  • Files: database/migrations/20260510_000105_add_invoice_requested_to_orders.sql, .paul/codebase/db_schema.md
  • Verification: php bin/migrate.php po naprawie - migracja przeszla.

2. [Migration] SELECT 1 w migracji 106 blokuje runner

  • Found during: Task 1 verify (drugie uruchomienie php bin/migrate.php)
  • Issue: SELECT 1; zwraca result set ktory pozostawal otwarty przy PDO unbuffered queries -> SQLSTATE[HY000] 2014: Cannot execute queries while other unbuffered queries are active.
  • Fix: Zastapiono SELECT 1; przez ALTER TABLE integrations COMMENT = '...'; - bezpieczny DDL no-op ktory nie zwraca result setu i jest idempotentny.
  • Files: database/migrations/20260510_000106_seed_fakturownia_integration_type.sql
  • Verification: Migracja przeszla.

3. [UI] Lista integracji Fakturownia z zlym stylem

  • Found during: User smoke test po wdrozeniu
  • Issue: Pierwsza wersja widoku fakturownia.php uzywala class="data-table" (nie istniejace) i inline'owych stylow strukturalnych - tabela wygladala obco wzgledem reszty UI.
  • Fix: Przepisano widok w stylu email-mailboxes.php: section.card + table-wrap + table.table + badge.badge--{success,muted,info} + przyciski usun przez js-confirm-delete/js-delete-btn (window.OrderProAlerts).
  • Files: resources/views/settings/fakturownia.php
  • Verification: User potwierdzil "Teraz jest ok".

Scope Addition

1. [Helper] IntegrationsRepository::updateTestResult()

  • Context: Plan zakladal "after teście integrations.last_test_status/last_test_http_code/last_test_at są zaktualizowane (przez IntegrationsRepository::updateTestResult())" - ale metoda nie istniala w IntegrationsRepository.
  • Decision: Dodano publiczna metode updateTestResult(int $integrationId, string $status, ?int $httpCode, string $message) zamiast inline'owego UPDATE w FakturowniaIntegrationController::test().
  • Korzysc: Reusable wzorzec dla przyszlych integracji (np. STAT-NET czy nowe API) - jeden punkt zapisu wynikow testow.

Deferred Items

Brak. Plan wykonany w pelnym zakresie (z auto-fixami w czasie APPLY).

Issues Encountered

Issue Resolution
MySQL/XAMPP offline przy pierwszym php -l + bin/migrate.php Uruchomione po stronie usera; po naprawach 105/106 migracje przeszly.
Stary notes w db_schema.md Usuniety; dodana adnotacja o order_notes.
SonarQube scan nie uruchomiony XAMPP env; gap odnotowany do nastepnego planu (kontynuacja z Phase 108/110 gap).

Next Phase Readiness

Ready:

  • Schema DB v3.7 Invoices kompletna - kolejne plany moga budowac InvoiceService, InvoiceRepository, InvoiceConfigController bez migracji DB.
  • FakturowniaIntegrationRepository::getDecryptedToken(int) gotowy do uzycia przez InvoiceService w trybie is_delegated=1.
  • FakturowniaApiClient ma STUB-y createInvoice/downloadPdf z jasnym RuntimeException - kolejny plan tylko implementuje cialo.
  • orders.invoice_requested gotowe do (a) importera Allegro/shopPRO, (b) toggle w UI szczegolow zamowienia.

Concerns:

  • Operator musi recznie utworzyc pierwszy invoice_config przed kolejnym planem (CRUD invoice_configs). Alternatywnie: kolejny plan moze dodac seed migracji z default config (name='Domyslny VAT', numbering_type='monthly', is_delegated=0).
  • Refaktor edycji receipt_configs na osobna podstrone (z planu pierwotnego, poza zakresem 113-01) musi zostac zaplanowany - obecnie zarzadzanie receipt_configs jest pod tabela na /settings/accounting. User zaznaczyl ze chce ten sam refaktor zrobic dla paragonow przy okazji wprowadzania faktur.

Blockers:

  • Brak.

Phase: 113-fakturownia-integration, Plan: 01 Completed: 2026-05-10