- Display up to 3 next events with RSVP status instead of just one
- Add import script for WhatsApp Norda group data (Feb 2026):
events, company updates, Alter Energy, Croatia announcement
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Employees clicking "Edytuj profil" now see a modal with their company's
management team contacts instead of being sent to an edit form they can't use.
Managers and admins continue to access the edit form directly. Direct URL
access to /firma/edytuj is also guarded with redirect + flash message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The analyze_roadmap_with_ai() was using google.generativeai directly
which bypasses API key configuration. Switch to GeminiService which
has the key pre-configured via init_gemini_service().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New analyze_roadmap_with_ai() function sends existing milestones and recent
knowledge facts to Gemini for comprehensive analysis. Returns new milestone
suggestions, status update recommendations, and identified roadmap gaps.
Adds PATCH endpoint for milestone status updates and tabbed UI modal.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The JS was fetching from /api/zopk/milestones (non-existent) instead of
/admin/zopk-api/milestones (actual endpoint). This caused "Unexpected
token '<'" errors as the 404 HTML page was parsed as JSON.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds "Zarządzaj" edit links next to each section header, visible only
to admin users. Links point to the corresponding admin panels (knowledge,
timeline, news, dashboard). Also adds a "Panel ZOPK" button in the hero.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Role field stores uppercase 'ADMIN' (from SystemRole enum). Use
is_admin boolean property which is synced by set_role() for reliable checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4 new features visible only to admin (role=='admin'):
- Homepage: "Czy wiesz, że?" widget with 3 random high-confidence facts
- /zopk: Knowledge stats, top entities, key numeric facts, fact type distribution
- /zopk: Dated facts timeline (CSS-only vertical timeline)
- /zopk: D3.js entity co-occurrence graph with slider control
No migrations needed - read-only SELECT queries only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Google deprecated text-embedding-004 on v1beta API (returns 404 NOT_FOUND).
Migrated to gemini-embedding-001 with output_dimensionality=768 to maintain
compatibility with 412 existing embeddings in the database.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical bug: CSS selector pipeline stopped at first match even if element
had 0-94 chars of text (empty <article> tags on wnp.pl, polskieradio24.pl,
portalkomunalny.pl, weekendfm.pl). Now skips elements with <200 chars text.
Added domain-specific selectors for: radiogdansk.pl (Elementor),
nadmorski24.pl (Joomla), portalkomunalny.pl, weekendfm.pl, globenergia.pl,
polskieradio24.pl.
Added 9 domains to SKIP_DOMAINS: wnp.pl (paywall), tvp.pl/tvp.info (JS SPA),
gp24.pl/strefaobrony.pl/dziennikbaltycki.pl (Cloudflare), pap.pl,
obserwatorfinansowy.pl, cire.pl (block bots).
Moved 'article' lower in default selectors to avoid matching empty tags first.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Articles with only 100-458 chars were passing validation but contained
metadata/teasers instead of full article text, causing all knowledge
extraction to fail ("Treść za krótka do ekstrakcji"). The 500-char
minimum better aligns with the 200-token chunking requirement (~800 chars).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Long-running Gemini extractions (30-120s per article) caused SSE
connection timeout. Now runs extraction in a thread and sends
heartbeat updates every 10s to keep the connection alive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin was confused by red "Błędy: 2" when scraping/extraction had
expected issues (403, content too short). Changes:
- All scraper/extractor messages translated to Polish
- HTTP 403/404/429 get specific descriptive messages
- Expected failures shown as yellow "Pominięte" instead of red "Błędy"
- "No chunks created" → "Treść za krótka do ekstrakcji"
- Summary label "Błędy" → "Pominięte"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The scrape stream used 'type' field and lacked 'percent', 'message',
'details' - format incompatible with the shared SSE modal handler.
Aligned to match knowledge stream format: status/percent/message/details.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SSE scrape stream was filtering on ZOPKNews.content_scraped which
doesn't exist in the model. The correct field is scrape_status with
values 'pending', 'failed', 'scraped', 'skipped'.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flask-Login's current_user proxy loses context inside generator
functions. Same fix as applied to search stream endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds visual guidance through the 4-step ZOPK news pipeline:
- Enhanced stepper with green checkmarks (done), orange pulsing badges
(needs attention), and gray (inactive) states
- Status banners under each step heading with contextual messages
- Transition banners between steps with action buttons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brave free tier was returning 429 for ~50% of queries due to back-to-back
requests. Added 1.1s delay between queries and retry with exponential
backoff (1.5s, 3s). Heartbeat endpoint exempted from Flask-Limiter and
interval increased from 30s to 60s to reduce log noise.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create separate SessionLocal() in run_search() thread instead of sharing
main thread's session (SQLAlchemy sessions are not thread-safe). Increase
connection pool_size to 10 with pool_pre_ping for gthread worker support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flask-Login's current_user proxy loses context inside generator
functions, causing 'NoneType' has no attribute 'id' error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace simulated progress animation with Server-Sent Events streaming
that shows actual backend progress in real-time during ZOPK news search.
Prevents timeout errors by keeping the connection alive with heartbeat
events. Old POST endpoint preserved as automatic fallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After refactoring to blueprints, templates still used bare endpoint names
(e.g., url_for('admin_zopk')) instead of prefixed names (e.g.,
url_for('admin.admin_zopk')). While most worked via backward-compat aliases,
api_zopk_search_news was missing from the alias list causing 500 on /admin/zopk.
Fixed 19 template files and added missing alias for api_zopk_search_news.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix uc.company.category → uc.company.category.name on dashboard
- Replace "Więcej" dropdown with direct "Kaszubia" link for non-owner users
- Owner (Maciej) keeps full "Więcej" dropdown with all items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Hide Integracje link in user menu for non-owner users
- Add server-side access check on /konto/integracje route
- Add owner-only visual indicator on the link
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename "ZOP Kaszubia" to "Kaszubia" in More dropdown
- Hide Kontakty, Raporty, Mapa Powiązań from non-owner users
- Add orange dot indicator (.owner-only) for owner-restricted items
- Apply indicator to 5 audit links in admin panel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shown by nginx during gunicorn restart (502/503/504). Auto-refreshes
after 8 seconds. Replaces generic NPM error page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
user_loader was closing the SQLAlchemy session after loading User,
causing lazy-load of company_associations to fail when dashboard template
calls can_edit_company(). Eagerly load associations in user_loader.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin can now set passwords directly via modal with generator (crypto.getRandomValues),
replacing the confirm-dialog flow with a tabbed modal (set password / reset link).
Custom CSS tooltips replace native title="" for instant hover display.
New "Ostatnie logowanie" column shows last_login timestamps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comprehensive rewrite of access control dashboard: role hierarchy table,
full function-by-role access matrix (7 columns incl. unauthenticated users),
Rada Izby members section, and all active accounts with Excel-like
collapsible grouping by role. Expand/collapse all controls included.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Audits (SEO, IT, GBP, Social Media) are now visible only to the
designated audit owner (maciej.pienczyn@inpi.pl). All other users,
including admins, see 404 for audit routes and no audit links in
navigation. KRS Audit and Digital Maturity remain unchanged.
Adds /admin/access-overview panel showing the access matrix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add GBP Performance API integration for visibility metrics (Maps/Search
impressions, call/website clicks, direction requests, search keywords).
Extend Search Console with URL Inspection, Sitemaps, device/country/type
breakdowns, and period-over-period trend comparison. Change OAuth scope
from webmasters.readonly to webmasters for URL Inspection support.
Migration 064 adds 24 new columns to company_website_analysis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix ~190 hardcoded Polish strings missing diacritical characters
across seo_audit.html, gbp_audit.html, social_audit.html
- Fix encoding issue in SEO scraper: requests defaults to ISO-8859-1
when server omits charset, causing mojibake for UTF-8 pages.
Now uses apparent_encoding detection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Audit links (GBP, SEO, Social, IT) now appear on their own line below
contact info and social media buttons for better visual separation.
Also added 'Mój pulpit' back-link for logged-in users.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Logged-in users now see both "Powrót do katalogu" and "Mój pulpit"
links at the top of the company profile page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaced compact single-line company listing with prominent cards featuring
left border accent, larger text, icon buttons, and category display.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, the integrations page only read token status from DB without
attempting refresh, causing "Token wygasł" after 1h of inactivity despite
valid refresh_token. Now get_connected_services() auto-refreshes expired
tokens on page load, matching the behavior already present in audit flows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace simple spinner with 9-step progress stepper showing audit stages
(page fetch, on-page SEO, technical SEO, PageSpeed, local SEO, citations,
content freshness, GSC, score calculation) with simulated timing and
real data enrichment from API response.
Add deterministic "Znalezione problemy" section generated from audit data
with 3 priority levels (critical/important/improvement) covering 24 rules
for SSL, meta tags, sitemap, performance, security headers, and more.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The site was added as a domain property in GSC, not URL prefix.
_normalize_site_url() now tries sc-domain:example.com variant.
Also added ctr/position to top_queries for template display.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SEO dashboard: show step-by-step guide when GSC connected but site
not found in Search Console (instead of generic "connect" CTA)
- Integrations page: add info note about GSC site verification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SEO audit from admin panel uses seo_audit.py (SEOAuditor), not
audit_ai_service.py. Added GSC OAuth enrichment step after audit save.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add GSC columns to DB, persist OAuth data during audits, and render
clicks/impressions/CTR/position with top queries table on the dashboard.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Users with a company can now access /konto/integracje from the user
dropdown menu and from the account settings sidebar navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Company users should connect their own Google/Meta accounts, not admins.
- Add /konto/integracje route for company users (auth blueprint)
- OAuth callbacks now redirect to /konto/integracje
- Template breadcrumb adapts to user vs admin view
- Admin route /admin/companies/<id>/settings kept for admin access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Company settings page with 4 OAuth cards (GBP, Search Console, Facebook, Instagram)
- 3 API service clients: GBP Management, Search Console, Facebook Graph
- OAuth enrichment in GBP audit (owner responses, posts), social media (FB/IG Graph API),
and SEO prompt (Search Console data)
- Fix OAuth callback redirects to point to company settings page
- All integrations have graceful fallback when no OAuth credentials configured
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>