10 tasks across 4 chunks: backend routes, templates, nav reorganization, and verification/deploy. Includes fixes from spec and plan reviews (field names, endpoint aliases, diacritics). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 KiB
PEJ Section — Dedicated Nuclear Energy Space on nordabiznes.pl
Date: 2026-03-16 Status: Draft Approach: Hybrid — "soczewka" na dane ZOPK + własne treści PEJ
Problem
Izba Norda Biznes aktywnie angażuje się w projekt PEJ (Polskie Elektrownie Jądrowe). Po spotkaniu z dyrektorem PEJ ds. local content (Grzegorz Maj) pojawiła się pilna potrzeba:
- Dostarczenia PEJ listy firm członkowskich z kontaktami i branżami
- Motywowania członków do uzupełnienia profili na portalu
- Śledzenia aktualności i postępów projektu nuklearnego
- Wydzielenia PEJ z ogólnej sekcji ZOPK — PEJ to strategiczny kierunek Izby, nie tylko jeden z projektów Kaszubia
Architecture
Hybrid "Lens" Approach
PEJ section nie tworzy nowych tabel — konsumuje istniejące dane ZOPK, filtrując po projektach nuklearnych. Dodaje jedynie:
- Nowe routes i templates pod
/pej - Routes w istniejących blueprintach
publiciadmin(spójnie z wzorcem ZOPK) - Kategorię
pejw systemie ogłoszeń - Endpoint eksportu CSV firm dla PEJ
┌─────────────────────────────────────────────────┐
│ ZOPK Pipeline │
│ (news fetch → scrape → extract → embed) │
│ Zbiera dane: PEJ, offshore, Kongsberg, H2... │
└──────────────────┬──────────────────────────────┘
│ filtruje po project_id
│ (nuclear-plant) i category='nuclear'
▼
┌─────────────────────────────────────────────────┐
│ Sekcja PEJ (/pej) │
│ Landing page + Local Content + Aktualności │
│ + Ogłoszenia Izby (kategoria 'pej') │
└─────────────────────────────────────────────────┘
Data Sources — Co skąd ciągniemy
| Dane | Źródło ZOPK | Filtr | Join path |
|---|---|---|---|
| Aktualności | zopk_news |
project_id IN (nuclear_project_ids) |
bezpośredni |
| Milestones/Timeline | zopk_milestones |
category = 'nuclear' |
bezpośredni |
| Firmy dostawcy | zopk_company_links |
project_id IN (nuclear_project_ids) |
bezpośredni |
| Fakty wiedzy | zopk_knowledge_facts |
source_news_id → zopk_news.project_id |
1 JOIN przez source_news_id |
| Encje (Westinghouse, Bechtel...) | zopk_knowledge_entities |
zopk_project_id IN (nuclear_project_ids) |
bezpośredni |
Nuclear Project ID Resolution
NUCLEAR_PROJECT_SLUGS = ['nuclear-plant'] # explicite lista, łatwa do rozszerzenia o SMR
def get_nuclear_project_ids(db_session):
"""Zwraca ID projektów nuklearnych z ZOPK."""
projects = db_session.query(ZOPKProject.id).filter(
ZOPKProject.slug.in_(NUCLEAR_PROJECT_SLUGS),
ZOPKProject.project_type == 'energy'
).all()
return [p.id for p in projects]
Filtr po explicit slug list + project_type = 'energy' — bezpieczny przed przypadkowym dopasowaniem.
Ogłoszenia Izby (np. notatki ze spotkań z PEJ)
Wykorzystujemy istniejący model Announcement z nową kategorią pej. Treści jak notatka WhatsApp o spotkaniu z Grzegorzem Majem → ogłoszenie z category = 'pej', widoczne na stronie PEJ.
Wymagane zmiany kodu (bez migracji SQL):
database.py→Announcement.CATEGORIESlist — dodać'pej'database.py→Announcement.CATEGORY_LABELSdict — dodać'pej': 'PEJ / Energetyka jądrowa'- Template
admin/announcements_form.htmlrenderuje checkboxy zCATEGORIESautomatycznie — brak zmian
Routes
Public Routes
Wymagają @login_required — w odróżnieniu od ZOPK (publiczne), PEJ zawiera dane kontaktowe firm (email, telefon) w sekcji Local Content, dlatego wymaga logowania.
| Route | Funkcja | Opis |
|---|---|---|
GET /pej |
pej_index() |
Landing page — hero, stats, najnowsze aktualności, timeline nuklearny, top 6 firm Local Content, ogłoszenia Izby |
GET /pej/local-content |
pej_local_content() |
Pełna lista firm z matchingiem do PEJ — filtry po branży, typie współpracy, score |
GET /pej/aktualnosci |
pej_news() |
Aktualności nuklearne (paginacja, z ZOPK news filtered) |
Admin Routes
| Route | Funkcja | Opis |
|---|---|---|
GET /admin/pej/export |
pej_export_csv() |
Eksport CSV firm: nazwa, email kontaktowy, branża, PKD, usługi, typ współpracy, opis, score |
File Structure (spójne z wzorcem ZOPK)
blueprints/public/routes_pej.py # 3 public routes (jak routes_zopk.py)
blueprints/admin/routes_pej.py # 1 admin export route (jak routes_zopk_*.py)
templates/pej/
├── index.html # Landing page
├── local_content.html # Lista firm
└── news.html # Aktualności nuklearne
Rejestracja w app.py — import routes w odpowiednich blueprintach (public, admin).
Templates
1. templates/pej/index.html — Landing Page
┌─────────────────────────────────────────────────────┐
│ HERO: "Elektrownia Jądrowa — Szanse dla Naszych │
│ Firm" │
│ Krótki opis: Izba Norda Biznes aktywnie uczestniczy │
│ w projekcie PEJ. Tu znajdziesz aktualności, │
│ listę firm gotowych do współpracy i informacje │
│ o możliwościach dla członków. │
├─────────────────────────────────────────────────────┤
│ STATS BAR: [X firm gotowych] [Y aktualności] │
│ [Z milestones] │
├─────────────────────────────────────────────────────┤
│ OGŁOSZENIA IZBY (kategoria 'pej') │
│ Np. notatka o spotkaniu z PEJ │
├──────────────────────┬──────────────────────────────┤
│ AKTUALNOŚCI (3-4) │ TIMELINE nuklearny │
│ Najnowsze newsy │ (milestones category= │
│ z ZOPK nuclear │ nuclear) │
│ [Zobacz wszystkie →] │ │
├──────────────────────┴──────────────────────────────┤
│ LOCAL CONTENT — Firmy z Izby gotowe do współpracy │
│ Top 6 firm (wg relevance_score) │
│ Każda karta: nazwa, branża, typ współpracy, opis │
│ [Zobacz pełną listę →] [Eksportuj CSV →] │
└─────────────────────────────────────────────────────┘
Kolorystyka: odróżniona od ZOPK (zielony). PEJ → fioletowo-niebieski (#7c3aed / #4f46e5) — nawiązanie do koloru projektu nuclear-plant w bazie.
2. templates/pej/local_content.html — Lista Firm
┌─────────────────────────────────────────────────────┐
│ HEADER: "Local Content — Firmy Izby Norda dla PEJ" │
│ [Eksportuj CSV] │
├─────────────────────────────────────────────────────┤
│ FILTRY: [Branża ▼] [Typ współpracy ▼] [Szukaj...] │
├─────────────────────────────────────────────────────┤
│ LISTA FIRM (karty): │
│ ┌───────────────────────────────────────────────┐ │
│ │ Logo | Nazwa firmy | Score: 85/100 │ │
│ │ | Branża: IT, Services | Dostawca ⚡ │ │
│ │ | Opis współpracy z AI matching │ │
│ │ | Email: kontakt@firma.pl │ │
│ │ | [Zobacz profil →] │ │
│ └───────────────────────────────────────────────┘ │
│ ... (paginacja) │
└─────────────────────────────────────────────────────┘
Sortowanie domyślne: relevance_score DESC. Filtry:
- Branża (z
Company.category) - Typ współpracy (z
ZOPKCompanyLink.link_type) - Szukaj (po nazwie firmy)
Wyświetlane firmy: ZOPKCompanyLink.relevance_score >= 25 (próg z matchingu AI), wszystkie statusy (suggested, confirmed, active) — na tym etapie nie rozróżniamy, bo wszystkie linki pochodzą z AI matchingu.
3. templates/pej/news.html — Aktualności
Analogicznie do zopk/news_list.html, ale z filtrem na projekt nuklearny. Bez filtra po projekcie (bo wszystko jest już nuklearne).
CSV Export
Endpoint: GET /admin/pej/export (wymaga admin/OFFICE_MANAGER)
Kolumny:
Nazwa firmy;Email;Telefon;Branża;PKD (główny);Usługi;Typ współpracy PEJ;Opis współpracy;Score;Miasto
Źródło: ZOPKCompanyLink JOIN Company WHERE project_id IN (nuclear_ids) AND relevance_score >= 25 — sortowane po score DESC.
Kodowanie: UTF-8 BOM (dla Excela). Separator: ; (standard PL).
Filename: pej-local-content-YYYY-MM-DD.csv. MIME: text/csv; charset=utf-8.
Navigation — Reorganizacja głównego NAV
Zmiana dla WSZYSTKICH zalogowanych użytkowników
Standalone link "Kaszubia" zastępujemy dropdownem "Projekty ▾":
- Projekty ▾ → Kaszubia (
/zopk), PEJ (/pej)
Reorganizacja NAV admina (13 → 10 pozycji)
Usuwamy z głównego NAV:
- "Social (beta)" — duplikat, jest w admin barze jako "Publikacja social media"
- "Korzyści" — duplikat, jest w admin barze pod "Izba → Korzyści"
- "Więcej ▾" — zastępujemy "Projekty ▾", a admin-only items (Kontakty zewnętrzne, Raporty, Mapa Powiązań) przenosimy do admin bara
Przenosiny do admin bara:
- Kontakty zewnętrzne → admin bar, nowy dropdown "Narzędzia" lub do "Izba"
- Raporty → admin bar "Narzędzia"
- Mapa Powiązań → admin bar "Narzędzia"
Wynik — admin NAV:
Firmy | NordaGPT | Kalendarz | B2B | Forum | Wiadomości | Aktualności | Edukacja | Rada | Projekty▾ | [🔔] [User▾]
Wynik — zwykły użytkownik NAV:
Firmy | NordaGPT | Kalendarz | B2B | Forum | Wiadomości | Aktualności | Edukacja | Projekty▾ | [🔔] [User▾]
Mobile
- "Projekty ▾" w hamburger menu, rozwijany na tap
Data Model Changes
Brak nowych tabel
Cała sekcja PEJ operuje na istniejących modelach ZOPK.
Announcement category (zmiana w kodzie, bez migracji)
Dwa miejsca w database.py:
Announcement.CATEGORIES— dodać'pej'do listyAnnouncement.CATEGORY_LABELS— dodać'pej': 'PEJ / Energetyka jądrowa'
Kolumna categories to ARRAY(String) bez CHECK constraint — brak potrzeby migracji SQL.
WhatsApp Content Strategy
Treść notatki WhatsApp o spotkaniu z PEJ:
- Ogłoszenie na portalu —
Announcementzcategory=['pej'], widoczne na/peji/ogloszenia - Hero content na landing page — wyróżniony blok "Ostatnie spotkanie z PEJ" na stronie
/pej - Motywacja do uzupełnienia profili — CTA na stronie PEJ: "Uzupełnij profil firmy, aby znaleźć się na liście Local Content"
Scope Exclusions (YAGNI)
Celowo nie robimy teraz:
- Formularz deklaracji gotowości firmy do PEJ (wystarczy matching AI)
- Integracja NordaGPT z filtrem PEJ-only (chatbot i tak rozpoznaje pytania o PEJ)
- Osobny pipeline news dla PEJ (ZOPK pipeline już zbiera te dane)
- PDF export (CSV wystarczy na potrzeby PEJ)
- Osobna sekcja dla SMR / OSGE (przyszłościowo — dodanie slugów do
NUCLEAR_PROJECT_SLUGS) - Dalsze konsolidacje NAV (Forum+Wiadomości itp.) — obecny układ jest wystarczający
Testing
- Weryfikacja na staging.nordabiznes.pl przed wdrożeniem na produkcję
- Sprawdzenie czy firmy z matchingiem nuklearnym wyświetlają się poprawnie
- Test eksportu CSV — otwarcie w Excel, weryfikacja polskich znaków (UTF-8 BOM)
- Test nawigacji — link PEJ widoczny dla zalogowanych
- Test responsywności — mobile, tablet