--- plan_id: 20260706-1430-modul-inwestycji title: Moduł inwestycji — instrumenty, wpłaty/wypłaty, ręczne wyceny, pulpit completed: 2026-07-06T14:55:00+02:00 storage: plan-first quality_radar: degraded --- # Summary: Moduł inwestycji — instrumenty, wpłaty/wypłaty, ręczne wyceny, pulpit ## Objective Dodać moduł inwestycji: płaska lista instrumentów (kategorie główne, np. Obligacje, ETF), operacje wpłat/wypłat per instrument, ręczne snapshoty wyceny per instrument oraz pulpit inwestycji z wykresem zbiorczym w czasie i tabelą per instrument. W trakcie sesji dodano też pulpit globalny (`/dashboard`) i przepięto dotychczasowy pulpit finansów pod `/finances`. ## What Was Built | Area | Result | |------|--------| | Schemat DB | 3 migracje `inv_instruments`, `inv_operations` (FK RESTRICT), `inv_valuations` (FK RESTRICT); seeder Obligacje/ETF | | Modele | `InstrumentModel` (`withStats`, `portfolioTimeline`, `hasChildren` — logika zarobku netto w jednym miejscu), `InvOperationModel`, `ValuationModel` | | CRUD | Instrumenty, operacje inwestycyjne (wpłaty/wypłaty), wyceny — pełny CRUD, filtry, blokada usunięcia instrumentu z powiązaniami | | Pulpit inwestycji | `/investments`: kafelki (netto/wartość/zarobek), wykres liniowy 3-seryjny w czasie, tabela per instrument z % zwrotu | | Pulpit globalny | `/dashboard`: kafel „Majątek razem" (saldo bieżące + wartość inwestycji) + sekcje Finanse/Inwestycje z linkami | | Pulpit finansów | dotychczasowy dashboard przepięty pod `/finances` (`Dashboard::finances`) | | Nawigacja | top-level „Pulpit" + dropdown „Finanse bieżące" (Pulpit finansów/Operacje/Kategorie) + dropdown „Inwestycje" (Pulpit/Wpłaty-wypłaty/Wyceny/Instrumenty) | ## Files Modified - `app/Database/Migrations/2026-07-06-140001_CreateInvInstruments.php`, `...140002_CreateInvOperations.php`, `...140003_CreateInvValuations.php` — schemat inwestycji - `app/Database/Seeds/DefaultInstrumentsSeeder.php` — idempotentny seed Obligacje/ETF - `app/Models/InstrumentModel.php`, `InvOperationModel.php`, `ValuationModel.php` — domena inwestycji - `app/Controllers/Instruments.php`, `InvOperations.php`, `Valuations.php`, `Investments.php` — CRUD + pulpit inwestycji - `app/Controllers/Dashboard.php` — `index()` globalny + `finances()` - `app/Views/instruments/{index,form}.php`, `inv_operations/{index,form}.php`, `valuations/{index,form}.php`, `investments/index.php` — widoki inwestycji - `app/Views/dashboard/index.php` (globalny, przepisany), `app/Views/dashboard/finances.php` (przeniesiony finansowy) - `app/Config/Routes.php` — trasy `investments/*`, `instruments/*`, `finances` - `app/Views/layout/main.php` — nawigacja zgrupowana w dropdowny ## Acceptance Criteria Results | Criterion | Status | Evidence | |-----------|--------|----------| | AC-1: instrumenty CRUD + blokada usunięcia | Pass | curl: dodanie OK; usunięcie ETF z operacjami → 302 + „Nie można usunąć instrumentu z operacjami lub wycenami" | | AC-2: operacje wpłata/wypłata + filtry | Pass | curl: deposit/withdraw zapisane; filtr `type=withdraw` zwraca wiersz 200,00; `instrument_id=1` → brak | | AC-3: ręczne wyceny per instrument | Pass | curl: wycena 950 na 2026-07-01 zapisana, użyta do zarobku | | AC-4: zarobek netto | Pass | ETF: netto 800,00 (1000−200), zarobek 150,00 (950−800), 18,75% | | AC-5: pulpit inwestycji | Pass | kafelki 800/950/150; `timeline=[{date:2026-07-01,net:800,value:950,profit:150}]`; tabela per instrument | ## Verification Results | Check | Result | Notes | |-------|--------|-------| | `php spark migrate` | Pass | 3 tabele `inv_*` na bazie hostido | | `php spark db:seed DefaultInstrumentsSeeder` | Pass | Obligacje, ETF (idempotentnie) | | `php -l` (7 nowych plików PHP + Dashboard) | Pass | brak błędów składni | | `php spark serve` + curl (login/CRUD/filtry/blokada/pulpity) | Pass | pełny przepływ end-to-end | | Zarobek netto ETF = 150 (18,75%) | Pass | zgodne z ręcznym wyliczeniem | | `/dashboard` globalny + `/finances` | Pass | globalny: majątek + sekcje; finances: 200 + 3 wykresy | | Dane testowe | Cleaned | `inv_operations=0`, `inv_valuations=0`, seed instrumentów zachowany | ## Quality Radar Results **Status:** degraded - New risks: brak nowych ryzyk duplikacji (jscpd/ast-grep wyłączone polityką). Kopiowanie wzorców zapytań z `OperationModel` świadome — osobna domena. - Resolved risks: logika zarobku netto w jednym miejscu (`InstrumentModel::withStats`), nie powielana w widokach; typ operacji `deposit|withdraw` jako ENUM + walidacja `in_list`. - Deferred risks: pełna indeksacja `codebase-memory-mcp` odłożona do `$paul-map-codebase`; weryfikacja runtime. - Raw outputs: `.paul/codebase/tooling_status.md` ## Deviations - **Wykonanie inline zamiast `delegation: auto`** — 3 zadania ściśle sekwencyjne, wspólne pliki (`Routes.php`, modele); delegacja tylko powielałaby odczyty wzorców. - **`.env` toggle** — tymczasowo `production→development` na czas migracji/testów (lokalny MySQL zgaszony, dev łączy do zdalnej hostido), po weryfikacji przywrócony na `production`. Netto zero zmian, boundary `.env` zachowany. - **Nawigacja rozszerzona** — zamiast jednego linku „Inwestycje" powstały dwa dropdowny (na prośbę użytkownika o zgrupowanie wcześniejszych pozycji). - **Pulpit globalny + `/finances`** — poza pierwotnym zakresem planu; dodane na prośbę użytkownika (globalny `/dashboard`, finansowy przepięty pod `/finances`). ## Key Decisions / Patterns - **Jedno źródło prawdy dla zarobku**: `InstrumentModel::withStats` liczy `net_invested = Σwpłat − Σwypłat`, `profit = ostatnia_wycena − net_invested`; kontrolery/widoki tylko konsumują. - **FK RESTRICT** na `inv_operations`/`inv_valuations` — instrument z powiązaniami nie da się skasować (spójne z blokadą w kontrolerze). - **Szereg czasowy portfela** liczony w PHP (`portfolioTimeline`) z kilku prostych zapytań — bez okien SQL; trywialne przy ręcznych wycenach. - **Pulpit globalny** agreguje majątek = saldo bieżące + wartość inwestycji; szczegóły delegowane do `/finances` i `/investments`. ## Follow-up - Wdrożenie produkcyjne `https://finanse.projectpro.pl/` — wgrać pliki + `vendor/`, uruchomić `php spark migrate` na serwerze (3 nowe tabele `inv_*`); `CI_ENVIRONMENT=production`. Schemat finansów bez zmian. - Opcjonalnie: `$paul-map-codebase` (pełny indeks codebase-memory-mcp) przed kolejnym planem. - Możliwe rozszerzenia: wykres per instrument, historia wartości vs wpłat na osi czasu z interpolacją, eksport.