- Document incident 2026-01-31 (alias failure) - New rule: Use full blueprint names, NOT aliases - New procedure: Update templates BEFORE moving routes - Enhanced checklist: Test page rendering, not just HTTP status Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.2 KiB
Status Refaktoringu app.py
Ostatnia aktualizacja: 2026-01-31 Autor sesji: Claude Opus 4.5
Stan obecny
Faza 1 - ✅ WDROŻONA NA PRODUKCJĘ
Commit: 66856a6
Data wdrożenia: 2026-01-28
| Blueprint | URL Prefix | Routes | Status |
|---|---|---|---|
| reports | /raporty |
4 | ✅ Przetestowane |
| contacts | /kontakty |
6 | ✅ Przetestowane |
| classifieds | /tablica |
4 | ✅ Przetestowane |
| calendar | /kalendarz |
3 | ✅ Przetestowane |
| education | /edukacja |
2 | ✅ Przetestowane |
Faza 2a - ✅ WDROŻONA NA PRODUKCJĘ
Data wdrożenia: 2026-01-31
Strategia: Alias Bridge (bezpieczna migracja)
Commity: d5adf02 (blueprinty), cdd050a (cleanup), 0ccb109 (docs)
| Blueprint | Routes | Status |
|---|---|---|
| auth | 20 | ✅ Gotowy, aliasy aktywne |
| public | 11 | ✅ Gotowy, aliasy aktywne |
Pliki utworzone:
blueprints/auth/__init__.pyblueprints/auth/routes.py(1,040 linii)blueprints/public/__init__.pyblueprints/public/routes.py(862 linii)
Redukcja app.py:
- Przed: 15,577 linii
- Po: 13,820 linii
- Usunięto: 1,757 linii (11.3%)
Testy (DEV):
- ✅ Wszystkie endpointy działają
- ✅ Aliasy:
url_for('login')=url_for('auth.login') - ✅ Istniejące blueprinty działają
Metodologia Refaktoringu (Alias Bridge)
Dlaczego ta metoda?
Problem: 125+ wywołań url_for() w szablonach i kodzie używa starych nazw (url_for('login')).
Rozwiązanie: Aliasy pozwalają na stopniową migrację bez "Big Bang".
Procedura dla każdej fazy
Krok 1: Utworzenie blueprintu
mkdir -p blueprints/<nazwa>
touch blueprints/<nazwa>/__init__.py
touch blueprints/<nazwa>/routes.py
# blueprints/<nazwa>/__init__.py
from flask import Blueprint
bp = Blueprint('<nazwa>', __name__)
from . import routes
Krok 2: Przeniesienie tras
- Skopiuj funkcje z app.py do
blueprints/<nazwa>/routes.py - Zmień
@app.routena@bp.route - Zaktualizuj importy (używaj
from extensions import limiter) - Wewnętrzne url_for: użyj
.endpoint(z kropką)
Krok 3: Rejestracja + aliasy
# blueprints/__init__.py
from blueprints.<nazwa> import bp as <nazwa>_bp
app.register_blueprint(<nazwa>_bp)
_create_endpoint_aliases(app, <nazwa>_bp, {
'stara_nazwa': '<nazwa>.nowa_nazwa',
# ...
})
Krok 4: Dezaktywacja duplikatów w app.py
# PRZED:
@app.route('/endpoint')
def funkcja():
# PO:
# @app.route('/endpoint') # MOVED TO <nazwa>.<endpoint>
def _old_funkcja():
Krok 5: Test
python3 -c "from app import app; print('OK')"
# Test wszystkich endpointów
Krok 6: Cleanup (po weryfikacji na PROD)
Usuń funkcje z prefiksem _old_ z app.py.
Harmonogram
Szczegółowy plan: docs/MODULAR_MONOLITH_PLAN.md
Podsumowanie faz
| Faza | Zakres | Routes | Status |
|---|---|---|---|
| 1 | reports, community, education | 19 | ✅ WDROŻONA |
| 2a | auth + public + cleanup | 31 | ✅ WDROŻONA |
| 3 | forum (10 routes) | 10 | ✅ WDROŻONA |
| 4 | messages + notifications (11 routes) | 11 | ✅ WDROŻONA |
| 5 | chat (9 routes) | 9 | ✅ WDROŻONA |
| 6.1 | admin Part 1 (recommendations, users, fees, calendar) | 19 | ✅ WDROŻONA |
| 6.2 | admin Part 2 (seo, analytics, ai-usage, status, etc.) | ~41 | ⏳ |
| 7 | audits (6 modułów) | ~35 | ⏳ |
| 8 | zopk (5 modułów) | ~32 | ⏳ |
| 9 | api misc, honeypot | ~25 | ⏳ |
| 10 | final cleanup | - | ⏳ |
Cel końcowy: Redukcja app.py z 15,570 → ~500 linii
Metryki optymalizacji
Po Fazie 1 (2026-01-28)
- app.py: 15,570 → 13,699 linii (-12%)
Po Fazie 2a (2026-01-31)
- app.py: 15,577 → 13,820 linii
- Usunięto: 1,757 linii (11.3%)
- Nowe pliki:
blueprints/auth/routes.py(1,040 linii)blueprints/public/routes.py(862 linii)
Po Fazie 3 - Forum (2026-01-31)
- app.py: 13,820 → 13,398 linii
- Usunięto: 422 linie (3.1%)
- Nowe pliki:
blueprints/forum/__init__.pyblueprints/forum/routes.py(450 linii)
Po Fazie 6.1 - Admin Part 1 (2026-01-31)
- app.py: 12,600 → 11,774 linii (-826 linii)
- Nowe pliki:
blueprints/admin/__init__.py(12 linii)blueprints/admin/routes.py(828 linii)
- Trasy przeniesione: 19 (recommendations: 3, users: 8, fees: 5, calendar: 3)
- UWAGA: Trasy AI-parse pozostają w app.py
Łączna redukcja app.py
- Start: 15,570 linii
- Po Fazie 1: 13,699 linii (-12.0%)
- Po Fazie 2a: 13,820 linii (-11.2% od startu)
- Po Fazie 3: 13,398 linii (-13.9% od startu)
- Po Fazie 4: 13,058 linii (-16.1% od startu)
- Po Fazie 5: 12,600 linii (-19.1% od startu)
- Po Fazie 6.1: 11,774 linii (-24.4% od startu)
- Cel końcowy: ~500 linii
Weryfikacja przed wdrożeniem
Checklist DEV
# 1. Import aplikacji
python3 -c "from app import app; print('OK')"
# 2. Test endpointów
python3 -c "
from app import app
with app.test_client() as c:
assert c.get('/').status_code == 200
assert c.get('/login').status_code == 200
assert c.get('/health').status_code == 200
print('All endpoints OK')
"
# 3. Test url_for (aliasy)
python3 -c "
from app import app
from flask import url_for
with app.test_request_context():
assert url_for('login') == '/login'
assert url_for('auth.login') == '/login'
assert url_for('index') == '/'
assert url_for('public.index') == '/'
print('Aliases OK')
"
Checklist PROD
# Po wdrożeniu
curl -sI https://nordabiznes.pl/health | head -1
curl -sI https://nordabiznes.pl/ | head -1
curl -sI https://nordabiznes.pl/login | head -1
curl -sI https://nordabiznes.pl/release-notes | head -1
Metodologia Bezpiecznego Wdrażania (OBOWIĄZKOWA)
INCYDENT 2026-01-31: Awaria produkcji spowodowana niedziałającymi aliasami. Szablony używały
url_for('admin_seo')ale alias nie został utworzony.
Zasady PRZED przeniesieniem trasy do blueprintu
- NAJPIERW zaktualizuj szablony - zmień
url_for('stara_nazwa')naurl_for('blueprint.endpoint') - Wdróż zmianę szablonów - przetestuj na produkcji
- DOPIERO POTEM przenieś trasę do blueprintu
Zasada: Pełne nazwy blueprintów (NIE aliasy)
# ❌ BŁĘDNIE - aliasy są zawodne
url_for('admin_seo')
# ✅ PRAWIDŁOWO - pełna nazwa blueprintu
url_for('admin.admin_seo')
Dlaczego: Aliasy mogą nie działać dla tras w oddzielnych plikach. Pełne nazwy są jawne i niezawodne.
Checklist PRZED każdym deploy
# 1. Test importu
python3 -c "from app import app; print('OK')"
# 2. Test renderowania strony głównej (NIE tylko status!)
curl -s https://localhost:5000/ | head -50
# 3. Test url_for dla przeniesionych endpointów
python3 -c "
from app import app
from flask import url_for
with app.test_request_context():
print(url_for('admin.admin_seo')) # Musi działać
"
# 4. Dopiero po pozytywnych testach - deploy na PROD
Procedura przenoszenia trasy (NOWA)
- Audit szablonów - znajdź wszystkie
url_for('nazwa_trasy')w templates/ - Zaktualizuj szablony - zmień na
url_for('blueprint.nazwa_trasy') - Wdróż szablony - commit, push, deploy, test PROD
- Utwórz trasę w blueprincie - skopiuj kod do blueprints/
- Skomentuj trasę w app.py - prefix
_old_ - Test lokalny - import + renderowanie stron
- Deploy - commit, push, deploy
- Test PROD - sprawdź czy strony się renderują
- Cleanup - usuń martwy kod z app.py
Lekcje na przyszłość
-
url_for w szablonach:
- ZAWSZE używaj pełnych nazw:
url_for('blueprint.endpoint') - NIE polegaj na aliasach - są zawodne
- Wewnątrz blueprintu:
url_for('.endpoint')(z kropką)
- ZAWSZE używaj pełnych nazw:
-
Kolejność operacji:
- NAJPIERW szablony - zaktualizuj url_for
- Potem blueprinty
- Cleanup dopiero po teście PROD
-
Bezpieczeństwo:
- Zawsze testuj renderowanie stron, nie tylko status HTTP
- Prefix
_old_dla zdezaktywowanych funkcji - Rollback: odkomentuj
@app.route
Kontakt
W razie problemów z wdrożeniem sprawdź:
- Logi:
/var/log/nordabiznes/ - Health check:
curl https://nordabiznes.pl/health - Rollback:
git revert HEAD && git push