refactor: Migrate digital_maturity_dashboard and admin_krs_audit to blueprints

- Move routes from app.py to blueprints/admin/routes_audits.py
- Add endpoint aliases for backward compatibility
- Update base.html template to use full blueprint names
- Comment old routes in app.py with _old_ prefix

Phase 6.2f of blueprint migration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-31 09:19:56 +01:00
parent 9dedab2929
commit 806f9e730e
4 changed files with 199 additions and 8 deletions

12
app.py
View File

@ -5986,9 +5986,9 @@ def _old_api_test_log():
return jsonify({'success': True, 'message': 'Test logs generated'})
@app.route('/admin/digital-maturity')
@login_required
def digital_maturity_dashboard():
# @app.route('/admin/digital-maturity') # MOVED TO admin.digital_maturity_dashboard
# @login_required
def _old_digital_maturity_dashboard():
"""Admin dashboard for digital maturity assessment results"""
if not current_user.is_admin:
flash('Brak uprawnień do tej strony.', 'error')
@ -9644,9 +9644,9 @@ def api_zopk_timeline_suggestion_approve():
# KRS AUDIT (Krajowy Rejestr Sądowy)
# ============================================================
@app.route('/admin/krs-audit')
@login_required
def admin_krs_audit():
# @app.route('/admin/krs-audit') # MOVED TO admin.admin_krs_audit
# @login_required
def _old_admin_krs_audit():
"""
Admin dashboard for KRS (Krajowy Rejestr Sądowy) audit.

View File

@ -236,6 +236,9 @@ def register_blueprints(app):
# Social Media (Phase 6.2e)
'admin_social_media': 'admin.admin_social_media',
'admin_social_audit': 'admin.admin_social_audit',
# Digital Maturity & KRS Audit (Phase 6.2f)
'digital_maturity_dashboard': 'admin.digital_maturity_dashboard',
'admin_krs_audit': 'admin.admin_krs_audit',
})
logger.info("Created admin endpoint aliases")
except ImportError as e:

View File

@ -13,7 +13,8 @@ from flask_login import login_required, current_user
from . import bp
from database import (
SessionLocal, Company, Category, CompanyWebsiteAnalysis, GBPAudit
SessionLocal, Company, Category, CompanyWebsiteAnalysis, GBPAudit,
CompanyDigitalMaturity, KRSAudit, CompanyPKD, CompanyPerson
)
logger = logging.getLogger(__name__)
@ -299,3 +300,190 @@ def admin_gbp_audit():
)
finally:
db.close()
# ============================================================
# DIGITAL MATURITY DASHBOARD
# ============================================================
@bp.route('/digital-maturity')
@login_required
def digital_maturity_dashboard():
"""Admin dashboard for digital maturity assessment results"""
if not current_user.is_admin:
flash('Brak uprawnień do tej strony.', 'error')
return redirect(url_for('public.dashboard'))
db = SessionLocal()
try:
from sqlalchemy import func, desc
# Get all companies with maturity data
companies_query = db.query(
Company.id,
Company.name,
Company.slug,
Company.website,
CompanyDigitalMaturity.overall_score,
CompanyDigitalMaturity.online_presence_score,
CompanyDigitalMaturity.sales_readiness,
CompanyDigitalMaturity.total_opportunity_value,
CompanyWebsiteAnalysis.opportunity_score,
CompanyWebsiteAnalysis.has_blog,
CompanyWebsiteAnalysis.has_portfolio,
CompanyWebsiteAnalysis.has_contact_form,
CompanyWebsiteAnalysis.content_richness_score,
CompanyDigitalMaturity.critical_gaps,
CompanyWebsiteAnalysis.missing_features
).join(
CompanyDigitalMaturity, Company.id == CompanyDigitalMaturity.company_id
).join(
CompanyWebsiteAnalysis, Company.id == CompanyWebsiteAnalysis.company_id
).filter(
CompanyDigitalMaturity.overall_score > 0
).order_by(
desc(CompanyDigitalMaturity.overall_score)
).all()
# Calculate stats
total_analyzed = len(companies_query)
avg_score = round(sum(c.overall_score for c in companies_query) / total_analyzed, 1) if total_analyzed else 0
total_opportunity = sum(float(c.total_opportunity_value or 0) for c in companies_query)
warm_leads = [c for c in companies_query if c.sales_readiness == 'warm']
cold_leads = [c for c in companies_query if c.sales_readiness == 'cold']
# Top 10 and bottom 10
top_performers = companies_query[:10]
bottom_performers = sorted(companies_query, key=lambda c: c.overall_score)[:10]
# Top opportunities
top_opportunities = sorted(
companies_query,
key=lambda c: float(c.total_opportunity_value or 0),
reverse=True
)[:10]
return render_template('admin/digital_maturity.html',
total_analyzed=total_analyzed,
avg_score=avg_score,
total_opportunity=total_opportunity,
warm_leads_count=len(warm_leads),
cold_leads_count=len(cold_leads),
top_performers=top_performers,
bottom_performers=bottom_performers,
top_opportunities=top_opportunities,
all_companies=companies_query
)
finally:
db.close()
# ============================================================
# KRS AUDIT DASHBOARD
# ============================================================
@bp.route('/krs-audit')
@login_required
def admin_krs_audit():
"""
Admin dashboard for KRS (Krajowy Rejestr Sądowy) audit.
Displays:
- Summary stats (with KRS, audited count, data extraction status)
- List of companies with KRS numbers
- Audit progress and status for each company
- Links to source PDF files
"""
if not current_user.is_admin:
flash('Brak uprawnień do tej strony.', 'error')
return redirect(url_for('public.dashboard'))
# Check if KRS audit service is available
try:
from krs_audit_service import KRS_AUDIT_AVAILABLE
except ImportError:
KRS_AUDIT_AVAILABLE = False
db = SessionLocal()
try:
from sqlalchemy import func
# Get all active companies with KRS numbers
companies_query = db.query(Company).filter(
Company.status == 'active',
Company.krs.isnot(None),
Company.krs != ''
).order_by(Company.name).all()
# Get latest audit for each company
companies = []
for company in companies_query:
# Get latest audit
latest_audit = db.query(KRSAudit).filter(
KRSAudit.company_id == company.id
).order_by(KRSAudit.audit_date.desc()).first()
# Get PKD codes (all)
pkd_codes = db.query(CompanyPKD).filter(
CompanyPKD.company_id == company.id
).order_by(CompanyPKD.is_primary.desc(), CompanyPKD.pkd_code).all()
pkd_count = len(pkd_codes)
# Get people count
people_count = db.query(CompanyPerson).filter(
CompanyPerson.company_id == company.id
).count()
companies.append({
'id': company.id,
'name': company.name,
'slug': company.slug,
'krs': company.krs,
'nip': company.nip,
'capital_amount': company.capital_amount,
'krs_last_audit_at': company.krs_last_audit_at,
'krs_pdf_path': company.krs_pdf_path,
'audit': latest_audit,
'pkd_count': pkd_count,
'pkd_codes': [{
'code': pkd.pkd_code,
'description': pkd.pkd_description,
'is_primary': pkd.is_primary
} for pkd in pkd_codes],
'people_count': people_count,
'capital_shares_count': company.capital_shares_count
})
# Calculate stats
total_with_krs = len(companies)
audited_count = len([c for c in companies if c['krs_last_audit_at']])
not_audited_count = total_with_krs - audited_count
with_capital = len([c for c in companies if c['capital_amount']])
with_people = len([c for c in companies if c['people_count'] > 0])
with_pkd = len([c for c in companies if c['pkd_count'] > 0])
# Companies without KRS
no_krs_count = db.query(Company).filter(
Company.status == 'active',
(Company.krs.is_(None)) | (Company.krs == '')
).count()
stats = {
'total_with_krs': total_with_krs,
'audited_count': audited_count,
'not_audited_count': not_audited_count,
'no_krs_count': no_krs_count,
'with_capital': with_capital,
'with_people': with_people,
'with_pkd': with_pkd
}
return render_template('admin/krs_audit_dashboard.html',
companies=companies,
stats=stats,
krs_audit_available=KRS_AUDIT_AVAILABLE,
now=datetime.now()
)
finally:
db.close()

View File

@ -1311,7 +1311,7 @@
</svg>
Audyt Social
</a>
<a href="{{ url_for('admin_krs_audit') }}">
<a href="{{ url_for('admin.admin_krs_audit') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>