nordabiz/docs/DEVELOPMENT.md
Maciej Pienczyn 110d971dca
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
feat: migrate prod docs to OVH VPS + UTC→Warsaw timezone in all templates
Production moved from on-prem VM 249 (10.22.68.249) to OVH VPS
(57.128.200.27, inpi-vps-waw01). Updated ALL documentation, slash
commands, memory files, architecture docs, and deploy procedures.

Added |local_time Jinja filter (UTC→Europe/Warsaw) and converted
155 .strftime() calls across 71 templates so timestamps display
in Polish timezone regardless of server timezone.

Also includes: created_by_id tracking, abort import fix, ICS
calendar fix for missing end times, Pros Poland data cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:41:53 +02:00

273 lines
7.2 KiB
Markdown

# NordaBiz - Dokumentacja deweloperska
Ten dokument zawiera szczegółowe informacje techniczne dla deweloperów.
Główne instrukcje znajdują się w [CLAUDE.md](../CLAUDE.md).
---
## SearchService (search_service.py)
Unified search dla chatbota AI i wyszukiwarki `/search`.
### Funkcje
- **NIP/REGON lookup** - bezpośrednie wyszukiwanie po identyfikatorach
- **Synonym expansion** - rozszerzenie słów kluczowych (np. "strony" → www, web, portal)
- **PostgreSQL FTS** - full-text search z tsvector (DEV i PROD)
- **SQLite fallback** - keyword scoring (tylko jako fallback, nieużywane)
- **Fuzzy matching** - pg_trgm dla literówek (gdy dostępne)
### Scoring
| Pole | Punkty |
|------|--------|
| Nazwa firmy | +10 |
| Opis | +5 |
| Usługi | +8 |
| Kompetencje | +7 |
| Miasto | +3 |
### Użycie
```python
from search_service import search_companies
results = search_companies(db, "strony www", limit=10)
# Zwraca List[SearchResult] z company, score, match_type
```
### UWAGA (PostgreSQL)
- Gdy FTS się nie powiedzie, wykonywany jest `db.rollback()` przed fallbackiem
- Bez tego następuje błąd `InFailedSqlTransaction`
---
## Chatbot AI (nordabiz_chat.py)
### Konfiguracja
- **Limit firm do AI:** 8 (zmienne w `_build_conversation_context`, linia ~312)
- **Historia wiadomości:** 10 ostatnich
- **Search:** używa `search_companies()` z SearchService
---
## Testy jakości AI
### Uruchomienie
```bash
python run_ai_quality_tests.py -v # Verbose output
python run_ai_quality_tests.py -v -s # Verbose + save report
python run_ai_quality_tests.py -q # Quick (tylko high-priority)
```
### Przypadki testowe (`tests/ai_quality_test_cases.json`)
- 15 przypadków w 8 kategoriach
- Próg zaliczenia: 70%
- Kategorie: IT/Web, Services/Legal, Services/Accounting, Production/Metal, Construction, HVAC, Energy/Renewable, IT/Security
---
## News Monitoring
### Brave Search API Integration
**Konfiguracja:**
- API Key w `.env`: `BRAVE_SEARCH_API_KEY`
- Endpoint: `https://api.search.brave.com/res/v1/news/search`
- Limit: 2000 req/miesiąc (free tier)
**Parametry wyszukiwania:**
```python
params = {
"q": f'"{company_name}" OR "{nip}"',
"count": 10,
"freshness": "pw", # past week
"country": "pl",
"search_lang": "pl"
}
```
### AI Filtering (Gemini)
Filtracja wyników przez Google Gemini:
- Ocena relevance_score (0.0-1.0)
- Kategoryzacja news_type
- Wykrywanie duplikatów/spamu
- Automatyczne odrzucanie wyników < 0.3 relevance
**Prompt systemu:**
```
Oceń czy artykuł dotyczy działalności firmy {company_name}.
Zwróć JSON: {"relevance": 0.0-1.0, "type": "news_mention|press_release|award", "reason": "..."}
```
### Panel admina /admin/news
**URL:** `/admin/news`
**Wymaga:** Zalogowany użytkownik z `is_admin=True`
**Funkcje:**
- Lista newsów pending do moderacji
- Filtrowanie po firmie, statusie, dacie
- Zatwierdzanie/odrzucanie z powodem
- Podgląd oryginalnego artykułu
- Bulk actions (zatwierdź wszystkie z relevance > 0.8)
### Sekcja Aktualności na profilu firmy
**Lokalizacja:** `templates/company_detail.html`
**Warunek:** Tylko newsy ze statusem `approved`
**Sortowanie:** Po `published_at` DESC
**Limit:** 5 ostatnich newsów
**Struktura wyświetlania:**
```
AKTUALNOŚCI
├── [data] Tytuł artykułu (źródło)
│ Krótki opis...
│ [Czytaj więcej →]
└── [data] Kolejny artykuł...
```
### System powiadomień
**Endpoint:** `/api/notifications`
**Zwraca:** JSON z listą powiadomień użytkownika
**Typy powiadomień:**
- `new_news` - nowy news o obserwowanej firmie (dla zalogowanych)
- `news_approved` - news firmy użytkownika został zatwierdzony
- `news_rejected` - news firmy użytkownika został odrzucony
**Struktura odpowiedzi:**
```json
{
"notifications": [
{
"id": 1,
"type": "new_news",
"message": "Nowa wzmianka o PIXLAB",
"url": "/company/pixlab-sp-z-o-o#news",
"created_at": "2025-12-29T10:30:00",
"read": false
}
],
"unread_count": 3
}
```
---
## Audyt SEO (Panel /admin/seo)
### Opis
System audytu SEO stron internetowych firm członkowskich Norda Biznes.
Wykorzystuje Google PageSpeed Insights API do analizy wydajności i jakości stron.
**URL panelu:** `/admin/seo`
**Wymaga:** Zalogowany użytkownik z `is_admin=True`
### Konfiguracja API
**Google PageSpeed Insights API:**
- API Key w `.env`: `GOOGLE_PAGESPEED_API_KEY`
- Projekt Google Cloud: NORDABIZNES (`gen-lang-client-0540794446`)
- Limit: 25,000 zapytań/dzień (free tier)
- Endpoint: `https://www.googleapis.com/pagespeedonline/v5/runPagespeed`
**Klucz API:**
- **Nazwa w Google Cloud:** `Page SPEED SEO Audit v2`
- **Wartość:** Przechowywany w `.env` (GOOGLE_PAGESPEED_API_KEY)
### Metryki audytu
| Metryka | Źródło | Skala |
|---------|--------|-------|
| WYNIK SEO | PageSpeed Insights | 0-100 |
| PERFORMANCE | PageSpeed Insights | 0-100 |
| DOSTĘPNOŚĆ | PageSpeed Insights | 0-100 |
| BEST PRACTICES | PageSpeed Insights | 0-100 |
**Interpretacja wyników:**
- 90-100 (zielony) - Doskonały
- 50-89 (żółty) - Wymaga poprawy
- 0-49 (czerwony) - Słaby
### Skrypty SEO
```bash
# Audyt pojedynczej firmy
cd /var/www/nordabiznes/scripts
python seo_audit.py --company-id 26
# Audyt wsadowy (batch)
python seo_audit.py --batch 1-10
# Audyt wszystkich firm
python seo_audit.py --all
# Tryb testowy (bez zapisu)
python seo_audit.py --company-id 26 --dry-run
```
### WAŻNE - Połączenie z bazą danych
Skrypty w `scripts/` muszą używać **localhost (127.0.0.1)** do połączenia z PostgreSQL:
```python
# PRAWIDŁOWO (hasło z .env):
DATABASE_URL = 'postgresql://nordabiz_app:<PASSWORD_FROM_ENV>@127.0.0.1:5432/nordabiz'
# BŁĘDNIE (PostgreSQL nie akceptuje zewnętrznych połączeń):
DATABASE_URL = 'postgresql://nordabiz_app:<PASSWORD>@57.128.200.27:5432/nordabiz'
```
**Pliki z konfiguracją bazy:**
- `scripts/seo_audit.py` (linia ~79)
- `scripts/seo_report_generator.py` (linia ~47)
- `scripts/social_media_audit.py` (linia ~53)
### UI - Stylizowane modale
Panel SEO używa niestandardowych modali (zamiast natywnych `confirm()`/`alert()`):
- Modal potwierdzenia audytu z ikoną ostrzeżenia
- Modal informacyjny o błędach
- Animacje CSS (fade in/out)
**Lokalizacja kodu:** `templates/admin_seo_dashboard.html`
---
## Social Media
### Skrypty aktualizacji
```bash
# Aktualizacja Social Media z pliku JSON
cd /var/www/nordabiznes
sudo -u www-data /var/www/nordabiznes/venv/bin/python3 update_social_media.py --dry-run # Test
sudo -u www-data /var/www/nordabiznes/venv/bin/python3 update_social_media.py # Produkcja
```
**Pliki:**
- `social_media_found.json` - wyniki wyszukiwania (źródło danych)
- `update_social_media.py` - skrypt aktualizujący bazę
**Platformy:** facebook, instagram, youtube, linkedin, tiktok, twitter
---
## Skrypty danych
### Import (wykonywać kolejno)
```bash
python import_norda_companies.py # Batch 1 (56 firm)
python import_norda_batch2.py # Batch 2
python import_norda_batch3.py # Batch 3
python import_norda_batch4.py # Batch 4 (9 firm)
python import_norda_batch5.py # Batch 5 (8 firm)
```
### Weryfikacja
```bash
python verify_all_companies_data.py # Raport jakości danych
python fix_krs_verification.py # Weryfikacja KRS
```