Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Expanded roadmap card for multi-location feature with 7 detailed steps: model, migration, edit form, save logic, profile display, route changes, and explicit out-of-scope items. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
103 lines
4.3 KiB
Python
103 lines
4.3 KiB
Python
"""
|
|
Admin Roadmap Routes
|
|
====================
|
|
|
|
Product roadmap — feature requests from members and strategic plans.
|
|
"""
|
|
|
|
import logging
|
|
from flask import render_template
|
|
from flask_login import login_required
|
|
from . import bp
|
|
from database import SystemRole
|
|
from utils.decorators import role_required
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
ROADMAP_ITEMS = [
|
|
{
|
|
'id': 1,
|
|
'title': 'Wiele lokalizacji firmy na mapie',
|
|
'description': 'Firmy z kilkoma oddziałami/punktami mogą dodać wiele adresów. '
|
|
'Każdy wyświetlany na profilu z linkiem do Google Maps.',
|
|
'details': [
|
|
'<strong>1. Model</strong> — nowa tabela <code>company_locations</code>: id, company_id (FK CASCADE), '
|
|
'label (np. "Biuro główne", "Magazyn"), address_street, address_city, address_postal, '
|
|
'lat, lng (opcjonalne — na przyszłość), is_primary, source, created_at. '
|
|
'Relacja na Company: locations = relationship(CompanyLocation, cascade=all delete-orphan)',
|
|
|
|
'<strong>2. Migracja SQL</strong> — <code>database/migrations/100_company_locations.sql</code>: '
|
|
'CREATE TABLE IF NOT EXISTS, indeks na company_id, GRANT na nordabiz_app. '
|
|
'Migracja danych: INSERT z istniejących address_* dla firm z adresem (żeby nie stracić danych)',
|
|
|
|
'<strong>3. Formularz edycji</strong> — nowa sekcja "Dodatkowe lokalizacje" w zakładce Kontakt '
|
|
'(<code>templates/company_edit.html</code>). Dynamiczne wiersze wzorowane na CompanyWebsite: '
|
|
'label + street + postal + city + is_primary radio + przycisk usuń. Max 10 lokalizacji. '
|
|
'JS: makeLocationRow(), removeLocationRow(), reindexLocationRadios()',
|
|
|
|
'<strong>4. Zapis</strong> — funkcja <code>_save_locations()</code> w '
|
|
'<code>blueprints/public/routes_company_edit.py</code>. '
|
|
'Strategia delete-and-reinsert (jak websites): usuń wszystkie WHERE company_id AND source IN (null, manual_edit), '
|
|
'wstaw z formularza: location_labels[], location_streets[], location_postals[], location_cities[], location_primary. '
|
|
'Aktualizacja address_* na Company z primary location',
|
|
|
|
'<strong>5. Profil firmy</strong> — wyświetlanie w <code>templates/company_detail.html</code> (linia ~1078). '
|
|
'Jeśli firma ma lokalizacje → wyświetl wszystkie z labelami, każda z linkiem "Pokaż na mapie →" '
|
|
'(Google Maps Search URL). Primary oznaczona jako "Siedziba główna". '
|
|
'Fallback na obecny address_full jeśli brak lokalizacji',
|
|
|
|
'<strong>6. Route</strong> — w <code>blueprints/public/routes.py</code> company_detail(): '
|
|
'eager load company.locations i przekazać do szablonu',
|
|
|
|
'<strong>Czego NIE robimy:</strong> brak embedded Google Maps (iframe/API), '
|
|
'brak geocodingu (lat/lng pola przygotowane na przyszłość), '
|
|
'brak edycji lokalizacji przez admina — tylko przez właściciela firmy',
|
|
],
|
|
'requested_by': 'Daniel Kochański (Stalpunkt)',
|
|
'date': '2026-04-09',
|
|
'priority': 'medium',
|
|
'status': 'planned',
|
|
'category': 'feature',
|
|
},
|
|
]
|
|
|
|
STATUS_LABELS = {
|
|
'planned': ('Planowane', '#6366f1'),
|
|
'in_progress': ('W trakcie', '#f59e0b'),
|
|
'done': ('Zrealizowane', '#10b981'),
|
|
'on_hold': ('Wstrzymane', '#94a3b8'),
|
|
}
|
|
|
|
PRIORITY_LABELS = {
|
|
'high': ('Wysoki', '#ef4444'),
|
|
'medium': ('Średni', '#f59e0b'),
|
|
'low': ('Niski', '#6b7280'),
|
|
}
|
|
|
|
CATEGORY_LABELS = {
|
|
'feature': 'Nowa funkcjonalność',
|
|
'improvement': 'Ulepszenie',
|
|
'bugfix': 'Naprawa błędu',
|
|
}
|
|
|
|
|
|
@bp.route('/roadmap')
|
|
@login_required
|
|
@role_required(SystemRole.ADMIN)
|
|
def admin_roadmap():
|
|
"""Product roadmap — feature requests and development plans."""
|
|
planned = [i for i in ROADMAP_ITEMS if i['status'] == 'planned']
|
|
in_progress = [i for i in ROADMAP_ITEMS if i['status'] == 'in_progress']
|
|
done = [i for i in ROADMAP_ITEMS if i['status'] == 'done']
|
|
|
|
return render_template(
|
|
'admin/roadmap.html',
|
|
planned=planned,
|
|
in_progress=in_progress,
|
|
done=done,
|
|
status_labels=STATUS_LABELS,
|
|
priority_labels=PRIORITY_LABELS,
|
|
category_labels=CATEGORY_LABELS,
|
|
)
|