From 9ab41b13cb6a29727fdbad3e1b9c151a32526d06 Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Mon, 16 Mar 2026 10:47:36 +0100 Subject: [PATCH] docs: add PEJ section design spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hybrid "lens" approach — PEJ section filters existing ZOPK data by nuclear project IDs, adding dedicated routes, templates, and CSV export without new database tables. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../specs/2026-03-16-pej-section-design.md | 237 ++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-16-pej-section-design.md diff --git a/docs/superpowers/specs/2026-03-16-pej-section-design.md b/docs/superpowers/specs/2026-03-16-pej-section-design.md new file mode 100644 index 0000000..d34eff2 --- /dev/null +++ b/docs/superpowers/specs/2026-03-16-pej-section-design.md @@ -0,0 +1,237 @@ +# 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: +1. Dostarczenia PEJ listy firm członkowskich z kontaktami i branżami +2. Motywowania członków do uzupełnienia profili na portalu +3. Śledzenia aktualności i postępów projektu nuklearnego +4. 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 `public` i `admin` (spójnie z wzorcem ZOPK) +- Kategorię `pej` w 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 + +```python +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.CATEGORIES` list — dodać `'pej'` +- `database.py` → `Announcement.CATEGORY_LABELS` dict — dodać `'pej': 'PEJ / Energetyka jądrowa'` +- Template `admin/announcements_form.html` renderuje checkboxy z `CATEGORIES` automatycznie — 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 + +Dodajemy link "PEJ" w nawigacji `base.html`: + +**Dla zwykłych zalogowanych użytkowników:** +- Obok istniejącego linku "Kaszubia" dodajemy "PEJ" → `/pej` +- Oba linki jako osobne elementy w top nav (nawigacja nie jest jeszcze przepełniona) + +**Dla admina (w dropdown "Więcej"):** +- Dodajemy "PEJ" pod "Kaszubia" w tym samym dropdown + +**Mobile:** +- Oba linki w hamburger menu, pod sobą + +## 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`: +1. `Announcement.CATEGORIES` — dodać `'pej'` do listy +2. `Announcement.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: +1. **Ogłoszenie na portalu** — `Announcement` z `category=['pej']`, widoczne na `/pej` i `/ogloszenia` +2. **Hero content na landing page** — wyróżniony blok "Ostatnie spotkanie z PEJ" na stronie `/pej` +3. **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`) +- Dropdown "Projekty" grupujący Kaszubia + PEJ (nie potrzebny przy 2 linkach) + +## 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