diff --git a/.paul/PROJECT.md b/.paul/PROJECT.md index f89205c..faf97ab 100644 --- a/.paul/PROJECT.md +++ b/.paul/PROJECT.md @@ -12,6 +12,7 @@ Jednoosobowa aplikacja finansowa w CodeIgniter 4.7.3 i MySQL do ewidencji finans - ✓ Instrumenty, operacje, wyceny i pulpity inwestycji — Plan 2. - ✓ Import paragonów przez OpenAI Responses API z podpowiedziami kategorii — Plan 3. - ✓ Zapamiętywanie logowania przez 30 dni na wielu urządzeniach — Plan 4. +- ✓ Skanowanie paragonu kamerą telefonu i mobilny przegląd wyniku AI — Plan 20260713-2111. ## Trwałe wymagania i ograniczenia @@ -29,4 +30,4 @@ Jednoosobowa aplikacja finansowa w CodeIgniter 4.7.3 i MySQL do ewidencji finans | 2026-07-12 | Bez panelu urządzeń i „wyloguj wszędzie” | YAGNI; brak takiego wymagania | --- -*Last updated: 2026-07-12 after Plan 20260712-1647* +*Last updated: 2026-07-13 after Plan 20260713-2111* diff --git a/.paul/STATE.md b/.paul/STATE.md index e0013df..e14ba23 100644 --- a/.paul/STATE.md +++ b/.paul/STATE.md @@ -1,6 +1,6 @@ # STATE — finansePRO -**Aktualizacja:** 2026-07-12T17:31:28+02:00 +**Aktualizacja:** 2026-07-13T21:38:51+02:00 ## Project Reference @@ -8,10 +8,14 @@ CodeIgniter 4.7.3 + MySQL na hostido. Jedno konto z `.env`. Tryb PAUL: plan-firs ## Current Position -- Plan `20260712-1647-zapamietywanie-logowania`: **UKOŃCZONY**. +- Plan `20260713-2111-skanowanie-paragonu-kamera`: **UKOŃCZONY**. - Status: PLAN → APPLY → UNIFY zamknięte; gotowe do następnego planu. -- Dostarczono tokeny logowania ważne 30 dni, niezależne dla wielu urządzeń. -- Zdalna tabela `remember_tokens` została utworzona i zweryfikowana. +- Dostarczono natywne skanowanie paragonu tylną kamerą oraz mobilny układ przeglądu wyniku AI. +- Quality Radar post-apply: ok; UAT mobilny zatwierdzony. +- Po UNIFY poprawiono także mobilny widok historii importów (`app/Views/receipts/index.php`). +- Poprawiono mobilny widok historii wpłat i wypłat (`app/Views/inv_operations/index.php`). +- Poprawiono mobilny widok historii wycen (`app/Views/valuations/index.php`). +- Poprawiono mobilny widok listy instrumentów (`app/Views/instruments/index.php`). ## Loop Position @@ -22,25 +26,18 @@ PLAN ──▶ APPLY ──▶ UNIFY ## Session Continuity -- Last session: 2026-07-12T17:31:28+02:00 -- Stopped at: UNIFY planu zapamiętywania logowania. -- Next action: opcjonalnie potwierdzić UAT w dwóch profilach albo uruchomić `$paul-plan` dla kolejnej funkcji. -- Resume file: `.paul/plans/20260712-1647-zapamietywanie-logowania/SUMMARY.md` +- Last session: 2026-07-13T21:38:51+02:00 +- Stopped at: wszystkie zgłoszone widoki historii oraz lista instrumentów poprawione na mobile. +- Next action: opcjonalny UAT widoków na telefonie albo kolejny `$paul-plan`. +- Resume file: `.paul/plans/20260713-2111-skanowanie-paragonu-kamera/SUMMARY.md` ## Aktywne sprawy / do weryfikacji -- UAT: dwa profile przeglądarki, zamknięcie zwykłej sesji oraz wylogowanie tylko jednego urządzenia. -- `vendor/bin/phpunit` nie jest dostępny lokalnie; test `RememberTokenModelTest.php` został tylko sprawdzony przez `php -l`. -- Deploy hostido nie uruchamia migracji automatycznie; tabela dla tego planu została już utworzona zdalnie. +- UAT poprawionych historii na telefonie jest opcjonalny; kontrola składni i struktury responsywnej przeszła. +- Repozytorium ma wcześniejszą, niezwiązaną zmianę `.vscode/ftp-kr.sync.cache.json`; nie obejmować jej. ## Decisions -- Token per urządzenie; kolejne logowanie nie usuwa wcześniejszych tokenów. -- Wylogowanie usuwa wyłącznie token bieżącego cookie. -- Bez panelu urządzeń i globalnego wylogowania do czasu realnej potrzeby. - -## Uwagi - -- Radar post-apply: degraded z powodu niepełnego wyniku indeksu i braku PHPUnit. -- Repozytorium Git ma liczne wcześniejsze i niezwiązane zmiany; commit fazowy pominięty zgodnie z `preferences.auto_commit: false`. -- `ROADMAP.md` nie istnieje i pozostaje opcjonalny w trybie plan-first. +- Natywne `capture="environment"`; bez WebRTC i nowych zależności. +- Zachować jeden istniejący przepływ `Receipts::create`. +- Widoki mobilne adaptować responsywnym HTML/CSS bez zmian backendu. diff --git a/.paul/changelog/2026-07-13.md b/.paul/changelog/2026-07-13.md new file mode 100644 index 0000000..0eb2cd0 --- /dev/null +++ b/.paul/changelog/2026-07-13.md @@ -0,0 +1,20 @@ +# 2026-07-13 + +## Co zrobiono + +- [Plan 20260713-2111] Dodano skanowanie paragonu bezpośrednio tylną kamerą telefonu. +- Zachowano istniejący upload JPG/JPEG/PNG/PDF/JSON i przepływ analizy AI. +- Poprawiono responsywność formularza przeglądu pozycji po analizie AI. +- Po zamknięciu planu poprawiono mobilny widok historii importów: wiersze tabeli zmieniają się w czytelne karty. +- Poprawiono mobilny widok historii wpłat i wypłat inwestycyjnych tym samym układem kart. +- Poprawiono mobilny widok historii wycen inwestycyjnych. +- Poprawiono mobilny widok listy instrumentów inwestycyjnych. + +## Zmienione pliki + +- `app/Views/receipts/new.php` +- `app/Views/receipts/review.php` +- `app/Views/receipts/index.php` +- `app/Views/inv_operations/index.php` +- `app/Views/valuations/index.php` +- `app/Views/instruments/index.php` diff --git a/.paul/codebase/impact_map.md b/.paul/codebase/impact_map.md index b63b06b..f7a28dc 100644 --- a/.paul/codebase/impact_map.md +++ b/.paul/codebase/impact_map.md @@ -1,5 +1,18 @@ # Impact Map +## Post-apply 20260713-2111 +- Zmieniono wyłącznie `app/Views/receipts/new.php` i `app/Views/receipts/review.php`. +- Aparat korzysta z istniejącego pola `receipt` i `Receipts::create`; backend, routing, parser, modele i baza bez zmian. +- Mobilny przegląd pozycji używa układu kart poniżej `md`, zachowując nazwy pól i skrypt grupowania. +- UAT aparatu i poprawionego przeglądu zatwierdzony przez użytkownika. + +## Plan 20260713-2111 — skanowanie paragonu kamerą telefonu +- UI: `app/Views/receipts/new.php`; istniejące pole `receipt` może użyć natywnego `capture="environment"`. +- Backend: `Receipts::create` już obsługuje JPG/JPEG/PNG do 10 MB i przekazuje obraz do obecnego parsera; bez zmiany kontrolera. +- Trasy, parser AI, modele, baza i zapis operacji pozostają bez zmian. +- UAT: telefon mobilny — tylna kamera, wysłanie zdjęcia, przejście do przeglądu oraz zachowany wybór istniejącego pliku. +- Ukryte sprzężenie: zachować `name="receipt"`, `multipart/form-data` i obecny `accept`, aby nie rozdzielić przepływu uploadu. + ## Post-apply 20260712-1647 - Mechanizm wdrożony w kontrolerze logowania, filtrze, widoku, modelu i migracji. - Zdalna tabela `remember_tokens` istnieje. diff --git a/.paul/codebase/quality_risks.md b/.paul/codebase/quality_risks.md index bd36598..90b34ed 100644 --- a/.paul/codebase/quality_risks.md +++ b/.paul/codebase/quality_risks.md @@ -1,5 +1,18 @@ # 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. diff --git a/.paul/codebase/radar/codebase-memory-plan.txt b/.paul/codebase/radar/codebase-memory-plan.txt index 28ba140..dcc28b6 100644 --- a/.paul/codebase/radar/codebase-memory-plan.txt +++ b/.paul/codebase/radar/codebase-memory-plan.txt @@ -1,15 +1,13 @@ -Tryb: plan -Data: 2026-07-12T16:47:19+02:00 -Projekt: C-visual-studio-code-finansePRO -Status indeksu: indexed, moderate, 789 nodes, 1015 edges - -Zapytania: logowanie, sesja, filtr auth, logout, remember. - -Najważniejsze pliki: -- `app/Controllers/Auth.php` -- `app/Filters/AuthFilter.php` -- `app/Views/auth/login.php` -- `app/Config/Session.php` -- `app/Config/Cookie.php` - -Wniosek: osobne trwałe tokeny per urządzenie odtwarzające istniejącą sesję; bez wydłużania globalnej sesji. +Plan scan: 2026-07-13T21:11:21+02:00 +Scope: skanowanie paragonu bezpośrednio z kamery telefonu +Project: C-visual-studio-code-finansePRO +Index status: ready; 789 nodes; 1015 edges +Relevant symbols: +- app/Controllers/Receipts.php: Receipts::new +- app/Controllers/Receipts.php: Receipts::create (lines 41-147; accepts JPG/JPEG/PNG and routes them through existing parser) +- app/Views/receipts/new.php: existing multipart input name="receipt", accepts image/* plus PDF/JSON +- app/Config/Routes.php: GET receipts/new, POST receipts +Impact conclusion: native HTML capture hint in the existing view; no backend, route, parser, model, or database change. +Trace note: trace_path did not resolve the qualified method despite search_graph result; code snippet and connected graph search were sufficient for this one-view change. +jscpd: disabled by policy +ast-grep: disabled by policy diff --git a/.paul/codebase/radar/codebase-memory-post-apply.txt b/.paul/codebase/radar/codebase-memory-post-apply.txt index 15e2b4b..594ef06 100644 --- a/.paul/codebase/radar/codebase-memory-post-apply.txt +++ b/.paul/codebase/radar/codebase-memory-post-apply.txt @@ -1,12 +1,16 @@ -Tryb: post-apply -Data: 2026-07-12T17:31:28+02:00 -Projekt: C-visual-studio-code-finansePRO - -- Indeks moderate odświeżony: 789 nodes, 1015 edges. -- `search_graph` nie zwrócił nowych symboli `RememberTokenModel`. -- `search_code` zakończył się błędem tworzenia pliku tymczasowego. -- Fallback: bezpośredni lint 6 zmienionych plików — wszystkie poprawne. -- Zdalna tabela `remember_tokens`: 6 kolumn, 3 indeksy. -- PHPUnit: niedostępny, brak `vendor/bin/phpunit`. - -Status: degraded — kod i schemat sprawdzone, brak automatycznego testu runtime. +Post-apply scan: 2026-07-13T21:29:46+02:00 +Plan: 20260713-2111-skanowanie-paragonu-kamera +Project: C-visual-studio-code-finansePRO +Index refreshed in fast mode: ready; 835 nodes; 1048 edges +Modified source files: +- app/Views/receipts/new.php +- app/Views/receipts/review.php +Impact conclusion: +- Existing Receipts::create flow, routes, parser, models, and database remain unchanged. +- Native camera capture reuses the receipt upload field. +- Mobile review layout changes presentation only; form names and grouping script remain intact. +Verification: +- php -l both views: pass +- mobile UAT camera and review: approved by user +jscpd: disabled by policy +ast-grep: disabled by policy diff --git a/.paul/codebase/tooling_status.md b/.paul/codebase/tooling_status.md index 6db5448..cfdb4a4 100644 --- a/.paul/codebase/tooling_status.md +++ b/.paul/codebase/tooling_status.md @@ -1,11 +1,12 @@ # Tooling Status -- Timestamp: 2026-07-12T17:31:28+02:00 +- Timestamp: 2026-07-13T21:29:46+02:00 - Scan mode: post-apply -- codebase-memory-mcp: degraded; indeks odświeżony, ale nowe symbole nie zostały zwrócone, a `search_code` zgłosił błąd pliku tymczasowego -- fallback: `php -l` dla 6 plików — pass -- PHPUnit: unavailable (`vendor/bin/phpunit` missing) +- codebase-memory-mcp: ok; CLI 0.6.1, indeks odświeżony w trybie fast (835 węzłów, 1048 krawędzi) +- Queries: `index_repository`, `index_status`, `search_graph` +- PHP syntax: pass dla `app/Views/receipts/new.php` i `app/Views/receipts/review.php` +- Mobile UAT: pass, potwierdzony przez użytkownika - jscpd: disabled by policy - ast-grep: disabled by policy - Raw output: `.paul/codebase/radar/codebase-memory-post-apply.txt` -- Next action: opcjonalny UAT dwóch profili przeglądarki. +- Next action: pętla zamknięta; gotowe do kolejnego planu. diff --git a/.paul/plans/20260713-2111-skanowanie-paragonu-kamera/PLAN.md b/.paul/plans/20260713-2111-skanowanie-paragonu-kamera/PLAN.md new file mode 100644 index 0000000..47a26a1 --- /dev/null +++ b/.paul/plans/20260713-2111-skanowanie-paragonu-kamera/PLAN.md @@ -0,0 +1,147 @@ +--- +plan_id: 20260713-2111-skanowanie-paragonu-kamera +title: Skanowanie paragonu kamerą telefonu +storage: plan-first +legacy_phase: null +created: 2026-07-13T21:11:21+02:00 +status: planned +type: execute +autonomous: false +delegation: auto +files_modified: + - app/Views/receipts/new.php +quality_radar: ok +--- + + +## Cel +Umożliwić wykonanie zdjęcia paragonu tylną kamerą telefonu bezpośrednio z formularza importu. + +## Uzasadnienie +Użytkownik nie musi wcześniej zapisywać zdjęcia ani wybierać go z galerii; wykonane zdjęcie trafia do istniejącego importu i analizy AI. + +## Wynik +Formularz `receipts/new` korzysta z natywnego mechanizmu HTML `capture="environment"`, zachowując dotychczasowy upload JPG/PNG/PDF/JSON i istniejący endpoint `Receipts::create`. + + + +## Dokumentacja projektu +@.paul/PROJECT.md +@.paul/STATE.md +@.paul/plans/20260706-2046-import-paragonow/SUMMARY.md +@.paul/codebase/architecture.md +@.paul/codebase/impact_map.md +@.paul/codebase/quality_risks.md + +## Pliki źródłowe +@app/Views/receipts/new.php +@app/Controllers/Receipts.php +@app/Config/Routes.php + + + +- Przyjęto natywny wybór tylnej kamery telefonu; nie jest potrzebny podgląd obrazu na żywo ani własny interfejs aparatu. + + + +## Quality Radar + +**Status:** ok +**Narzędzia:** codebase-memory-mcp 0.6.1 (indeks gotowy, 789 węzłów / 1015 krawędzi); jscpd i ast-grep wyłączone polityką. + +## Obszary wpływu + +- `app/Views/receipts/new.php` — jedyne miejsce wymagające zmiany: natywna wskazówka użycia tylnej kamery i jasny tekst formularza. +- `Receipts::create` — bez zmian; już waliduje, zapisuje i parsuje JPG/JPEG/PNG do 10 MB. +- Routing, parser AI, modele i baza danych — bez zmian. +- Weryfikacja — telefon z przeglądarką mobilną oraz kontrola zachowania dotychczasowego wyboru pliku. + +## Ryzyka duplikacji / hardcodowania + +- Nie tworzyć drugiego endpointu ani drugiego przepływu uploadu; zdjęcie ma użyć istniejącego pola `receipt` i `Receipts::create`. +- Atrybut `capture` jest wskazówką dla przeglądarki, więc zachowanie aparatu zależy od telefonu; obsłużone przez checkpoint UAT. + +## Jawne odroczenia + +- WebRTC, własny podgląd kamery, kadrowanie, kompresja i skanowanie wielu zdjęć — poza zakresem; dodać dopiero po osobnym wymaganiu. + + + + + + +## AC-1: Uruchomienie tylnej kamery na telefonie +```gherkin +Given użytkownik otworzył formularz nowego importu na obsługiwanym telefonie +When wybiera pole skanu paragonu +Then przeglądarka umożliwia wykonanie zdjęcia tylną kamerą +``` + +## AC-2: Zdjęcie korzysta z istniejącego importu +```gherkin +Given użytkownik wykonał zdjęcie paragonu w formularzu +When wysyła formularz +Then zdjęcie trafia jako pole `receipt` do `Receipts::create` i przechodzi dotychczasowy przepływ parsowania oraz przeglądu +``` + +## AC-3: Dotychczasowe formaty pozostają dostępne +```gherkin +Given użytkownik nie chce wykonać zdjęcia aparatem +When korzysta z formularza importu +Then nadal może przekazać obsługiwany plik JPG, JPEG, PNG, PDF lub JSON +``` + + + + + + + Task 1: Włączyć natywne przechwytywanie zdjęcia + app/Views/receipts/new.php + + Dodać do istniejącego `input type="file"` atrybut `capture="environment"`, bez JavaScriptu i bez nowego formularza lub endpointu. Zachować `name="receipt"`, `required`, wszystkie obecne typy `accept` oraz limit opisany w UI. Zmienić etykietę i krótki tekst pomocniczy tak, aby użytkownik telefonu rozumiał możliwość zrobienia zdjęcia i dalszą analizę AI. + + `php -l app/Views/receipts/new.php` oraz kontrola źródła: dokładnie jedno pole `name="receipt"` z `capture="environment"`. + AC-1, AC-2 i AC-3 są pokryte w kodzie formularza, a dotychczasowy backend pozostaje nietknięty. + + + + Task 2: Potwierdzić import zdjęcia na telefonie + app/Views/receipts/new.php + + Na telefonie otworzyć `/receipts/new`, uruchomić pole pliku, wykonać zdjęcie paragonu tylną kamerą i wysłać formularz. Potwierdzić przejście do przeglądu rozpoznanych pozycji. Następnie sprawdzić, że formularz nadal pozwala wybrać wcześniej istniejący obsługiwany plik. + + Manualny UAT na docelowym telefonie: aparat tylny → zdjęcie → upload → ekran przeglądu; dodatkowo wybór istniejącego pliku. + AC-1, AC-2 i AC-3 potwierdzone na urządzeniu mobilnym. + + + + + +## Nie zmieniać +- `app/Controllers/Receipts.php`, `app/Libraries/ReceiptParser.php`, tras, modeli, migracji ani schematu bazy. +- Istniejącego limitu 10 MB, whitelisty rozszerzeń oraz półautomatycznego zatwierdzania pozycji. + +## Limity zakresu +- Jedno zdjęcie / jeden plik na import. +- Bez WebRTC, JavaScriptowego podglądu, kadrowania, filtrów obrazu, kompresji i galerii wielu stron. +- Bez nowych zależności. + + + +- [ ] `php -l app/Views/receipts/new.php` +- [ ] Pole `receipt` zawiera `capture="environment"` i zachowuje obecny `accept`. +- [ ] Manualny UAT aparatu i dotychczasowego wyboru pliku na telefonie. +- [ ] Nie zmieniono backendu, routingu ani bazy danych. +- [ ] Ryzyka Quality Radar obsłużono lub jawnie odroczono. + + + +- [ ] Wszystkie AC przechodzą. +- [ ] Weryfikacja automatyczna i mobilna jest zakończona. +- [ ] Zmiana obejmuje tylko istniejący widok formularza. + + + +SUMMARY.md path: `.paul/plans/20260713-2111-skanowanie-paragonu-kamera/SUMMARY.md` + diff --git a/.paul/plans/20260713-2111-skanowanie-paragonu-kamera/SUMMARY.md b/.paul/plans/20260713-2111-skanowanie-paragonu-kamera/SUMMARY.md new file mode 100644 index 0000000..a7d596f --- /dev/null +++ b/.paul/plans/20260713-2111-skanowanie-paragonu-kamera/SUMMARY.md @@ -0,0 +1,66 @@ +--- +plan_id: 20260713-2111-skanowanie-paragonu-kamera +title: Skanowanie paragonu kamerą telefonu +completed: 2026-07-13T21:29:46+02:00 +storage: plan-first +quality_radar: ok +--- + +# Summary: Skanowanie paragonu kamerą telefonu + +## Objective + +Umożliwić wykonanie zdjęcia paragonu tylną kamerą telefonu bezpośrednio z formularza importu i przekazać je do istniejącej analizy AI. + +## What Was Built + +| Obszar | Rezultat | +|--------|----------| +| Import | Istniejące pole `receipt` otrzymało natywne `capture="environment"`; zachowano wybór JPG/JPEG/PNG/PDF/JSON. | +| Przegląd AI | Tabela pozycji zmienia się na czytelne karty na ekranach poniżej `md`; przyciski i podgląd księgowania układają się responsywnie. | +| Backend | Bez zmian; oba widoki korzystają z istniejącego `Receipts::create`, nazw pól i logiki grupowania. | + +## Files Modified + +- `app/Views/receipts/new.php` — uruchomienie tylnej kamery i doprecyzowany tekst formularza. +- `app/Views/receipts/review.php` — mobilny układ pozycji po analizie AI. + +## Acceptance Criteria Results + +| Kryterium | Status | Dowód | +|-----------|--------|-------| +| AC-1: tylna kamera telefonu | Pass | `capture="environment"`; użytkownik zatwierdził UAT na telefonie. | +| AC-2: istniejący import | Pass | Zachowano pojedyncze `name="receipt"`; zdjęcie przeszło do ekranu przeglądu. | +| AC-3: dotychczasowe formaty | Pass | Zachowano pełne `accept` dla JPG/JPEG/PNG/PDF/JSON; UAT zatwierdzony. | + +## Verification Results + +| Kontrola | Wynik | Uwagi | +|----------|-------|-------| +| `php -l app/Views/receipts/new.php` | Pass | Brak błędów składni. | +| `php -l app/Views/receipts/review.php` | Pass | Brak błędów składni. | +| Kontrola formularza | Pass | Jedno pole `receipt`, zachowane `required`, `accept`, limit 10 MB i UTF-8 bez BOM. | +| Kontrola granic | Pass | Kontroler, parser, routing, modele i baza bez zmian. | +| Mobilny UAT | Pass | Użytkownik potwierdził aparat oraz poprawiony ekran przeglądu. | + +## Quality Radar Results + +**Status:** ok + +- Nowe ryzyka: brak. +- Rozwiązane ryzyka: mobilny overflow formularza przeglądu usunięty bez drugiego przepływu uploadu. +- Odroczone ryzyka: zachowanie `capture` zależy od przeglądarki; potwierdzone na docelowym telefonie. WebRTC, kadrowanie i wiele zdjęć pozostają poza zakresem. +- Raw outputs: `.paul/codebase/radar/codebase-memory-post-apply.txt` + +## Deviations + +- Po pierwszym UAT użytkownik zgłosił rozjeżdżający się mobilny formularz po analizie AI. Zakres rozszerzono o `app/Views/receipts/review.php`; zmiana nie naruszyła backendu ani kontraktu formularza. + +## Key Decisions / Patterns + +- Natywne HTML i responsywny CSS/Bootstrap zamiast WebRTC lub nowej zależności. +- Jeden istniejący endpoint i jedno źródło logiki importu. + +## Follow-up + +- Poprawić mobilny widok historii importów — osobne zlecenie użytkownika po zamknięciu tej pętli. diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index 67f6adf..462a144 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -58,16 +58,22 @@ "lmtime": 1783364116680, "modified": false }, + "2026-07-06-200005_AddDisplayNameToReceiptItems.php": { + "type": "-", + "size": 580, + "lmtime": 1783366821444, + "modified": false + }, ".gitkeep": { "type": "-", "size": 0, "lmtime": 0, "modified": false }, - "2026-07-06-200005_AddDisplayNameToReceiptItems.php": { + "2026-07-12-160001_CreateRememberTokens.php": { "type": "-", - "size": 580, - "lmtime": 1783366821444, + "size": 1003, + "lmtime": 1783867980803, "modified": false } } @@ -117,8 +123,14 @@ }, "ReceiptModel.php": { "type": "-", - "size": 937, - "lmtime": 1783364152838, + "size": 1082, + "lmtime": 1783870528100, + "modified": false + }, + "RememberTokenModel.php": { + "type": "-", + "size": 2015, + "lmtime": 1783868007680, "modified": false }, "ValuationModel.php": { @@ -145,8 +157,8 @@ "Controllers": { "Auth.php": { "type": "-", - "size": 1314, - "lmtime": 0, + "size": 2159, + "lmtime": 1783868092101, "modified": false }, "BaseController.php": { @@ -199,8 +211,8 @@ }, "Receipts.php": { "type": "-", - "size": 11901, - "lmtime": 1783366894415, + "size": 12169, + "lmtime": 1783870528101, "modified": false }, "Valuations.php": { @@ -219,7 +231,14 @@ } }, "Views": { - "auth": {}, + "auth": { + "login.php": { + "type": "-", + "size": 1378, + "lmtime": 1783868092103, + "modified": false + } + }, "categories": {}, "dashboard": {}, "errors": {}, @@ -229,8 +248,8 @@ "layout": { "main.php": { "type": "-", - "size": 3815, - "lmtime": 1783364283479, + "size": 3980, + "lmtime": 1783870528102, "modified": false } }, @@ -281,6 +300,14 @@ "modified": false } } + }, + "Filters": { + "AuthFilter.php": { + "type": "-", + "size": 1020, + "lmtime": 1783868092102, + "modified": false + } } }, "builds": { @@ -340,26 +367,57 @@ "size": 4897, "lmtime": 1783367953541, "modified": false + }, + "2026-07-12.md": { + "type": "-", + "size": 634, + "lmtime": 1783870371082, + "modified": false } }, "codebase": { "impact_map.md": { "type": "-", - "size": 3932, - "lmtime": 1783368033490, + "size": 4777, + "lmtime": 1783870371083, "modified": false }, "quality_risks.md": { "type": "-", - "size": 2521, - "lmtime": 1783368045743, + "size": 3382, + "lmtime": 1783870371084, "modified": false }, - "radar": {}, + "radar": { + "codebase-memory-plan.txt": { + "type": "-", + "size": 483, + "lmtime": 1783867802646, + "modified": false + }, + "codebase-memory-post-apply.txt": { + "type": "-", + "size": 553, + "lmtime": 1783870371080, + "modified": false + } + }, "tooling_status.md": { "type": "-", - "size": 1103, - "lmtime": 1783364442507, + "size": 513, + "lmtime": 1783870371086, + "modified": false + }, + "architecture.md": { + "type": "-", + "size": 652, + "lmtime": 1783870371081, + "modified": false + }, + "db_schema.md": { + "type": "-", + "size": 598, + "lmtime": 1783870371081, "modified": false } }, @@ -371,6 +429,8 @@ }, "handoffs": {}, "plans": { + "20260706-1248-fundament-wydatki-przychody": {}, + "20260706-1430-modul-inwestycji": {}, "20260706-2046-import-paragonow": { "PLAN.md": { "type": "-", @@ -384,19 +444,42 @@ "lmtime": 1783367919539, "modified": false } + }, + "20260712-1647-zapamietywanie-logowania": { + "PLAN.md": { + "type": "-", + "size": 7269, + "lmtime": 1783867802645, + "modified": false + }, + "SUMMARY.md": { + "type": "-", + "size": 3439, + "lmtime": 1783870407435, + "modified": false + } } }, "PROJECT.md": { "type": "-", - "size": 645, - "lmtime": 0, + "size": 1407, + "lmtime": 1783870371088, + "modified": false + }, + "rules": { + "ast-grep": {}, + "jscpd": {} + }, + "run_remember_tokens_migration.php": { + "type": "-", + "size": 1746, + "lmtime": 1783869602000, "modified": false }, - "rules": {}, "STATE.md": { "type": "-", - "size": 2648, - "lmtime": 1783368004681, + "size": 1853, + "lmtime": 1783870407436, "modified": false } }, @@ -451,9 +534,50 @@ "lmtime": 0, "modified": false }, - "tests": {}, + "tests": { + "unit": { + "HealthTest.php": { + "type": "-", + "size": 1440, + "lmtime": 0, + "modified": false + }, + "RememberTokenModelTest.php": { + "type": "-", + "size": 914, + "lmtime": 1783868195270, + "modified": false + }, + "ReceiptModelTest.php": { + "type": "-", + "size": 737, + "lmtime": 1783870528103, + "modified": false + } + } + }, "vendor": {}, - "writable": {} + "writable": {}, + ".codebase-memory": { + ".gitattributes": { + "type": "-", + "size": 123, + "lmtime": 1783867604274, + "modified": false + }, + "artifact.json": { + "type": "-", + "size": 263, + "lmtime": 1783867604273, + "modified": false + }, + "graph.db.zst": { + "type": "-", + "size": 315382, + "lmtime": 1783867604244, + "modified": false + } + } } }, "$version": 1 diff --git a/app/Views/instruments/index.php b/app/Views/instruments/index.php index 779ce6c..a47b67e 100644 --- a/app/Views/instruments/index.php +++ b/app/Views/instruments/index.php @@ -3,14 +3,14 @@ section('content') ?> number_format((float) $v, 2, ',', ' ') . ' zł'; ?> -
+

Instrumenty

+ Nowy instrument
- +
@@ -25,17 +25,17 @@ - - - - - + + + + - -
Instrument
Brak instrumentów.
brak wyceny' ?> +
brak wyceny' ?> + + Edytuj Usuń @@ -46,4 +46,33 @@
+ + endSection() ?> diff --git a/app/Views/inv_operations/index.php b/app/Views/inv_operations/index.php index 2f40f9f..0862736 100644 --- a/app/Views/inv_operations/index.php +++ b/app/Views/inv_operations/index.php @@ -3,7 +3,7 @@ section('content') ?> number_format((float) $v, 2, ',', ' ') . ' zł'; ?> -
+

Operacje inwestycyjne

+ Nowa operacja
@@ -47,7 +47,7 @@
- +
@@ -63,19 +63,19 @@ - - - - + + + - - + -
Data
Brak operacji dla wybranych filtrów.
+
+ + Edytuj Usuń @@ -86,4 +86,33 @@
+ + endSection() ?> diff --git a/app/Views/receipts/index.php b/app/Views/receipts/index.php index 1e6a151..1fcb989 100644 --- a/app/Views/receipts/index.php +++ b/app/Views/receipts/index.php @@ -11,14 +11,14 @@ $badges = [ ]; ?> -
+

Import paragonów

+ Nowy import
- +
@@ -34,14 +34,14 @@ $badges = [ - - - - - - - - + + + + + + +
Data
Brak zaimportowanych paragonów.
+
Przegląd @@ -56,4 +56,30 @@ $badges = [
+ + endSection() ?> diff --git a/app/Views/receipts/new.php b/app/Views/receipts/new.php index 3bb1787..8d719c2 100644 --- a/app/Views/receipts/new.php +++ b/app/Views/receipts/new.php @@ -10,11 +10,12 @@
'row g-3']) ?>
- + + accept=".jpg,.jpeg,.png,.pdf,.json,image/*,application/pdf,application/json" + capture="environment">
- Obsługiwane formaty: skan JPG/PNG, PDF lub JSON. Maks. 10 MB. + Na telefonie możesz zrobić zdjęcie paragonu. Obsługiwane formaty: JPG/PNG, PDF lub JSON. Maks. 10 MB. Po wgraniu AI odczyta pozycje i zaproponuje kategorie do zatwierdzenia.
diff --git a/app/Views/receipts/review.php b/app/Views/receipts/review.php index aae0345..29679b7 100644 --- a/app/Views/receipts/review.php +++ b/app/Views/receipts/review.php @@ -3,7 +3,7 @@ section('content') ?> number_format((float) $v, 2, ',', ' ') . ' zł'; ?> -
+

Przegląd paragonu

← Historia importów
@@ -23,7 +23,7 @@ (podpowiedź zaznaczona; „— pomiń —” = nie księguj)
- +
@@ -37,17 +37,17 @@ - - -
Pozycja
+ z paragonu: + + +
@@ -44,11 +44,11 @@ - - - - - + + + +
Data
Brak wycen.
+
Edytuj Usuń @@ -59,4 +59,33 @@
+ + endSection() ?>