Initial commit
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# SoftSPM_2 - aplikacja Laravel (nakładka + szkielet)
|
||||
|
||||
Historycznie ten katalog trzymał **tylko pliki specyficzne dla SoftSPM** (modele,
|
||||
kontrolery, widoki, konfiguracja, trasy), a czysty szkielet Laravela stał osobno
|
||||
na UAT jako `softspm_pge`. Od 2026-09-03 katalog jest **pełnym, uruchamialnym
|
||||
projektem Laravel** - szkielet został domieszany lokalnie, żeby dało się pracować
|
||||
i testować na stacji roboczej.
|
||||
|
||||
Lista plików nakładki (to, co nakładamy na szkielet na UAT/produkcji) jest
|
||||
zapisana w [`docker/overlay-files.txt`](docker/overlay-files.txt).
|
||||
|
||||
> Migracja legacy PHP 5.4/5.6 → Laravel.
|
||||
> **Źródło migracji: `C:\Programy\xampp_old\htdocs\trzeciCloude_v1\`** - NIE `newPGE`
|
||||
> ani inne kopie w `htdocs/`. Audyt legacy i mapa `siteNNN` → trasy: [docs/LEGACY.md](docs/LEGACY.md).
|
||||
> Kontekst i decyzje: patrz pamięć
|
||||
> projektu Claude. Charakterystyka: 3 bazy MariaDB, **produkcja bez internetu
|
||||
> (air-gap, LAN)**.
|
||||
|
||||
> **Wersja frameworka: Laravel 12** (nie 11). Laravel 11 jest EOL - Composer
|
||||
> odmawia instalacji każdego wydania 11.31+ z powodu niezałatanych advisory
|
||||
> bezpieczeństwa, a nowszych 11.x już nie ma. **UAT/produkcję trzeba podnieść
|
||||
> do 12.** Kod nakładki nie wymagał żadnych zmian przy tym przejściu.
|
||||
|
||||
> **Tailwind v4**, konfigurowany w CSS (`@theme` w `resources/css/app.css`).
|
||||
> Pliku `tailwind.config.js` **nie ma i nie powinno być** - starsze fragmenty
|
||||
> tego README, które go wymieniają, są nieaktualne.
|
||||
|
||||
### Środowiska
|
||||
|
||||
| Środowisko | OS | Ścieżka | Internet |
|
||||
|---|---|---|---|
|
||||
| **UAT / testowe** | Debian | `/var/www/html/softspm_pge` | jest (build assetów tutaj) |
|
||||
| **Produkcja** | Windows Server | (web root → `public/`) | **BRAK (air-gap, LAN)** |
|
||||
|
||||
> **Debian = case-sensitive!** Nazwy plików/ścieżek (komponenty Blade, fonty,
|
||||
> obrazki) muszą zgadzać się co do wielkości liter. Trzymamy wszystko lowercase.
|
||||
|
||||
## Środowisko lokalne (Docker)
|
||||
|
||||
Stacja robocza ma tylko PHP 5.6 i 7.4 (XAMPP), a Laravel 12 wymaga PHP ≥ 8.2 -
|
||||
dlatego dev stoi w kontenerze. **Baza NIE jest kontenerem**: łączymy się do
|
||||
istniejącej MariaDB `10.42.1.210` (podejście database-first).
|
||||
|
||||
Kontener: `docker/Dockerfile` (PHP 8.3 + Apache + Node 20, rozszerzenia
|
||||
`pdo_mysql mysqli soap zip gd intl opcache`; `soap` jest wymagany przez
|
||||
`SyndisService`). DocumentRoot → `public/`.
|
||||
|
||||
```bash
|
||||
docker compose up -d app # aplikacja na http://localhost:8000
|
||||
docker compose exec app php artisan ... # artisan
|
||||
docker compose exec app composer ... # composer
|
||||
docker compose exec app npm run build # produkcyjny build assetów
|
||||
docker compose --profile dev up vite # opcjonalny hot-reload (port 5173)
|
||||
```
|
||||
|
||||
Pierwsze uruchomienie na czystej maszynie:
|
||||
|
||||
```bash
|
||||
cp .env.example .env # uzupełnić DB_PASSWORD
|
||||
docker compose build app
|
||||
docker compose up -d app
|
||||
docker compose exec app composer install
|
||||
docker compose exec app npm install
|
||||
docker compose exec app npm run build
|
||||
docker compose exec app php artisan key:generate
|
||||
docker compose exec app chmod -R 777 storage bootstrap/cache
|
||||
docker compose exec app php docker/check/db-check.php # smoke-test 3 połączeń
|
||||
```
|
||||
|
||||
`php artisan migrate` **nie jest uruchamiane** - sesje i cache lecą na pliki,
|
||||
schematu legacy nie dotykamy.
|
||||
|
||||
### Zasoby binarne (air-gap)
|
||||
|
||||
Nie da się ich pobrać na produkcji, więc leżą w repo (`.gitignore` ma na nie wyjątki):
|
||||
|
||||
| Plik | Skąd |
|
||||
|---|---|
|
||||
| `public/images/logo.png`, `dashboard_01.png`, `dashboard_02.png` | makiety `newPGE/uj_dashboard/` (jedyna rzecz, po jaką sięgamy do `newPGE` - kodu legacy szukamy w `trzeciCloude_v1`) |
|
||||
| `public/fonts/inter/Inter-Variable.woff2` | fontsource (Inter VF, latin) |
|
||||
| `public/fonts/jetbrains-mono/JetBrainsMono-Variable.woff2` | fontsource (JetBrains Mono VF, latin) |
|
||||
| `public/fonts/material-symbols/MaterialSymbolsOutlined.woff2` | fontsource (Material Symbols Outlined VF) |
|
||||
|
||||
Vite przy buildzie ostrzega, że `/fonts/...` nie rozwiązuje się w czasie budowania -
|
||||
to jest **oczekiwane**: ścieżki są absolutne i obsługuje je serwer z `public/`.
|
||||
|
||||
## Jak nałożyć na `softspm_pge` (UAT, Debian)
|
||||
|
||||
1. Skopiować pliki nakładki (lista: `docker/overlay-files.txt`) do
|
||||
`/var/www/html/softspm_pge/`, nadpisując m.in. `config/database.php`,
|
||||
`config/navigation.php`, `config/softspm.php`, `routes/web.php`,
|
||||
`resources/`, `package.json`, `vite.config.js`. `vendor/` i `node_modules/`
|
||||
zostają; z `public/` kopiujemy tylko `images/` i `fonts/`.
|
||||
2. Uprawnienia (Debian): `chown -R www-data:www-data storage bootstrap/cache`.
|
||||
3. Front-end (Tailwind v4 przez `@tailwindcss/vite`, konfiguracja w
|
||||
`resources/css/app.css`; NIE ma `tailwind.config.js` ani `postcss.config.js`):
|
||||
```
|
||||
npm install
|
||||
npm run build # produkcyjny build do public/build
|
||||
```
|
||||
4. `.env` (sekcja niżej) + `php artisan config:cache`. **NIE** uruchamiać
|
||||
`php artisan migrate` - sesje/cache trzymamy na plikach (patrz `.env`), więc
|
||||
nie tworzymy żadnych tabel; legacy schematu nie dotykamy.
|
||||
|
||||
## Zmienne `.env`
|
||||
|
||||
```dotenv
|
||||
APP_NAME=SoftSPM
|
||||
APP_LOCALE=pl
|
||||
|
||||
# Database-first + brak potrzeby tabel pomocniczych → sesje/cache na plikach.
|
||||
# Dzięki temu NIE uruchamiamy migracji i nie dorzucamy tabel do baz legacy.
|
||||
SESSION_DRIVER=file
|
||||
CACHE_STORE=file
|
||||
QUEUE_CONNECTION=sync
|
||||
|
||||
DB_CONNECTION=softspm
|
||||
|
||||
# Baza operacyjna (domyślna)
|
||||
DB_HOST=10.42.1.210
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=softspm
|
||||
DB_USERNAME=przemek
|
||||
DB_PASSWORD=visia2209
|
||||
|
||||
# Bazy raportowa i historyczna (ten sam host/user, inna nazwa bazy)
|
||||
DB_REP_DATABASE=softspm_rep
|
||||
DB_HIS_DATABASE=softspm_his
|
||||
|
||||
# Migracja haseł MD5->bcrypt - włączyć DOPIERO po rozszerzeniu
|
||||
# kolumny sys_users.USR_PASSWORD do VARCHAR(255).
|
||||
SOFTSPM_REHASH=false
|
||||
```
|
||||
|
||||
## Air-gap (produkcja bez internetu) - zasady
|
||||
|
||||
- **Zero CDN w runtime.** Tailwind kompilujemy lokalnie (Vite). W makietach
|
||||
(`uj_dashboard/`) Tailwind/fonty szły z CDN - to tylko podgląd.
|
||||
- **Fonty self-hosted.** Pobrać i umieścić w `public/fonts/` (na maszynie z
|
||||
netem), zgodnie z `@font-face` w `resources/css/app.css`:
|
||||
- `public/fonts/inter/Inter-Variable.woff2`
|
||||
- `public/fonts/jetbrains-mono/JetBrainsMono-Variable.woff2`
|
||||
- `public/fonts/material-symbols/MaterialSymbolsOutlined.woff2`
|
||||
- **Tło logowania:** `public/images/login-bg.jpg` (zamiast obrazka z Google
|
||||
w makiecie - można użyć `trzeciCloude_v1/images/tlo.jpg`).
|
||||
- **Build na UAT (Debian, ma internet), wdrożenie na Windows (air-gap):**
|
||||
assety i zależności budujemy na UAT (`npm run build`, `composer install`),
|
||||
a na produkcję Windows kopiujemy **gotowy artefakt** - pełny `vendor/` +
|
||||
skompilowane `public/build/` + self-hostowane fonty/obrazki. Na produkcji
|
||||
**bez** `composer install` / `npm install` (brak internetu i często Node).
|
||||
- **Web root produkcji (Windows):** serwer (IIS/Apache) musi wskazywać podkatalog
|
||||
`public/`, nie korzeń projektu.
|
||||
|
||||
## Co już jest (pierwszy pionowy slice)
|
||||
|
||||
| Plik | Rola |
|
||||
|---|---|
|
||||
| `config/database.php` | 3 połączenia MariaDB (database-first, bez zmiany schematu) |
|
||||
| `config/softspm.php` | flaga migracji haseł MD5→bcrypt |
|
||||
| `resources/css/app.css` | tokeny „Industrial Precision" (Tailwind v4, `@theme`) + fonty self-hosted |
|
||||
| `resources/views/components/guest-layout.blade.php` | layout logowania |
|
||||
| `resources/views/components/app-layout.blade.php` | layout aplikacji (topbar + sidebar) |
|
||||
| `resources/views/auth/login.blade.php` | ekran logowania (wg makiety) |
|
||||
| `resources/views/dashboard.blade.php` | pulpit (placeholder mapy) |
|
||||
| `app/Models/User.php` | model na `sys_users` |
|
||||
| `app/Http/Controllers/Auth/LoginController.php` | logowanie MD5/bcrypt + wybór oddziału |
|
||||
| `app/Http/Controllers/WellController.php` | Studnie: lista (site401) + dodawanie/edycja (site301A/E/inf) |
|
||||
| `app/Services/WellService.php` | transakcyjny zapis studni (lookupy + create + update) |
|
||||
| `resources/views/wells/index.blade.php` | lista studni (wg makiety "Well Inventory") |
|
||||
| `resources/views/wells/create.blade.php`, `edit.blade.php` | formularze dodania/edycji |
|
||||
| `resources/views/components/well-field.blade.php`, `well-select.blade.php` | pola formularza |
|
||||
| `routes/web.php` | trasy: login / logout / dashboard / wells (CRUD) |
|
||||
|
||||
## Weryfikacja parytetu: Studnie (site401 → /wells)
|
||||
|
||||
Nowa lista zastępuje **N+1** z legacy (podzapytania pompa/silnik/ON-OFF na każdy
|
||||
wiersz) **jednym** zapytaniem z JOIN-ami. Przed zatwierdzeniem sprawdzić na
|
||||
serwerze testowym, że zwraca ten sam zestaw studni co legacy, dla tego samego
|
||||
oddziału i statusu. Szybki test liczności (MariaDB, podstaw `<DZIAL>`, `<STATUS>`):
|
||||
|
||||
```sql
|
||||
-- Legacy: bazowa lista (przed N+1) - site401.php, zapytanie $query
|
||||
SELECT COUNT(*) FROM seg_wells
|
||||
LEFT JOIN seg_dev_resources ON DRS_DEV_ID=WLL_ID AND DRS_DEV_TYPE=12
|
||||
LEFT JOIN seg_well_pump_eng_rel ON RWL_WLL_ID=WLL_ID
|
||||
WHERE DRS_DEPARTMENT='<DZIAL>' AND DRS_STATUS_DIC_ID=<STATUS>;
|
||||
```
|
||||
|
||||
Porównać z `->total()` na `/wells?status=<STATUS>` (ten sam oddział z sesji).
|
||||
Dodatkowo wyrywkowo sprawdzić kilka studni: nazwa pompy/silnika, nr seryjny i
|
||||
ostatni stan ON/OFF (DRD_RESOURCES_DETAIL=507, najnowszy DRD_ID) muszą się zgadzać.
|
||||
|
||||
### Świadome odstępstwa od legacy (do akceptacji)
|
||||
- **Paginacja serwerowa** (`paginate(20)`) zamiast cache w sesji + limit 100.
|
||||
Usuwa to limit 100 i checkbox „Pokaż wszystkie" (zbędny przy realnej paginacji).
|
||||
- **Filtry przez GET** (zamiast POST+sesja) - czyste linki, komponują się z paginacją.
|
||||
- **Stan ON/OFF jako chip** (ON/OFF) zamiast ikon power_on/off.png.
|
||||
|
||||
## Dodawanie / edycja studni (site301A/E/inf → /wells/create, /wells/{drs}/edit)
|
||||
|
||||
Zapis jest **wielotabelowy**. Dodanie studni wstawia do: `seg_wells`,
|
||||
`seg_dev_resources` (typ 12), `seg_dev_resources_det` ×3 (średnica `DST`,
|
||||
głębokość `LS`, zasilanie `LZ`), `seg_object_hole_cards`,
|
||||
`seg_object_hole_cards_his`, `seg_dev_resources_his`. Edycja aktualizuje
|
||||
`seg_wells`, `seg_dev_resources`, `seg_object_hole_cards` oraz (gdy istnieje)
|
||||
datę zabudowy w `seg_wells_exchanged`. Cała logika w `WellService`.
|
||||
|
||||
### Ulepszenia względem legacy
|
||||
- **Transakcja** (`DB::transaction`) - legacy robił te INSERT-y bez transakcji
|
||||
(ryzyko danych częściowych przy błędzie). Teraz zapis jest atomowy.
|
||||
- **Walidacja** wejścia + kontrola unikalności nazwy.
|
||||
|
||||
### Świadome odstępstwa / pominięcia (do akceptacji)
|
||||
- **NIE przebudowujemy `rep_object_departments`** po każdym dodaniu (legacy robił
|
||||
`truncate`+`insert` całej tabeli przez ajax `refresh_departments`). To wąskie
|
||||
gardło wydajności; nowa lista `/wells` go nie używa. Do rewizji przy migracji
|
||||
raportów, jeśli inne ekrany na nim polegają.
|
||||
- **Słowniki w języku PL** (`DIC_POL_LANG`) - pełne i18n PL/EN/DE w osobnym etapie.
|
||||
- **`build_time`** jako jedno pole `time` (HH:MM) zamiast dwóch selectów godz./min.
|
||||
|
||||
### Weryfikacja (na serwerze testowym)
|
||||
Dodać testową studnię w wybranym oddziale → sprawdzić, że pojawia się na `/wells`
|
||||
(status 3, ten oddział) oraz że powstały spójne wpisy w 6 tabelach. Edytować →
|
||||
sprawdzić aktualizację `seg_wells`/`seg_dev_resources`/`seg_object_hole_cards`.
|
||||
|
||||
## Otwarte do ustalenia
|
||||
|
||||
- **Hasła MD5 → bcrypt** - `USR_PASSWORD` to `varchar(64)`, więc bcrypt się mieści
|
||||
(rehash bezpieczny bez zmiany schematu). Czeka na zgodę klienta (`SOFTSPM_REHASH=true`).
|
||||
- **Mapa offline** - strategia kafelków bez internetu (lokalny tile-server /
|
||||
kafelki statyczne / własny podkład kopalni).
|
||||
- **`rep_object_departments`** - czy odtworzyć przebudowę po zapisie studni
|
||||
(na razie pominięta - patrz wyżej).
|
||||
Reference in New Issue
Block a user