Files
finansePRO/.paul/codebase/quality_risks.md
T
2026-07-13 21:46:29 +02:00

55 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Quality Risks
## Post-apply 20260713-2111
- **Obsłużone:** jeden istniejący upload, natywne `capture="environment"`, brak nowej zależności i zmian backendu.
- **Obsłużone po UAT:** mobilny overflow formularza przeglądu — tabela zmienia się w karty poniżej `md`.
- **Potwierdzone:** nazwy pól, `accept`, `required`, limit 10 MB i skrypt grupowania pozostały spójne.
- **Zaakceptowane:** zachowanie selektora aparatu zależy od przeglądarki; działa na docelowym telefonie.
## Plan 20260713-2111 — skanowanie paragonu kamerą telefonu
- **Jedno źródło uploadu:** użyć istniejącego pola `receipt` i `Receipts::create`; bez drugiego endpointu, kontrolera lub parsera.
- **Natywna funkcja platformy:** `capture="environment"`; bez WebRTC, JavaScriptu i nowej zależności.
- **Zgodność urządzeń:** `capture` jest wskazówką dla przeglądarki; wymagany manualny UAT na docelowym telefonie.
- **Regresja formatów:** zachować istniejący `accept` dla JPG/JPEG/PNG/PDF/JSON i sprawdzić wybór pliku obok aparatu.
- **Odroczone:** podgląd na żywo, kadrowanie, kompresja i wiele zdjęć — brak wymagania (YAGNI).
## Post-apply 20260712-1647
- **Obsłużone:** osobne tokeny urządzeń, hash walidatora, `hash_equals`, selektywne wylogowanie.
- **Obsłużone operacyjnie:** tabela utworzona na zdalnej bazie po wykryciu błędu braku migracji.
- **Odroczone:** PHPUnit i UAT dwóch profili; brak lokalnego `vendor/` i potwierdzenia użytkownika.
## Plan 20260712-1647 — zapamiętywanie logowania
- **Sekret tokenu:** w bazie wyłącznie hash walidatora; porównanie przez `hash_equals`.
- **Wiele urządzeń:** nowe logowanie dopisuje token, nie zastępuje aktywnych tokenów.
- **Wylogowanie:** unieważnia tylko token bieżącego cookie; sesja i cookie są usuwane.
- **Cookie:** 30 dni, HttpOnly, SameSite=Lax, Secure na produkcji.
- **Jedno źródło czasu życia:** stała w modelu tokenów.
- **YAGNI:** bez panelu urządzeń, harmonogramu i globalnego wylogowania.
**Aktualizacja:** 2026-07-06 (post-apply Plan 2 — degraded)
## Zaakceptowane świadomie
- **Kopiowanie wzorców zapytań** z `OperationModel` do `InvOperationModel`/`ValuationModel` (filtered/join). Osobna domena (brak type income/expense, dochodzą wyceny) — nie konsolidować w bazowy model, kod krótki.
- **Format kwoty** `number_format(...,2,',',' ').' zł'` powtórzony w widokach jako lokalna funkcja `$fmt`. Trywialny, świadomie nie wydzielony do helpera (YAGNI).
## Rozwiązane
- Zarobek netto: jedno źródło prawdy `InstrumentModel::withStats` (`net_invested`, `profit`, `percent`); nie liczony w widokach.
- Typ operacji inwestycyjnej: ENUM `deposit|withdraw` w DB + walidacja `in_list` w modelu + sanity w kontrolerze.
- Integralność: FK RESTRICT na `inv_operations`/`inv_valuations`.
## Odłożone
- Pełna indeksacja `codebase-memory-mcp``$paul-map-codebase`.
- jscpd/ast-grep — wyłączone polityką w `config.md` (skan on-demand).
## Import paragonów (Plan 3)
- **Zapis operacji przez `OperationModel`** — bez duplikacji walidacji/logiki; `receipt_id` dodany do `allowedFields`. Jedno źródło prawdy zachowane.
- **Format kwoty `$fmt`** powtórzony w widokach `receipts/` — świadomie spójny z resztą (YAGNI, jak w Plan 1/2).
- **Podpowiedzi kategorii**: priorytet `receipt_category_map` (nauczone) > propozycja AI; NIC nie księgowane bez `confirm()` użytkownika (wymóg twardy spełniony).
- **Klucz OpenAI** czytany z `.env` (`OPEN_AI_API`); nie logowany, nie w repo. Model konfigurowalny (`openai.model`).
- **OCR paragonów niedeterministyczny**: wiersze rabatu/gęsty druk bywają źle odczytane (waha się między próbami). Świadomie kryte edytowalnymi kwotami/nazwami w przeglądzie (pół-automat). o4-mini najdokładniejszy z testowanych (suma pozycji = total co do grosza), gpt-4o/4.1 gorzej.
- **Mechanizm PDF**: konieczne **Responses API + input_file** — chat-completions `file_data` NIE dostarcza treści PDF (model halucynuje). Rozstrzygnięte i wdrożone.
- **Do obserwacji**: `normalize()` robi dokładne dopasowanie surowej nazwy — przy rozbieżnych nazwach tej samej rzeczy podpowiedź się nie pojawi; rozbudować gdy za wąska. Koszt tokenów OpenAI per import (o4-mini). Ewent. zapamiętywanie ładnej nazwy w `receipt_category_map`.
## Do obserwacji
- `portfolioTimeline` liczony w PHP O(daty × operacje) — trywialne przy ręcznych wycenach; przy dużej liczbie wpisów rozważyć agregację SQL.