# Norda Biznes Partner - Instrukcje dla Claude ## Opis projektu Platforma katalogowa i networkingowa dla członków stowarzyszenia Norda Biznes z Wejherowa. - **Produkcja:** https://nordabiznes.pl - **Status:** LIVE (od 2025-11-23) - **Firmy:** 150 podmiotów gospodarczych (cel) ## Struktura projektu ``` nordabiz/ ├── app.py # Główna aplikacja Flask (routes, auth, API) ├── database.py # Modele SQLAlchemy (Company, User, Chat) ├── gemini_service.py # Integracja Google Gemini AI ├── nordabiz_chat.py # Silnik chatu AI z kontekstem firm ├── search_service.py # Unified SearchService (synonimy, FTS, fuzzy) ├── templates/ # Szablony Jinja2 ├── static/ # CSS, JS, obrazy ├── database/ # Schematy SQL, migracje ├── data/ # Dane źródłowe JSON ├── tests/ # Testy jakości AI ├── scripts/ # Narzędzia Python/Node.js └── docs/ # Dokumentacja ├── architecture/ # Architektura systemu (C4, flows) ├── DEVELOPMENT.md # Szczegóły deweloperskie ├── ROADMAP.md # Plan rozwoju, monetyzacja ├── CREDENTIALS.md # Zasady zarządzania credentials └── INCIDENT_REPORT_*.md ``` ## Dokumentacja | Dokument | Zawartość | |----------|-----------| | `docs/architecture/` | Architektura C4, schematy bazy, API, flows | | `docs/DEVELOPMENT.md` | SearchService, Chatbot, Testy AI, SEO, News | | `docs/ROADMAP.md` | Plan rozwoju, priorytety, monetyzacja | | `docs/CREDENTIALS.md` | Zarządzanie hasłami i kluczami API | **⚠️ WAŻNE:** Przed zmianami w NPM/proxy przeczytaj `docs/architecture/08-critical-configurations.md` ## Technologie | Warstwa | Technologia | |---------|-------------| | Backend | Flask 3.0, SQLAlchemy 2.0, Python 3.9+ | | Frontend | HTML5, CSS3, Vanilla JS, Jinja2 | | Baza danych | PostgreSQL (prod i dev via Docker) | | AI | Google Gemini 3 Flash (free tier) | | Security | Flask-Login, Flask-WTF (CSRF), Flask-Limiter | ## Środowiska ### Development (lokalne) - **Baza:** PostgreSQL via Docker (`localhost:5433/nordabiz`) - **Port:** 5000 lub 5001 - **Uruchomienie:** `python3 app.py` - **Docker DB:** `docker compose up -d` (jeśli nie działa) ### Staging (NOWE - 2026-02-02) - **Serwer:** NORDABIZ-STAGING-01 (VM 248, IP 10.22.68.248) - **Baza:** PostgreSQL `nordabiz_staging` na 10.22.68.248:5432 - **Domena:** staging.nordabiznes.pl - **NPM Proxy Host ID:** 44 - **SSL:** Let's Encrypt (ważny do 2026-05-03) **Cel:** Testowanie zmian przed wdrożeniem na produkcję (E2E, integration tests) **Weryfikacja:** ```bash curl -I https://staging.nordabiznes.pl/health ssh maciejpi@10.22.68.248 ``` ### Production - **Serwer:** NORDABIZ-01 (VM 249, IP 10.22.68.249) - **Baza:** PostgreSQL na 10.22.68.249:5432 - **Reverse Proxy:** NPM na R11-REVPROXY-01 (VM 119, IP 10.22.68.250) - **Domena:** nordabiznes.pl (DNS w OVH) - **SSL:** Let's Encrypt (auto-renewal) ### NPM Proxy Configuration (KRYTYCZNE!) **Proxy Host ID:** 27 **Forward Port:** 5000 (NIE 80!) ``` PRAWIDŁOWA KONFIGURACJA: NPM (10.22.68.250) → Backend (10.22.68.249:5000) ✓ BŁĘDNA KONFIGURACJA (powoduje pętlę przekierowań): NPM (10.22.68.250) → Backend (10.22.68.249:80) ✗ ``` **UWAGA:** Na serwerze 10.22.68.249 działa nginx na porcie 80 który przekierowuje na HTTPS. Flask/Gunicorn działa na porcie 5000. Przy edycji proxy hosta ZAWSZE sprawdź czy port = 5000! **Weryfikacja po zmianach NPM:** ```bash curl -I https://nordabiznes.pl/health # Oczekiwany: HTTP 200 ``` **Raport incydentu:** `docs/INCIDENT_REPORT_20260102.md` ## Git & Deployment ### Repozytoria Git | Remote | URL | Cel | |--------|-----|-----| | **origin** (GitHub) | `git@github.com:pienczyn/nordabiz.git` | Cloud backup, CI/CD ready | | **inpi** (Gitea) | `git@10.22.68.180:maciejpi/nordabiz.git` | Wewnętrzny backup, deploy source | **Konta:** GitHub: `pienczyn`, Gitea: `maciejpi` ### Workflow Deployment ``` ┌─────────┐ git push ┌─────────┐ git pull ┌─────────┐ │ DEV │ ────────────► │ Gitea │ ◄──────────── │ PROD │ │ (Mac) │ │ (INPI) │ │ │ └─────────┘ └─────────┘ └─────────┘ │ └──── git push ────► GitHub (backup) ``` ### Procedura wdrażania (WAŻNE!) ```bash # 1. DEV: Push do obu repozytoriów git push origin master && git push inpi master # 2. PROD: Pull zmiany ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && sudo -u www-data git pull" # 3. PROD: Uruchom migracje SQL (jeśli są) ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && /var/www/nordabiznes/venv/bin/python3 scripts/run_migration.py database/migrations/XXX_nazwa.sql" # 4. PROD: Restart serwisu ssh maciejpi@10.22.68.249 "sudo systemctl restart nordabiznes" # 5. Weryfikacja curl -sI https://nordabiznes.pl/health | head -3 ``` **⚠️ UWAGI KRYTYCZNE:** 1. **Migracje SQL** - NIE używaj `psql` bezpośrednio. Użyj `scripts/run_migration.py` 2. **Uprawnienia logów** - Jeśli błąd `Permission denied: /var/log/nordabiznes/*`: ```bash ssh maciejpi@10.22.68.249 "sudo chown -R maciejpi:maciejpi /var/log/nordabiznes/" ``` 3. **502 po restarcie** - Poczekaj 3-5 sekund i sprawdź ponownie 4. **Git pull** - Używaj `sudo -u www-data git pull` (www-data ma klucze SSH) **Uruchamianie skryptów na produkcji (KRYTYCZNE!):** - SSH timeout NIE oznacza że komenda nie została wykonana! - ZAWSZE sprawdź czy poprzedni proces nie działa: `ps aux | grep ` - Dla długich operacji używaj `nohup` lub `screen` - Incydent: `docs/INCIDENT_REPORT_20260115.md` **Uruchamianie skryptów Python z dostępem do bazy (WAŻNE!):** Skrypty Python wymagające dostępu do bazy danych MUSZĄ mieć ustawiony `DATABASE_URL`. Plik `.env` NIE jest automatycznie wczytywany przez `source .env` - to nie działa w kontekście SSH! ```bash # ✅ PRAWIDŁOWO - ustaw DATABASE_URL bezpośrednio: ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && \ DATABASE_URL='postgresql://nordabiz_app:HASŁO@127.0.0.1:5432/nordabiz' \ /var/www/nordabiznes/venv/bin/python3 skrypt.py" # ✅ PRAWIDŁOWO - pobierz DATABASE_URL z .env: ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && \ DATABASE_URL=\$(grep DATABASE_URL .env | cut -d'=' -f2) \ /var/www/nordabiznes/venv/bin/python3 skrypt.py" # ❌ BŁĘDNIE - source .env nie działa przez SSH: ssh maciejpi@10.22.68.249 "source .env && python3 skrypt.py" ``` **Hasło do bazy (produkcja):** W pliku `/var/www/nordabiznes/.env` (DATABASE_URL) ## Auto Claude - Rozwiązywanie problemów ### Pliki stanu (NIE COMMITOWAĆ!) - `.auto-claude-security.json`, `.auto-claude-status`, `.auto-claude/` - Są w `.gitignore` + pre-commit hook automatycznie je usuwa ze staging ### Konflikty merge z Auto Claude ```bash # 1. Sprawdź konflikt git status # 2. Usuń pliki Auto Claude z merge git rm .auto-claude-security.json .auto-claude-status # 3. Dokończ merge git commit -m "Merge branch 'feature' - resolve Auto Claude file conflicts" ``` ### Worktrees ```bash git worktree list # Lista aktywnych git worktree remove .auto-claude/worktrees/tasks/ # Usuń nieaktualny git branch -d auto-claude/ # Usuń branch ``` ## Konwencje danych ### Identyfikatory firm - **Slug:** kebab-case, np. `pixlab-sp-z-o-o` - **NIP:** 10 cyfr bez myślników - **REGON:** 9 lub 14 cyfr - **KRS:** 10 cyfr (tylko spółki) ### Kategorie firm `IT`, `Construction`, `Services`, `Production`, `Trade`, `Other` ### Poziomy jakości danych `basic`, `enhanced`, `complete` ## Ważne zasady ### Bezpieczeństwo - NIE edytuj bezpośrednio bazy produkcyjnej PostgreSQL - Testuj zmiany na DEV (Docker: localhost:5433) przed wdrożeniem - Klucze API i hasła tylko w `.env` (nigdy w kodzie) - Rate limiting: 200 req/dzień, 50 req/godzinę **Panel bezpieczeństwa:** `/admin/security` - 2FA, CSRF, HTTPS, GeoIP Blocking, Rate Limiting, Account Lockout, Audit Log ### Zarządzanie credentials (KRYTYCZNE!) **NIGDY nie umieszczaj haseł w kodzie źródłowym!** ```python # ✅ PRAWIDŁOWO: DATABASE_URL = os.getenv('DATABASE_URL') # ❌ BŁĘDNIE: DATABASE_URL = 'postgresql://user:password123@localhost/db' ``` - Wszystkie sekrety w `.env` (nigdy w `.py`, `.sh`, `.js`) - Fallback jako placeholder: `CHANGE_ME` (nie prawdziwe hasło!) **Pełne zasady:** `docs/CREDENTIALS.md` ### Deployment - Przed wdrożeniem: `python -m py_compile app.py` - SSH do NORDABIZ-01: `ssh maciejpi@10.22.68.249` (ZAWSZE jako maciejpi!) - Ścieżka aplikacji: `/var/www/nordabiznes` - Restart: `sudo systemctl restart nordabiznes` - **ZAWSZE** aktualizuj historię zmian (`release_notes` w app.py) ### Szablony Jinja2 - WAŻNE! - Blok `{% block extra_js %}` w `base.html` jest już wewnątrz `