Without email scope, userinfo endpoint returns 401 and account email
cannot be captured during OAuth flow. Added openid+email to both GBP
and Search Console scopes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After token exchange, fetches Google userinfo to save the email and
name of the Google account used for authorization. Displays this info
on the GBP audit page so users know which account to reconnect with.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moved the OAuth connection status banner from the middle of the page
to directly below the header for immediate visibility. Added direct
link buttons to /konto/integracje for each state: "Zarządzaj" (active),
"Połącz ponownie" (expired), "Połącz konto" (not connected).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows whether the company has an active Google Business Profile
console connection, with clear status indicators (connected/expired/
not connected) and guidance on how to reconnect via Konto → Integracje.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Translate English day names to Polish abbreviations (Mon→Pon, etc.)
- Show all 7 days in grid layout instead of 5 + "..."
- Remove technical scoring breakdown formula from reviews card
- Add "zdjęć w profilu" suffix to photos count
- Show categories as styled badges
- Truncate long descriptions at 120 chars
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JSONB stores dict keys as strings ("5") but template looked up integer keys (5).
Now checks both int and string key variants.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix google_reviews_data bug: data is dict with 'reviews' key, not a list
(was always hidden by 'is not mapping' guard)
- Add rating distribution bar chart from Places API review data
- Display google_photos_metadata table (author, dimensions, owner photos)
- Add audit diagnostics footer (source, version, errors)
- Show owner_response_time and keywords on individual GBP reviews
- Add Polish translations for Google Places business types (40+ types)
- Use primary_type_display for human-readable category names
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add opening hours, business status, Google types, website URL, Place ID,
rating/reviews/photos summary, website tracking indicators, Google attributes,
Places API reviews, smart recommendations engine, and benchmarks comparison
with other Norda Biznes members.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Speed Index, Time to Interactive, Total Blocking Time from PageSpeed
- Benchmark table: company vs category avg vs all-members avg with arrows
- WHOIS via RDAP: domain registration, expiry, last change, registrar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When OG image fails to load (hotlink protection, CORS), shows
clickable URL instead of just "Obrazek niedostepny". Adds
referrerpolicy=no-referrer to bypass referer-based hotlink blocking.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds 'is not mapping' checks for gsc_top_queries, gsc_top_pages,
and gbp_search_keywords to prevent KeyError on slicing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds mapping check before slicing to prevent KeyError when
google_reviews_data is a dict instead of a list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 7 granular steps instead of 4 (connect, pagespeed, onpage, technical,
GSC, save, done) - steps advance on timers during API call
- Results stay visible until user clicks "Ukryj" or "Odswiez strone"
- No more auto-reload that hides results
- Error results also stay visible with hide button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses vertical stepper with checkmarks (connect → analyze → save → done),
confirmation modal before audit, info modal for results. Matches the
pattern used in admin_seo_dashboard.html.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes browser alert/confirm dialogs. Adds inline progress bar with
spinner, percentage, status messages and log entries. Auto-reloads
page after successful audit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds: H3 count, hreflang, meta keywords, canonical URL, noindex reason,
Open Graph Facebook preview (image + title + description), portfolio,
live chat detection, Google website URL, Google business categories,
audit diagnostics section (source, version, errors).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses ip-api.com to look up ISP name, organization, city, region,
country and AS number for the hosting IP address.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Google reviews with text and star ratings (top 5)
- Opening hours from Google Business Profile
- GBP search keywords (how people find this business in Maps)
- GSC top pages (most popular subpages in Google)
- Infrastructure: server IP, software, generator, frameworks,
HTTP status code, last modification date
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New /admin/seo/<id> detail page with full audit breakdown
- 4 score cards with visual rings and Polish descriptions
- Recommendations section: critical/warning/info issues with actionable text
- SEO checklist: meta tags, sitemap, robots, structured data, OG tags
- Technical details: SSL, mobile, CWV metrics, security headers
- Google Business Profile section when available
- Add "Szczegoly" button in company table (replaces profile link)
- Add visible column descriptions above table (not hidden tooltips)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "Problemy" column showing actionable issues per company
(Slabe SEO, Wolna strona, Niska dostepnosc, Brak standardow)
- Add tooltips to column headers explaining each metric
- Sort by worst scores first (companies needing help on top)
- Unaudited companies always at bottom regardless of sort
- Replace "medium" stat card with total companies count
- Remove API button from header (admin doesn't need raw JSON)
- Add problem/warn/ok/na tag styling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove in-memory log viewer (DebugLogHandler, 5 routes, template,
menu links, endpoint aliases). Logs available via journalctl on server.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace complex dashboard (11 stat cards, token stats, model breakdown,
recent logs, advanced filters) with clean 3-card PLN cost view,
usage by type, user ranking, company ranking, and daily history.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace anonymized metadata ("45 chars") with real topic categories
(O firmach, Szukanie kontaktu, O wydarzeniach, etc). Remove empty
conversion stats, UTM sources, avg message length. Keep feedback
with ratings in compact two-column layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace complex Problem Score tables and remediation metrics with
two clear sections: "Members needing help" (actionable alerts with
buttons) and "Technical problems" (collapsed, for developer).
Removes ~200 lines of unused scoring/remediation code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Paths tab (entry/exit pages, transitions, drop-off) provided little
actionable value for association admin. Session length distribution
moved to Overview as compact card layout. Menu: 6 tabs -> 5.
Old /paths URL redirects to /overview.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zombie sessions (browser tab left open for days) were inflating
duration-based scores. LEAST(duration_seconds, 3600) per session
ensures only active time counts toward engagement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hovering over the activity bar shows breakdown: sessions, pages,
clicks, time, conversions, searches with weights and final score.
Column header explains what the metric measures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 3-section active/at-risk/dormant design with one clear table
showing all members sorted by activity level. Green/yellow/gray bars,
human-readable last login dates, inactive users dimmed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace single 50-row table with Active/At Risk/Dormant sections.
Remove noisy WoW% column and sparklines, add human-readable last activity.
Score displayed as colored bar instead of abstract number.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Alert improvements:
- "Send welcome email" button on never-logged-in alerts (sends activation
email with 72h reset token)
- "Reset password" button on reset-no-effect and repeat-resets alerts
- Buttons show status: sending → sent/error, prevent double-clicks
- New POST /admin/analytics/send-welcome/<user_id> endpoint
Companies needing attention:
- New section on Overview tab listing active companies with incomplete
profiles (missing description, contact, website, address, logo)
- Sorted by number of issues, shows quality badge and edit link
- Checks logo file existence on disk for webp/svg/png/jpg
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pass search_query_id to search results template
- Add POST /api/analytics/search-click endpoint to update SearchQuery
with clicked_result_position, clicked_company_id, time_to_click_ms
- Add data-position and data-company-id attributes to company cards
- Add JS using navigator.sendBeacon for non-blocking click tracking
- Fix content engagement labels: "nowych (30 dni)" instead of "opublikowanych"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Open rate now shows percentage of active members who read at least one
piece of content, capped at 100%. Previously showed inflated numbers
because it counted reads of older content against only recent publications.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Company pages use /company/<id> paths (not slugs). Updated _humanize_path
to try numeric ID lookup first, and fixed company popularity query to
match only /company/<digits> paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Dashboard admin widget: compact KPI cards (active/total members with
progress bar, sessions, security alerts, never-logged users)
2. Overview KPI: first card shows X/Y members with progress bar and %
3. Feature adoption chart: which portal modules are used by what % of
members (NordaGPT, Forum, Search, Calendar, B2B, News, Companies)
4. Event comparison table: views, unique viewers, RSVP count per event
in the last 60 days - helps plan better events
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Event paths like /kalendarz/29 were matched by the /kalendarz/
prefix before reaching the dynamic event title lookup. Reorder
to check dynamic patterns (event ID, company slug) first.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The refactor to _kpi_for_period() removed the local variables but
the return dict still referenced them. Replace with the kpi dict.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. KPI cards show trend arrows (▲▼ X%) comparing current vs previous period
2. Raw paths replaced with human-readable names throughout Pages and Paths tabs:
- /company/pixlab-sp-z-o-o → PixLab sp. z o.o.
- /kalendarz/45 → Spotkanie z posłami (event title from DB)
- /login → Logowanie, /dashboard → Panel użytkownika etc.
3. Bounce rate threshold adjusted (85%+ warning instead of 70%)
with tooltip explaining 70-85% is normal for membership portals
4. Column headers changed from technical (Ścieżka, Exit rate) to
user-friendly (Strona, Wsp. wyjścia)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add EXCLUDED_PATH_CONTAINS patterns to catch security scanners using
varied paths (.php, .env, wp-includes, aws-config, phpinfo etc.)
that bypass the prefix-based filter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add KPI stat cards to Overview tab (active users, sessions, pageviews, bounce rate)
- Filter technical paths from Pages and Paths tabs (/sw.js, /robots.txt, /.git/, /.env, etc.)
- Cap time_on_page at 30min to exclude outlier tabs left open
- Format time as human-readable (Xm Ys) instead of raw seconds
- Mask security tokens in unused pages list (/reset-password/*** etc.)
- Fix Polish labels (period display: "7 dni" instead of "week")
- Add percentages to logged/anonymous donut chart legend
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jsdelivr.net returns 503 from production network (behind FortiGate).
Downloaded Chart.js 4.4.7 UMD bundle locally to eliminate CDN dependency.
Updated all 4 templates that used the CDN link.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Chart.js <script src> was placed between {% endblock %} content and
{% block extra_js %}, causing "Chart is not defined" error. Moved to
{% block head_extra %} so it loads in <head> before the JS code runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>