docs: Reorganizacja dokumentacji - wydzielenie DEVELOPMENT, ROADMAP, CREDENTIALS
- CLAUDE.md uproszczony - tylko kluczowe info dla Claude - docs/DEVELOPMENT.md - szczegóły SearchService, Chatbot, Testy AI, SEO, News - docs/ROADMAP.md - plan rozwoju, priorytety, strategia monetyzacji 3-tier - docs/CREDENTIALS.md - zasady zarządzania hasłami i kluczami API Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9e82c00ca4
commit
587d000b9b
168
docs/CREDENTIALS.md
Normal file
168
docs/CREDENTIALS.md
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# NordaBiz - Zarządzanie danymi uwierzytelniającymi
|
||||||
|
|
||||||
|
Ten dokument zawiera szczegółowe zasady zarządzania hasłami, kluczami API i innymi wrażliwymi danymi.
|
||||||
|
Główne instrukcje znajdują się w [CLAUDE.md](../CLAUDE.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## KRYTYCZNE: Nigdy nie umieszczaj haseł w kodzie!
|
||||||
|
|
||||||
|
**NIGDY nie umieszczaj haseł i kluczy API bezpośrednio w kodzie źródłowym!**
|
||||||
|
|
||||||
|
Jest to krytyczna podatność bezpieczeństwa (CWE-798: Use of Hard-coded Credentials). Narusza standardy bezpieczeństwa i może prowadzić do kompromitacji systemu jeśli repozytorium zostanie ujawnione.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Zasady obowiązkowe
|
||||||
|
|
||||||
|
### 1. Używaj zmiennych środowiskowych
|
||||||
|
|
||||||
|
```python
|
||||||
|
# ✅ PRAWIDŁOWO:
|
||||||
|
DATABASE_URL = os.getenv('DATABASE_URL')
|
||||||
|
API_KEY = os.getenv('GOOGLE_PAGESPEED_API_KEY')
|
||||||
|
|
||||||
|
# ❌ BŁĘDNIE - NIGDY TAK NIE RÓB:
|
||||||
|
DATABASE_URL = 'postgresql://user:password123@localhost/db'
|
||||||
|
API_KEY = 'AIzaSyAbc123...'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Wartości domyślne jako bezpieczne placeholdery
|
||||||
|
|
||||||
|
```python
|
||||||
|
# ✅ PRAWIDŁOWO - wartość domyślna która wymusi konfigurację .env:
|
||||||
|
DATABASE_URL = os.getenv('DATABASE_URL', 'postgresql://user:CHANGE_ME@localhost/nordabiz')
|
||||||
|
|
||||||
|
# ❌ BŁĘDNIE - wartość produkcyjna jako fallback:
|
||||||
|
DATABASE_URL = os.getenv('DATABASE_URL', 'postgresql://user:RealPassword@10.22.68.249/nordabiz')
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Przechowuj credentials w plikach .env
|
||||||
|
|
||||||
|
| Środowisko | Lokalizacja |
|
||||||
|
|------------|-------------|
|
||||||
|
| Produkcja | `/var/www/nordabiznes/.env` |
|
||||||
|
| Development | `.env` w katalogu projektu |
|
||||||
|
| Wzorzec | `.env.example` (bez prawdziwych wartości!) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wymagane zmienne środowiskowe
|
||||||
|
|
||||||
|
| Zmienna | Cel | Przykład |
|
||||||
|
|---------|-----|----------|
|
||||||
|
| `DATABASE_URL` | Połączenie PostgreSQL dla skryptów Python | `postgresql://user:pass@127.0.0.1:5432/nordabiz` |
|
||||||
|
| `PGPASSWORD` | Hasło PostgreSQL dla skryptów shell | `export PGPASSWORD='your_password'` |
|
||||||
|
| `GOOGLE_PAGESPEED_API_KEY` | API Key Google PageSpeed | `AIzaSy...` |
|
||||||
|
| `BRAVE_SEARCH_API_KEY` | API Key Brave Search | `BSA...` |
|
||||||
|
| `GEMINI_API_KEY` | API Key Google Gemini AI | `AIzaSy...` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Skrypty shell - sprawdzanie zmiennych
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ✅ PRAWIDŁOWO:
|
||||||
|
if [ -z "$PGPASSWORD" ]; then
|
||||||
|
echo "ERROR: PGPASSWORD not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
psql -h localhost -U nordabiz_app -d nordabiz
|
||||||
|
|
||||||
|
# ❌ BŁĘDNIE:
|
||||||
|
PGPASSWORD='hardcoded_password' psql -h localhost -U nordabiz_app -d nordabiz
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## NIGDY nie commituj plików z credentials
|
||||||
|
|
||||||
|
- `.env` jest w `.gitignore`
|
||||||
|
- Sprawdzaj przed commitem: `git diff` i `git status`
|
||||||
|
- W razie wątpliwości: `git log -p | grep -i password`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Co zrobić jeśli przypadkowo scommitujesz hasło
|
||||||
|
|
||||||
|
⚠️ **NATYCHMIAST zmień hasło w bazie/API**
|
||||||
|
|
||||||
|
Powód: Nie wystarczy usunąć z najnowszego commita - hasło pozostaje w historii Git.
|
||||||
|
|
||||||
|
### Opcje naprawy:
|
||||||
|
|
||||||
|
1. **Zmiana hasła** (ZALECANE)
|
||||||
|
- Natychmiast zmień hasło we wszystkich systemach
|
||||||
|
- Traktuj stare hasło jako skompromitowane
|
||||||
|
- Najprostsze i najbezpieczniejsze rozwiązanie
|
||||||
|
|
||||||
|
2. **Przepisanie historii Git** (SKOMPLIKOWANE)
|
||||||
|
- `git filter-branch` lub `BFG Repo-Cleaner`
|
||||||
|
- Wymaga force push do wszystkich remotów
|
||||||
|
- Może powodować problemy dla innych deweloperów
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wyjątki - kiedy dozwolone jest hasło w kodzie
|
||||||
|
|
||||||
|
| Dozwolone | Niedozwolone |
|
||||||
|
|-----------|--------------|
|
||||||
|
| ✅ Pliki dokumentacji (CLAUDE.md, README) | ⛔ Pliki Python (.py) |
|
||||||
|
| ✅ `.env.example` z placeholderami | ⛔ Skrypty shell (.sh) |
|
||||||
|
| | ⛔ Pliki JavaScript (.js) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Weryfikacja przed wdrożeniem
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Sprawdź czy nie ma hardcoded credentials w kodzie:
|
||||||
|
grep -r "PGPASSWORD=" --include="*.sh" .
|
||||||
|
grep -r "postgresql://.*:.*@" --include="*.py" . | grep -v "CHANGE_ME" | grep -v ".example" | grep -v "PASSWORD"
|
||||||
|
|
||||||
|
# Oczekiwany wynik: brak znalezisk (lub tylko w dokumentacji/placeholderach)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bezpieczne przechowywanie
|
||||||
|
|
||||||
|
### Lokalizacje plików .env
|
||||||
|
|
||||||
|
```
|
||||||
|
/var/www/nordabiznes/.env # Produkcja (PROD)
|
||||||
|
./nordabiz/.env # Development (DEV)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Uprawnienia plików
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Tylko właściciel może czytać plik .env
|
||||||
|
chmod 600 /var/www/nordabiznes/.env
|
||||||
|
chown www-data:www-data /var/www/nordabiznes/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfiguracja IDE
|
||||||
|
|
||||||
|
### VS Code - wykluczenie .env z wyszukiwania
|
||||||
|
|
||||||
|
```json
|
||||||
|
// .vscode/settings.json
|
||||||
|
{
|
||||||
|
"search.exclude": {
|
||||||
|
"**/.env": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Git - ignorowanie .env
|
||||||
|
|
||||||
|
```gitignore
|
||||||
|
# .gitignore
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
*.env
|
||||||
|
```
|
||||||
272
docs/DEVELOPMENT.md
Normal file
272
docs/DEVELOPMENT.md
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
# 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>@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)
|
||||||
|
|
||||||
|
### 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
|
||||||
|
```
|
||||||
223
docs/ROADMAP.md
Normal file
223
docs/ROADMAP.md
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
# NordaBiz - Plan rozwoju i monetyzacja
|
||||||
|
|
||||||
|
Ten dokument zawiera plany rozwoju projektu i strategię monetyzacji.
|
||||||
|
Główne instrukcje znajdują się w [CLAUDE.md](../CLAUDE.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Status wdrożonych funkcjonalności
|
||||||
|
|
||||||
|
| Funkcjonalność | Status | Data |
|
||||||
|
|----------------|--------|------|
|
||||||
|
| Social Media Audit | ✅ Wdrożone | 2026-01-09 |
|
||||||
|
| News Monitoring | ✅ Wdrożone | 2025-12-29 |
|
||||||
|
| Katalog firm | ✅ Wdrożone | 2025-11-23 |
|
||||||
|
| Chat AI (NordaGPT) | ✅ Wdrożone | 2025-11-23 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
### Typy zdarzeń
|
||||||
|
- `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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Strategia monetyzacji
|
||||||
|
|
||||||
|
### Model 3-tier Pricing (Kotwiczenie ceny)
|
||||||
|
|
||||||
|
**Strategia:** Trzy poziomy cenowe z zastosowaniem psychologii kotwiczenia ceny (Price Anchoring).
|
||||||
|
Najwyższy poziom służy jako **kotwica** - sprawia że środkowy wydaje się atrakcyjny i jest docelowy.
|
||||||
|
|
||||||
|
| Poziom | Nazwa | Cena/mies. | Cel strategiczny |
|
||||||
|
|--------|-------|------------|------------------|
|
||||||
|
| **1** | Basic | ~49 zł | Entry point, ograniczone funkcje |
|
||||||
|
| **2** | Premium | ~99 zł | **DOCELOWY** - rekomendowany, najlepsza wartość |
|
||||||
|
| **3** | Enterprise | ~199 zł | **KOTWICA** - premium, pełny dostęp |
|
||||||
|
|
||||||
|
**Wyjątek:** Członkowie Izby NORDA płacący składki (~200 zł/mies.) mają specjalny status - dostęp Premium za symboliczne 1 zł.
|
||||||
|
|
||||||
|
### Psychologia 3-tier Pricing
|
||||||
|
|
||||||
|
- Ludzie naturalnie wybierają środkową opcję (efekt kompromisu)
|
||||||
|
- Wysoka cena kotwicy sprawia że środkowa wydaje się "okazją"
|
||||||
|
- Niska cena Basic sprawia że użytkownik czuje "upgrade jest wart dopłaty"
|
||||||
|
- Firmy stosujące 3-tier widzą ~30% wzrost przychodów
|
||||||
|
- Slack: dodanie Enterprise tier zwiększyło konwersję na Professional o 28%
|
||||||
|
|
||||||
|
### Matryca dostępu do funkcji
|
||||||
|
|
||||||
|
| Funkcja | Basic | Premium | Enterprise |
|
||||||
|
|---------|:-----:|:-------:|:----------:|
|
||||||
|
| Katalog firm | ✅ | ✅ | ✅ |
|
||||||
|
| Profil firmy | ✅ | ✅ | ✅ |
|
||||||
|
| Forum | ❌ | ✅ | ✅ |
|
||||||
|
| Kalendarz wydarzeń | ❌ | ✅ | ✅ |
|
||||||
|
| Chat AI (NordaGPT) | ❌ | ✅ | ✅ |
|
||||||
|
| **Raporty podstawowe** | ❌ | ✅ | ✅ |
|
||||||
|
| **Raporty zaawansowane** | ❌ | ❌ | ✅ |
|
||||||
|
| Eksport danych (CSV/PDF) | ❌ | ❌ | ✅ |
|
||||||
|
| API dostęp | ❌ | ❌ | ✅ |
|
||||||
|
| Priorytetowe wsparcie | ❌ | ❌ | ✅ |
|
||||||
|
|
||||||
|
### Implementacja techniczna (przyszłość)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Model User - nowe pola
|
||||||
|
class User(Base):
|
||||||
|
# ...
|
||||||
|
subscription_tier = Column(String(20), default='basic') # basic, premium, enterprise
|
||||||
|
subscription_expires_at = Column(DateTime)
|
||||||
|
is_norda_member = Column(Boolean, default=False) # Członek Izby = specjalny status
|
||||||
|
|
||||||
|
# Dekorator kontroli dostępu
|
||||||
|
def requires_tier(min_tier):
|
||||||
|
def decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapped(*args, **kwargs):
|
||||||
|
tiers = ['basic', 'premium', 'enterprise']
|
||||||
|
user_tier_idx = tiers.index(current_user.subscription_tier)
|
||||||
|
required_idx = tiers.index(min_tier)
|
||||||
|
if user_tier_idx < required_idx:
|
||||||
|
flash(f'Ta funkcja wymaga konta {min_tier.title()}.', 'warning')
|
||||||
|
return redirect(url_for('pricing'))
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return wrapped
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
# Użycie
|
||||||
|
@app.route('/raporty/zaawansowane')
|
||||||
|
@login_required
|
||||||
|
@requires_tier('enterprise')
|
||||||
|
def advanced_reports():
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Raporty - podział według poziomu
|
||||||
|
|
||||||
|
**Raporty podstawowe (Premium+):**
|
||||||
|
- Staż członkostwa w Izbie NORDA
|
||||||
|
- Pokrycie Social Media
|
||||||
|
- Struktura branżowa
|
||||||
|
|
||||||
|
**Raporty zaawansowane (Enterprise only):**
|
||||||
|
- Ranking SEO
|
||||||
|
- Mapa lokalizacji
|
||||||
|
- Sieć rekomendacji
|
||||||
|
- Aktywność w wydarzeniach
|
||||||
Loading…
Reference in New Issue
Block a user