# Strategia Bezpiecznego Wdrożenia Fazy 2

> **Data:** 2026-01-31
> **Status:** KRYTYCZNE - wymaga starannego planowania
> **Ryzyko:** Wysokie - 125+ zmian musi być atomowych

---

## Problem

### Obecne nazwy endpointów (bez prefiksu)

```python
# app.py
@app.route('/')
def index(): ...           # url_for('index')

@app.route('/login')
def login(): ...           # url_for('login')

@app.route('/dashboard')
def dashboard(): ...       # url_for('dashboard')
```

### Docelowe nazwy endpointów (z prefiksem blueprintu)

```python
# blueprints/public/routes.py
@bp.route('/')
def index(): ...           # url_for('public.index')

# blueprints/auth/routes.py
@bp.route('/login')
def login(): ...           # url_for('auth.login')
```

### Skala zmian

| Lokalizacja | url_for('index') | url_for('login') | url_for('dashboard') | url_for('register') |
|-------------|------------------|------------------|----------------------|---------------------|
| app.py | 18 | 10 | 43 | 0 |
| szablony | 27 | 11 | 6 | 10 |
| **RAZEM** | **45** | **21** | **49** | **10** |

**Łącznie: ~125 miejsc do zmiany ATOMICZNIE**

---

## Strategie wdrożenia

### ❌ Opcja A: Stopniowe wdrażanie (NIEMOŻLIWE)

Nie można wdrożyć blueprintu bez zmiany wszystkich url_for.
Każda częściowa zmiana = awaria.

### ⚠️ Opcja B: Aliasy / Redirecty (RYZYKOWNE)

```python
# Po rejestracji blueprintu, dodać alias w app.py:
@app.route('/_redirect_index')
def _old_index():
    return redirect(url_for('public.index'))

# Ale url_for('index') wciąż nie zadziała!
```

**Problem:** Flask nie wspiera natywnie aliasów endpointów.

### ⚠️ Opcja C: Endpoint override (CZĘŚCIOWO)

```python
# W blueprincie - nadpisać nazwę endpointu
@bp.route('/', endpoint='index')  # Bez prefiksu!
def index_view():
    ...
```

**Problem:**
- `url_for('index')` zadziała ✅
- `url_for('public.index')` NIE zadziała ❌
- `utils/decorators.py` wymaga `url_for('public.index')` ❌

### ✅ Opcja D: Big Bang z testami (REKOMENDOWANA)

1. Przygotować WSZYSTKIE zmiany lokalnie
2. Uruchomić PEŁNE testy lokalne
3. Wdrożyć jednym commitem
4. Mieć gotowy rollback

---

## Plan wdrożenia Fazy 2 (bezpieczny)

### Etap 1: Przygotowanie (lokalnie)

```bash
# 1. Stworzyć nowy branch
git checkout -b feature/phase2-auth-public

# 2. Stworzyć blueprinty
mkdir -p blueprints/auth blueprints/public
```

### Etap 2: Implementacja blueprintów

#### blueprints/auth/routes.py
- Przenieść: login, logout, register, verify-2fa, forgot-password, reset-password, verify-email, resend-verification
- Użyć: `from utils.helpers import validate_email, validate_password, sanitize_input`

#### blueprints/public/routes.py
- Przenieść: index, company_detail, search, events, new_members, connections_map, release_notes
- Użyć: `from utils.helpers import sanitize_input`

### Etap 3: Masowa zmiana url_for

```bash
# Zmiana w szablonach
find templates/ -name "*.html" -exec sed -i '' \
  -e "s/url_for('index')/url_for('public.index')/g" \
  -e "s/url_for('login')/url_for('auth.login')/g" \
  -e "s/url_for('logout')/url_for('auth.logout')/g" \
  -e "s/url_for('register')/url_for('auth.register')/g" \
  -e "s/url_for('dashboard')/url_for('account.dashboard')/g" \
  {} \;

# Zmiana w app.py
sed -i '' \
  -e "s/url_for('index')/url_for('public.index')/g" \
  -e "s/url_for('login')/url_for('auth.login')/g" \
  ... \
  app.py
```

### Etap 4: Testy lokalne (KRYTYCZNE!)

```bash
# 1. Uruchomić aplikację
python3 app.py

# 2. Testy manualne - WSZYSTKIE muszą przejść!
□ Strona główna ładuje się
□ Menu nawigacji działa
□ Link "Zaloguj" działa
□ Formularz logowania działa
□ Logowanie przekierowuje na dashboard
□ Dashboard ładuje się
□ Wylogowanie działa
□ Rejestracja działa
□ Reset hasła działa
□ Wyszukiwarka działa
□ Profil firmy działa
□ Wszystkie istniejące blueprinty działają (reports, contacts, etc.)
```

### Etap 5: Wdrożenie

```bash
# 1. Commit
git add .
git commit -m "refactor(phase2): Extract auth + public blueprints

BREAKING CHANGE: All url_for() calls updated to use blueprint prefixes:
- url_for('index') -> url_for('public.index')
- url_for('login') -> url_for('auth.login')
- url_for('register') -> url_for('auth.register')
- url_for('dashboard') -> url_for('account.dashboard')

~125 files changed atomically."

# 2. Push
git push origin feature/phase2-auth-public
git checkout master
git merge feature/phase2-auth-public
git push origin master && git push inpi master

# 3. Deploy
ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && sudo -u www-data git pull && sudo systemctl restart nordabiznes"

# 4. Weryfikacja (natychmiast!)
curl -sI https://nordabiznes.pl/ | head -3
curl -sI https://nordabiznes.pl/login | head -3
curl -sI https://nordabiznes.pl/dashboard | head -3
```

### Etap 6: Rollback (jeśli potrzebny)

```bash
# Natychmiastowy rollback
git revert HEAD
git push origin master && git push inpi master
ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && sudo -u www-data git pull && sudo systemctl restart nordabiznes"
```

---

## Checklist przed wdrożeniem

### Przygotowanie
- [ ] Nowy branch utworzony
- [ ] Blueprinty auth i public stworzone
- [ ] Wszystkie routes przeniesione
- [ ] Wszystkie url_for zmienione w app.py
- [ ] Wszystkie url_for zmienione w szablonach
- [ ] utils/decorators.py sprawdzony

### Testy lokalne
- [ ] Aplikacja uruchamia się bez błędów
- [ ] Strona główna działa
- [ ] Logowanie działa
- [ ] Dashboard działa
- [ ] Wylogowanie działa
- [ ] Rejestracja działa
- [ ] Menu nawigacji działa
- [ ] Istniejące blueprinty działają

### Przed wdrożeniem
- [ ] Backup bazy danych (opcjonalnie)
- [ ] Czas wdrożenia: niska aktywność użytkowników
- [ ] Osoba monitorująca: dostępna

### Po wdrożeniu
- [ ] Health check OK
- [ ] Strona główna OK
- [ ] Logowanie OK
- [ ] Brak błędów w logach

---

## Alternatywa: Endpoint override (bezpieczniejsza?)

Zamiast zmieniać 125 miejsc, można użyć endpoint override:

```python
# blueprints/public/__init__.py
bp = Blueprint('public', __name__)

# blueprints/public/routes.py
@bp.route('/', endpoint='index')  # Endpoint = 'index' (bez prefiksu!)
def index():
    ...
```

**Zalety:**
- `url_for('index')` dalej działa ✅
- Nie trzeba zmieniać szablonów ✅
- Mniej ryzykowne ✅

**Wady:**
- `utils/decorators.py` używa `url_for('public.index')` - trzeba zmienić ❌
- Niespójna konwencja nazewnictwa ❌
- Trudniejsze debugowanie ❌

### Decyzja

**REKOMENDACJA:** Użyć endpoint override dla pierwszego wdrożenia, potem stopniowo migrować na pełne nazwy.

```python
# Faza 2a: Endpoint override (bezpieczne)
@bp.route('/', endpoint='index')
@bp.route('/login', endpoint='login')

# Faza 2b: Stopniowa zmiana szablonów (później)
# url_for('index') -> url_for('public.index')
```

---

## ✅ REKOMENDOWANA STRATEGIA: Dual Endpoints (Alias Bridge)

### Dowód koncepcji (przetestowane!)

```python
# Flask pozwala zarejestrować ten sam URL pod dwoma nazwami:
app.register_blueprint(auth_bp)  # Rejestruje /login -> auth.login

# Dodanie aliasu dla kompatybilności wstecznej:
app.add_url_rule('/login', 'login', app.view_functions['auth.login'])

# Wynik:
#   /login -> auth.login (nowy)
#   /login -> login      (stary alias)

# Oba url_for działają:
#   url_for('login') = /login        ✓
#   url_for('auth.login') = /login   ✓
```

### Plan wdrożenia (3 podfazy)

#### Faza 2a: Blueprinty + Aliasy (BEZPIECZNE)

```python
# blueprints/__init__.py
def register_blueprints(app):
    from blueprints.auth import bp as auth_bp
    from blueprints.public import bp as public_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(public_bp)

    # ALIASY dla kompatybilności wstecznej
    # Szablony dalej używają url_for('login'), url_for('index'), etc.
    _create_endpoint_aliases(app, {
        # stara_nazwa: nowa_nazwa
        'index': 'public.index',
        'login': 'auth.login',
        'logout': 'auth.logout',
        'register': 'auth.register',
        'dashboard': 'public.dashboard',  # lub account.dashboard
        'search': 'public.search',
        'company_detail': 'public.company_detail',
        'company_detail_by_slug': 'public.company_detail_by_slug',
        # ... wszystkie inne
    })

def _create_endpoint_aliases(app, aliases):
    """Tworzy aliasy dla starych nazw endpointów."""
    for old_name, new_name in aliases.items():
        if new_name in app.view_functions:
            # Znajdź URL dla nowego endpointu
            for rule in app.url_map.iter_rules():
                if rule.endpoint == new_name:
                    app.add_url_rule(
                        rule.rule,
                        old_name,
                        app.view_functions[new_name],
                        methods=rule.methods
                    )
                    break
```

**Efekt Fazy 2a:**
- ✅ Blueprinty działają
- ✅ `url_for('login')` działa (alias)
- ✅ `url_for('auth.login')` działa (nowy)
- ✅ Szablony NIE wymagają zmian
- ✅ Zero ryzyka awarii

#### Faza 2b: Stopniowa migracja szablonów

```bash
# Można zmieniać po jednym szablonie
# Każda zmiana = osobny commit

# Przykład:
sed -i '' "s/url_for('login')/url_for('auth.login')/g" templates/base.html
git commit -m "refactor: Migrate url_for in base.html"
```

**Efekt Fazy 2b:**
- ✅ Szablony używają nowych nazw
- ✅ Aliasy dalej działają (dla nieprzemigrowanych)
- ✅ Można robić stopniowo

#### Faza 2c: Usunięcie aliasów (cleanup)

```python
# Po pełnej migracji szablonów:
# Usunąć _create_endpoint_aliases()
```

**Efekt Fazy 2c:**
- ✅ Czysty kod
- ✅ Tylko nowe nazwy endpointów
- ✅ Pełna migracja zakończona

---

## Podsumowanie strategii

| Faza | Opis | Ryzyko | Szablony |
|------|------|--------|----------|
| **2a** | Blueprinty + aliasy | 🟢 Niskie | Bez zmian |
| **2b** | Migracja szablonów | 🟢 Niskie | Stopniowo |
| **2c** | Usunięcie aliasów | 🟢 Niskie | Po migracji |

### Porównanie z Big Bang

| Aspekt | Big Bang | Alias Bridge |
|--------|----------|--------------|
| Zmiany na raz | ~125 | ~20 (tylko blueprinty) |
| Ryzyko awarii | 🔴 Wysokie | 🟢 Niskie |
| Rollback | Trudny | Łatwy |
| Testowanie | Wszystko naraz | Etapami |
| Czas wdrożenia | 1 dzień | 3-5 dni (bezpiecznie) |

---

## Checklist Fazy 2a

### Przygotowanie
- [ ] Stworzyć `blueprints/auth/__init__.py`
- [ ] Stworzyć `blueprints/auth/routes.py`
- [ ] Stworzyć `blueprints/public/__init__.py`
- [ ] Stworzyć `blueprints/public/routes.py`
- [ ] Przenieść routes z app.py do blueprintów
- [ ] Dodać funkcję `_create_endpoint_aliases()`
- [ ] Zaktualizować `blueprints/__init__.py`

### Testy lokalne
- [ ] Aplikacja uruchamia się
- [ ] `url_for('index')` działa
- [ ] `url_for('public.index')` działa
- [ ] Logowanie działa
- [ ] Strona główna działa
- [ ] Istniejące blueprinty działają

### Wdrożenie
- [ ] Commit + push
- [ ] Deploy na produkcję
- [ ] Weryfikacja health check
- [ ] Weryfikacja logowania

---

**Ostatnia aktualizacja:** 2026-01-31
**Status:** REKOMENDOWANA STRATEGIA - Alias Bridge
