# Norda Biznes Hub - 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:** 80 członków Norda Biznes (100% pokrycia)

## 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
│   ├── ai_quality_evaluator.py
│   ├── ai_quality_test_cases.json
│   └── results/           # Wyniki testów (JSON)
├── scripts/               # Narzędzia Node.js
└── docs/                  # Dokumentacja
    ├── architecture/      # Architektura systemu (diagramy, przepływy)
    └── INCIDENT_REPORT_20260102.md
```

## Dokumentacja architektury

Kompletna dokumentacja architektury systemu dostępna w katalogu `docs/architecture/`.

### 📚 Dokumenty główne

| Dokument | Opis |
|----------|------|
| [**README.md**](docs/architecture/README.md) | Przegląd całej dokumentacji architektury (start tutaj!) |
| [01-system-context.md](docs/architecture/01-system-context.md) | Kontekst systemu (C4 Level 1) - aktorzy i systemy zewnętrzne |
| [02-container-diagram.md](docs/architecture/02-container-diagram.md) | Diagram kontenerów (C4 Level 2) - Flask, PostgreSQL, NPM, API |
| [03-deployment-architecture.md](docs/architecture/03-deployment-architecture.md) | Architektura wdrożenia - serwery, porty, infrastruktura |
| [04-flask-components.md](docs/architecture/04-flask-components.md) | Komponenty Flask - routes, services, models |
| [05-database-schema.md](docs/architecture/05-database-schema.md) | Schemat bazy danych - 36 tabel, relacje, indeksy |
| [06-external-integrations.md](docs/architecture/06-external-integrations.md) | Integracje API - Gemini, Brave, PageSpeed, Places, KRS, MS Graph |
| [07-network-topology.md](docs/architecture/07-network-topology.md) | Topologia sieci - Fortigate, NPM, routing, DNS |
| [08-critical-configurations.md](docs/architecture/08-critical-configurations.md) | Konfiguracje krytyczne - NPM proxy, SSL, PostgreSQL, systemd |
| [09-security-architecture.md](docs/architecture/09-security-architecture.md) | Architektura bezpieczeństwa - RBAC, CSRF, strefy zaufania |
| [10-api-endpoints.md](docs/architecture/10-api-endpoints.md) | Referencja API - 90+ endpointów, auth, rate limiting |

### 🔄 Przepływy danych (Data Flows)

| Przepływ | Opis |
|----------|------|
| [01-authentication-flow.md](docs/architecture/flows/01-authentication-flow.md) | Rejestracja, login, reset hasła, sesje |
| [02-search-flow.md](docs/architecture/flows/02-search-flow.md) | Wyszukiwanie firm - synonimy, FTS, fuzzy matching |
| [03-ai-chat-flow.md](docs/architecture/flows/03-ai-chat-flow.md) | Chat AI - kontekst, Gemini API, tracking kosztów |
| [04-seo-audit-flow.md](docs/architecture/flows/04-seo-audit-flow.md) | Audyt SEO - PageSpeed API, analiza on-page/technical |
| [05-news-monitoring-flow.md](docs/architecture/flows/05-news-monitoring-flow.md) | Monitoring newsów - Brave API, filtrowanie AI, moderacja |
| [06-http-request-flow.md](docs/architecture/flows/06-http-request-flow.md) | Przepływ HTTP - user → NPM → Flask → PostgreSQL |

### ⚡ Szybki start

**Dla deweloperów:**
- Zacznij od [architecture/README.md](docs/architecture/README.md)
- Przejrzyj [04-flask-components.md](docs/architecture/04-flask-components.md) i [05-database-schema.md](docs/architecture/05-database-schema.md)
- Sprawdź przepływy w [flows/](docs/architecture/flows/) dla zrozumienia logiki biznesowej

**Dla DevOps:**
- [03-deployment-architecture.md](docs/architecture/03-deployment-architecture.md) - infrastruktura
- [07-network-topology.md](docs/architecture/07-network-topology.md) - sieć i routing
- [08-critical-configurations.md](docs/architecture/08-critical-configurations.md) - **KRYTYCZNE!** NPM port 5000

**Dla architektów:**
- [01-system-context.md](docs/architecture/01-system-context.md) - widok wysokopoziomowy
- [02-container-diagram.md](docs/architecture/02-container-diagram.md) - komponenty główne
- [06-external-integrations.md](docs/architecture/06-external-integrations.md) - zależności zewnętrzne

### 🛡️ Kluczowe ostrzeżenia z dokumentacji

**NPM Proxy (KRYTYCZNE!):**
- Port forward **MUSI być 5000**, NIE 80!
- Szczegóły: [08-critical-configurations.md](docs/architecture/08-critical-configurations.md#npm-reverse-proxy)
- Incydent: [INCIDENT_REPORT_20260102.md](docs/INCIDENT_REPORT_20260102.md)

**PostgreSQL:**
- Skrypty używają `localhost (127.0.0.1)`, NIE `10.22.68.249`
- Szczegóły: [08-critical-configurations.md](docs/architecture/08-critical-configurations.md#database-configuration)

**API Limity:**
- Gemini: 1,500 req/dzień (free tier)
- PageSpeed: 25,000 req/dzień
- Brave Search: 2,000 req/miesiąc
- Szczegóły: [06-external-integrations.md](docs/architecture/06-external-integrations.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 2.0 Flash (free tier, 200 req/dzień) |
| 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)

### 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 (r11-git-inpi): `maciejpi` (osobiste), `gitadmin` (admin Gitea)

### Workflow Deployment

```
┌─────────┐   git push    ┌─────────┐   git pull    ┌─────────┐
│   DEV   │ ────────────► │  Gitea  │ ◄──────────── │  PROD   │
│  (Mac)  │               │ (INPI)  │               │         │
└─────────┘               └─────────┘               └─────────┘
     │
     └──── git push ────► GitHub (backup)
```

**Komendy deployment:**
```bash
# 1. DEV: Push do obu repozytoriów
git push origin master && git push inpi master

# 2. PROD: Pull i restart
ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && sudo -u www-data git pull && sudo systemctl restart nordabiznes"
```

### Serwery Git

| Serwer | IP | Port | Usługa |
|--------|-----|------|--------|
| r11-git-inpi | 10.22.68.180 | 3000 (HTTPS) | Gitea |
| GitHub | github.com | 22/443 | GitHub |

**Gitea wymaga HTTPS** (nie HTTP) - URL: `https://10.22.68.180:3000/`

### PROD Git Config

- **Remote:** `https://10.22.68.180:3000/maciejpi/nordabiz.git`
- **User:** www-data
- **SSL verify:** disabled (`git -c http.sslVerify=false`)

## Konwencje danych

### Identyfikatory firm
- **Slug:** kebab-case z nazwy, np. `pixlab-sp-z-o-o`
- **NIP:** 10 cyfr bez myślników, np. `5882436505`
- **REGON:** 9 lub 14 cyfr
- **KRS:** 10 cyfr (tylko spółki)

### Kategorie firm
- `IT` - IT i Technologie
- `Construction` - Budownictwo
- `Services` - Usługi (prawne, księgowe, doradcze)
- `Production` - Produkcja
- `Trade` - Handel
- `Other` - Pozostałe

### Poziomy jakości danych
- `basic` - Nazwa, NIP, kontakt
- `enhanced` - Pełne dane, zweryfikowane
- `complete` - Wzbogacone o usługi, kompetencje, certyfikaty

## Ważne zasady

### Bezpieczeństwo
- NIE edytuj bezpośrednio bazy produkcyjnej PostgreSQL
- Zawsze testuj zmiany na DEV PostgreSQL (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ę

### Import danych
- Używaj skryptów `import_*.py` do dodawania firm
- Weryfikuj NIP przez API przed importem
- Zachowaj spójność slugów (unikalne, lowercase)

### Deployment
- Przed wdrożeniem: `python -m py_compile app.py`
- SSH do NORDABIZ-01: `ssh maciejpi@10.22.68.249` (ZAWSZE jako maciejpi, NIE root!)
- Ścieżka aplikacji: `/var/www/nordabiznes`
- Restart: `sudo systemctl restart nordabiznes`
- **ZAWSZE** aktualizuj historię zmian (`release_notes` w app.py) po wdrożeniu
- Historia zmian: efekt końcowy, bez powtórzeń, prostym językiem

### Szablony Jinja2 - WAŻNE!
- Blok `{% block extra_js %}` w `base.html` jest już wewnątrz tagu `<script>`
- **NIE DODAWAJ** własnych tagów `<script>` w `extra_js` - spowoduje zagnieżdżenie i błąd JS
- Prawidłowo: `{% block extra_js %}function foo() {...}{% endblock %}`
- Błędnie: `{% block extra_js %}<script>function foo() {...}</script>{% endblock %}`

### Uprawnienia PostgreSQL
- Po utworzeniu nowych tabel: `GRANT ALL ON TABLE ... TO nordabiz_app`
- Po utworzeniu sekwencji: `GRANT USAGE, SELECT ON SEQUENCE ... TO nordabiz_app`
- Baza: `nordabiz`, użytkownik aplikacji: `nordabiz_app`

### Testowanie na produkcji
- **ZAWSZE używaj kont testowych** do weryfikacji funkcjonalności
- Używaj przeglądarki (browser automation) do testów wymagających logowania

**Konta testowe (PROD):**

| Konto | Email | Hasło | Rola |
|-------|-------|-------|------|
| Test User | `test@nordabiznes.pl` | `&Rc2LdbSw&jiGR0ek@Bz` | Zwykły użytkownik |
| Test Admin | `testadmin@nordabiznes.pl` | `cSfQbbwegwv1v3Q2Dm0Q` | Administrator |

**Użycie:**
- **Test User** - do testowania funkcji dostępnych dla zwykłych użytkowników
- **Test Admin** - do testowania panelu admina (rekomendacje, składki, kalendarz, forum, news)

## 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
```

## API Endpoints

| Endpoint | Metoda | Opis |
|----------|--------|------|
| `/` | GET | Katalog firm |
| `/company/<slug>` | GET | Profil firmy |
| `/search` | GET | Wyszukiwanie |
| `/api/companies` | GET | Lista firm (JSON) |
| `/api/verify-nip` | GET | Weryfikacja NIP |
| `/health` | GET | Health check |
| `/chat` | GET | Interfejs chatu AI |
| `/admin/news` | GET/POST | Panel moderacji newsów (wymaga admin) |
| `/api/notifications` | GET | Powiadomienia użytkownika (JSON) |

## 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:
- Nazwa firmy: +10 punktów
- Opis: +5 punktów
- Usługi: +8 punktów
- Kompetencje: +7 punktów
- Miasto: +3 punktów

### 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

## Powiązane zasoby

- **Źródło danych:** https://norda-biznes.info/czlonkowie
- **Monitoring:** Zabbix (do konfiguracji)
- **Backup:** Proxmox Backup Server (VM snapshots)
- **DNS wewnętrzny:** nordabiznes.inpi.local

## Kontakty

- **Projekt:** Norda Biznes Hub
- **Infrastruktura:** INPI (skills: proxmox-manager, dns-manager, npm-manager)

## Szablon profilu firmy (company profile)

### Zatwierdzone zmiany do wdrożenia

Sekcje do **połączenia** (redukcja duplikatów):
1. **"O firmie" + "Profil działalności"** → jedna sekcja "O firmie"
2. **"Oferta i usługi" + "Słowa kluczowe"** → jedna sekcja "Usługi i kompetencje"
3. **"Wyróżniki" + "Wartości firmy"** → jedna sekcja "Wyróżniki"
4. **Blok "Jakość Danych"** → usunąć (badge przy nazwie wystarczy)

### Sekcje które MUSZĄ pozostać

- **Social Media (6 kafelków)** - pokazywać WSZYSTKIE platformy, także te bez profilu ("Brak profilu") - ważne by widzieć czego brakuje
- **Dane kontaktowe (sekcja z kartami)** - to docelowe miejsce na WSZYSTKIE dane kontaktowe firmy (adres, telefony, emaile, godziny otwarcia, itp.)

### Docelowa struktura profilu (po optymalizacji)

```
1. Header (nazwa, kategoria, badge weryfikacji, krótki opis)
2. Pasek kontaktowy (www, email, telefon, lokalizacja) - szybki dostęp
3. O firmie (połączone opisy)
4. Usługi i kompetencje (połączone tagi)
5. Wyróżniki (połączone z wartościami)
6. Dane kontaktowe (pełne karty - główne miejsce na kontakt)
7. Informacje prawne i biznesowe (NIP, REGON, KRS, rok założenia)
8. Social Media (wszystkie 6 platform - widoczne braki)
9. Strona WWW (analiza techniczna) - zawsze na końcu
```

### Szablon: templates/company_detail.html

Plik do modyfikacji przy implementacji zmian.

## Plan rozwoju - Aktualności

### Social Media Audit (WDROŻONE)
**Status:** Wdrożone (2026-01-09)
**Panel:** `/admin/social-media`
**Funkcje:**
- Audyt profili Social Media firm (Facebook, Instagram, LinkedIn, YouTube, TikTok, Twitter)
- Weryfikacja aktywności profili (last_checked_at, followers_count)
- Raportowanie brakujących profili

### Priorytet 1: Social Media Integration (Posts/Events)
**Status:** Planowane
**Cel:** Pobieranie postów i wydarzeń z Social Media firm

**Źródła danych:**
- Facebook Pages firm członkowskich (posty, wydarzenia)
- LinkedIn Company Pages
- Google My Business (recenzje, posty)

**Wymagania techniczne:**
- Facebook Graph API (wymaga App Review dla pages_read_engagement)
- LinkedIn Marketing API (wymaga partnera lub OAuth)
- Google Business Profile API

**Typy zdarzeń do importu:**
- `social_post` - posty z social media
- `social_event` - wydarzenia z Facebooka
- `review` - nowe recenzje Google

### Priorytet 2: News Monitoring (Google/Brave API)
**Status:** Wdrożone (2025-12-29)
**Źródła danych:**
- Wzmianki o firmach w mediach lokalnych/branżowych
- Artykuły prasowe
- Komunikaty branżowe

**Wymagania techniczne:**
- Brave Search API (bezpłatny tier) LUB
- Google Custom Search API ($5/1000 queries)
- Cykliczne wyszukiwanie nazw firm

**Typy zdarzeń do importu:**
- `news_mention` - wzmianka w mediach
- `press_release` - komunikat prasowy
- `award` - nagroda/wyróżnienie

### Priorytet 3: Zarząd i Wspólnicy (rejestr.io)
**Status:** Planowane
**Cel:** Wyświetlanie osób powiązanych z firmą bezpośrednio na stronie profilu

**Dane do pobrania z rejestr.io:**
- Zarząd (Prezes, Wiceprezes, Członkowie Zarządu)
- Prokurenci
- Wspólnicy z % udziałów
- Beneficjenci rzeczywiści
- Linki do profili osób (powiązania z innymi firmami)

**Wymagania techniczne:**
- Tabela `company_people` (company_id, name, role, shares_percent, person_url)
- Scraper Playwright (już mamy bazę w `analyze_connections.py`)
- Sekcja w `company_detail.html` po "Informacje prawne i biznesowe"

**Przykład wyświetlania:**
```
👥 ZARZĄD I WSPÓLNICY
┌─────────────────────────────────────────┐
│ 👔 Jan Kowalski - Prezes Zarządu        │
│ 👔 Anna Nowak - Członek Zarządu         │
│ 💼 Firma XYZ Sp. z o.o. - 60% udziałów  │
│ 💼 Jan Kowalski - 40% udziałów          │
└─────────────────────────────────────────┘
```

**Korzyści:**
- Widoczne powiązania między firmami Norda Biznes
- Ułatwiony networking (kto zna kogo)
- Transparentność struktury właścicielskiej

### Notatki implementacyjne
- Scraper powinien deduplikować wydarzenia (hash tytułu + daty)
- Moderacja: nowe wydarzenia jako "pending" do zatwierdzenia przez admina
- Rate limiting: max 100 requestów/dzień do zewnętrznych API

## News Monitoring

### Opis funkcjonalności

System automatycznego monitoringu wzmianek o firmach Norda Biznes w mediach lokalnych i branżowych.

### Tabela w bazie danych

```sql
company_news (
  id SERIAL PRIMARY KEY,
  company_id INTEGER REFERENCES companies(id),
  title VARCHAR(500) NOT NULL,
  description TEXT,
  url VARCHAR(1000) NOT NULL,
  source VARCHAR(200),           -- nazwa portalu/medium
  published_at TIMESTAMP,
  news_type VARCHAR(50),         -- news_mention, press_release, award
  relevance_score FLOAT,         -- 0.0-1.0 (AI scoring)
  status VARCHAR(20) DEFAULT 'pending',  -- pending, approved, rejected
  moderated_by INTEGER,          -- user_id admina
  moderated_at TIMESTAMP,
  rejection_reason TEXT,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),
  UNIQUE(company_id, url)
)
```

**Statusy newsów:**
- `pending` - oczekuje na moderację
- `approved` - zatwierdzony, widoczny na profilu firmy
- `rejected` - odrzucony (spam, nieistotny, duplikat)

### 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"
}
```

**Skrypt pobierania:** (do implementacji)
```bash
# TODO: Skrypt fetch_company_news.py wymaga implementacji
# cd /var/www/nordabiznes
# sudo -u www-data /var/www/nordabiznes/venv/bin/python3 scripts/fetch_company_news.py
```

### 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
}
```

### Skrypty i cron (do implementacji)

```bash
# TODO: Skrypty do pobierania newsów wymagają implementacji
# Planowane komendy:
# python scripts/fetch_company_news.py --all
# python scripts/fetch_company_news.py --company pixlab-sp-z-o-o

# Cron job (do skonfigurowania po implementacji)
# 0 */6 * * * cd /var/www/nordabiznes && /var/www/nordabiznes/venv/bin/python3 scripts/fetch_company_news.py --all >> /var/log/nordabiznes/news_fetch.log 2>&1
```

## Social Media - Stan aktualny

### Statystyki (2025-12-29)

| Platforma | Liczba firm | Pokrycie |
|-----------|-------------|----------|
| Facebook | 39 | 49% |
| Instagram | 26 | 33% |
| LinkedIn | 22 | 28% |
| YouTube | 17 | 21% |
| Twitter/X | 7 | 9% |
| TikTok | 4 | 5% |

**Łącznie:** 115 profili dla 53 firm (66% pokrycia)
**Firmy bez Social Media:** 27

### Tabela w bazie danych

```sql
company_social_media (
  id, company_id, platform, url,
  verified_at, source, is_valid,
  last_checked_at, check_status,
  page_name, followers_count,
  created_at, updated_at
)
```

**Platformy:** facebook, instagram, youtube, linkedin, tiktok, twitter

### 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ę

### Firmy z najlepszym pokryciem Social Media

1. **PORTA KMI** - Facebook, Instagram, YouTube, LinkedIn (4 platformy, 124K FB fans)
2. **Rumia Invest Park** - Facebook, Instagram, YouTube, LinkedIn, Twitter (5 platform)
3. **GRAAL** - Facebook, Instagram, YouTube, LinkedIn (4 platformy)
4. **Chopin Telewizja Kablowa** - Facebook, Instagram, YouTube, Twitter (4 platformy)
5. **Hotel SPA Wieniawa** - Facebook, Instagram, YouTube, TikTok (4 platformy)

### Firmy bez Social Media (do uzupełnienia)

SIM Rumia, Rubinsolar, KORNIX, KBMS, Semerling Security, ARD Invest, AMA,
Jubiler Agat, P&P, Progress Optima, Ampery, Bibrokers, CoolAir, Joker,
KAMMET, Alumech, Litwic&Litwic, Orlex MG, Pro-Invest, Round Two, SCROL,
ALMARES, Pucka Gospodarka Komunalna, Hebel Masiak, Lenap Hale, MKonsult, Portal

## Audyt SEO (Panel /admin/seo)

### Opis funkcjonalności

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)
- **UWAGA:** Nigdy nie commituj kluczy API do repozytorium!

### 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:
DATABASE_URL = 'postgresql://nordabiz_app:NordaBiz2025Secure@127.0.0.1:5432/nordabiz'

# BŁĘDNIE (PostgreSQL nie akceptuje zewnętrznych połączeń):
DATABASE_URL = 'postgresql://nordabiz_app:NordaBiz2025Secure@10.22.68.249: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)

### Tabela w bazie danych

```sql
seo_metrics (
  id SERIAL PRIMARY KEY,
  company_id INTEGER REFERENCES companies(id),
  url VARCHAR(500),
  seo_score INTEGER,
  performance_score INTEGER,
  accessibility_score INTEGER,
  best_practices_score INTEGER,
  pwa_score INTEGER,
  audit_data JSONB,           -- pełne dane z PageSpeed
  audited_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
)
```

### 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`

## Planowane funkcjonalności (Backlog)

### Priorytet 4: System rekomendacji i zdjęć
**Status:** Planowane
**Cel:** Umożliwienie firmom członkowskim wzajemnego polecania się oraz prezentacji zdjęć

**Funkcje:**
- Rekomendacje między firmami (kto poleca kogo)
- Galeria zdjęć firmy (realizacje, zespół, biuro)
- Wyświetlanie na profilu firmy

### Priorytet 5: Status członkostwa i płatności
**Status:** Planowane
**Cel:** Śledzenie statusu członkostwa i składek miesięcznych

**Funkcje:**
- Status członka (aktywny, zawieszony, były członek)
- Informacja o opłaconych składkach
- Historia płatności
- Przypomnienia o zaległościach (dla admina)

**Tabela `membership_fees`:**
```sql
membership_fees (
  id SERIAL PRIMARY KEY,
  company_id INTEGER REFERENCES companies(id),
  period_start DATE NOT NULL,        -- początek okresu (np. 2026-01-01)
  period_end DATE NOT NULL,          -- koniec okresu (np. 2026-01-31)
  amount DECIMAL(10,2) NOT NULL,     -- kwota składki
  status VARCHAR(20) DEFAULT 'pending',  -- pending, paid, overdue
  paid_at TIMESTAMP,
  payment_method VARCHAR(50),        -- przelew, gotówka
  notes TEXT,
  created_at TIMESTAMP DEFAULT NOW()
)
```

## Forma prawna Norda Biznes

### Stan obecny
- **Forma:** OPP (Organizacja Pożytku Publicznego)
- **Typ:** Stowarzyszenie non-profit

### Planowana transformacja
- **Docelowa forma:** Działalność gospodarcza (przy Izbie)
- **Cel:** Możliwość pozyskiwania dofinansowań (granty, projekty UE)
- **Korzyści:**
  - Dostęp do funduszy na rozwój platformy
  - Możliwość świadczenia płatnych usług
  - Elastyczność finansowa
