- POST /konto/avatar: upload, center-crop to square, resize 300x300
- POST /konto/avatar/delete: remove file and clear DB
- dane.html: interactive avatar editor with hover overlay
- person_detail.html: show photo if available, fallback to initials
- Migration 070: avatar_path column on users table
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New column: users.notify_email_messages (default true)
- Send email via MS Graph when someone receives a private message
- Toggle in /konto/prywatnosc to enable/disable email notifications
- Email includes message preview, sender name, and direct link
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- _tab_problems: 750 queries → ~10 batch queries with GROUP BY
- _tab_engagement: 2550 queries → ~12 batch queries, sparkline in 1 query
- user_insights_profile: 60+ queries → batch trend (2 queries), bot filtering on all metrics
- Stat cards exclude UNAFFILIATED, dormant excludes never-logged-in users
- Engagement status: never-logged=dormant, login<=7d+score>=10=active, 8-30d=at_risk
- Badge CSS: support both at-risk and at_risk class names
- Problems table: added Alerts and Locked columns
- Security alerts stat card in Problems tab
- Back link preserves tab/period context
- Trend chart Y-axis dynamic instead of hardcoded max:30
- Timeline truncation info when >= 150 events
- Migration 080: composite indexes on audit_logs and email_logs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add is_bot column to user_sessions with backfill from user_agent patterns
- Update analytics_daily trigger to skip bot sessions
- Recalculate 90 days of analytics_daily without bot contamination
- Replace cumulative failed_login_attempts with time-based audit_logs queries
- Switch engagement score from linear (capped at 100) to log2 scale
- Expand section_map from 9 to 17 categories (~95% traffic coverage)
- Exclude robots.txt, sitemap.xml etc from page view tracking
- Add bot filter to all overview, pages, paths, and engagement queries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Migration 064 fixes 12 records in company_websites table missing https://
- Added ensure_url filter to w.url in contact bar template as safety net
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add /admin/portal-seo to run SEO audits on nordabiznes.pl
using the same SEOAuditor used for company websites.
Tracks results over time for before/after comparison.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Automated discovery using Brave Search API to find company websites,
scrape verification data (NIP/REGON/KRS/email/phone), and present
candidates with match badges in the data quality dashboard.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract 12-field completeness scoring to utils/data_quality.py service
- Auto-update data_quality_score and data_quality label on company data changes
- Add /admin/data-quality dashboard with field coverage stats, quality distribution, and sortable company table
- Add bulk enrichment with background processing, step selection, and progress tracking
- Flow GBP phone/website to Company record when company fields are empty
- Display Google opening hours on public company profile
- Add BulkEnrichmentJob model and migration 075
- Refactor arm_company.py to support selective steps and progress callbacks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a per-company setting to display logos on dark background,
useful for logos with white text or light-colored elements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add document management routes (upload, download, soft-delete) to board blueprint,
link BoardDocument to BoardMeeting via meeting_id FK, add documents section to
meeting view template, and include import scripts for meeting 2/2026 data and PDFs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Migration 071: Add cached_posts (JSONB) and posts_cached_at to social_media_config
- Service: get_cached_posts() and save_all_posts_to_cache() methods
- Route: New POST endpoint to save posts cache, pass cached data to template
- Template: Render cached posts+charts instantly on page load from DB,
save to DB after "Load all" or "Refresh", remove AJAX auto-load
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds bidirectional visibility control: published posts can be switched
between public (live) and draft (debug/admin-only) mode via Facebook
Graph API. Includes is_live column, status indicator, and toggle buttons.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Social Publisher now supports multi-company FB publishing via OAuth.
Each company can connect its own Facebook page through the existing
OAuth framework. Includes discover-pages/select-page endpoints,
per-company settings UI, and publishing_company_id on posts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds editable admin notes to company edit modal in admin panel,
with visual indicator (pencil icon) in companies table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brave Search matched unrelated companies by name token (e.g. VINDOR matched
vindorclothing, vindormusic, beautybyneyador). Social media profiles are now
sourced only from website scraping and manual admin entry.
- Disabled BraveSearcher initialization and call in audit_company()
- Removed Brave Search step from audit progress animation
- Updated missing profile message with explanation and link to profile editor
- Added migration 071 to clean up existing brave_search entries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin panel module for publishing posts on NORDA chamber Facebook page.
Includes AI content generation (Gemini), post workflow (draft/approved/
scheduled/published), Facebook Graph API publishing, and engagement tracking.
New: migration 070, SocialPost/SocialMediaConfig models, publisher service,
admin routes with AJAX, 3 templates (list/form/settings).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow company owners, managers, and admins to hide specific profile
sections from visitors. Hidden sections remain visible to authorized
users with a "Ukryta" badge. Includes migration, API endpoint,
edit UI tab, and conditional rendering for all 15 profile sections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add company_website_id FK to CompanyWebsiteAnalysis, extract audit cards
to Jinja macro, render per-website under each banner with fallback for
sites without audit data. Google Rating stays at company level.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Six types: website (blue), store (green), booking (purple), blog (orange),
portfolio (pink), other (gray). Each type has unique icon, color in contact
bar and banner section, and tooltip with site description.
Form edit adds type selector dropdown per website row.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migration 067 copied comma-separated URLs as single records.
067b splits them into individual rows and syncs companies.website.
Banner now uses primary from relationship instead of company.website.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add CompanyWebsite model with label, is_primary flag, and backward
compatibility sync to company.website. Dynamic form in company edit,
separate buttons in contact bar, additional banners in detail view.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add image_url column to NordaEvent model with migration 066.
Display event banner image above description in event detail page.
Include converted WebP image for Lean breakfast event (2026-02-20).
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>
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>
Add 4 quick-win features to GBP dashboard:
- "Poproś o opinię" button with writeAReviewUri from Places API
- "Pokaż trasę" button with directionsUri
- Open/Closed badge showing business status at audit time
- NAP comparison table (Name, Address, Phone) vs Google data
New DB columns: google_maps_links (JSONB), google_open_now (BOOLEAN)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Google replaced First Input Delay (FID) with Interaction to Next Paint
(INP) as a Core Web Vital in March 2024. This renames the DB column
from first_input_delay_ms to interaction_to_next_paint_ms, updates the
PageSpeed client to prefer the INP audit key, and fixes all references
across routes, services, scripts, and report generators. Updated INP
thresholds: good ≤200ms, needs improvement ≤500ms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route passes 16 new fields from DB (technical SEO, meta tags, structured
data, performance) plus CrUX/security/image metrics. Template shows new
sections: Meta Tags & Content, CrUX Field Data, Security Headers (score
X/4), Image Optimization (% modern formats), and 9 new Technical SEO
checklist items. Migration 059 adds 16 columns for persisting live data.
AI service now saves CrUX/security/image data to DB during analysis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New files:
- oauth_service.py: Shared OAuth 2.0 service supporting Google and Meta
providers with token exchange, refresh, and storage
- database/migrations/058_oauth_tokens.sql: oauth_tokens table with
company/provider/service unique constraint
- blueprints/api/routes_oauth.py: OAuth API endpoints for connect,
callback, status, and disconnect flows
Supports:
- Google OAuth (GBP Business Profile, Search Console)
- Meta OAuth (Facebook Pages, Instagram)
- CSRF state validation, token refresh, expiry tracking
- Per-company token storage with active/inactive status
Requires .env config:
- GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET (Google APIs)
- META_APP_ID, META_APP_SECRET (Facebook/Instagram)
- OAUTH_REDIRECT_BASE_URL (default: https://nordabiznes.pl)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store previous analysis before regeneration and show comparison table
with priority breakdown, new/removed actions diff.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Gemini AI integration to SEO, GBP, and Social Media audits that
generates contextual analysis summaries and prioritized action items
with ready-to-use content (Schema.org, meta descriptions, social posts,
GBP descriptions, review responses, content calendars).
New files:
- audit_ai_service.py: Central AI service with caching (7-day TTL)
- blueprints/api/routes_audit_actions.py: 4 API endpoints
- database/migrations/056_audit_actions.sql: 3 new tables
- templates/partials/audit_ai_actions.html: Reusable UI component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds user_companies table with BEFORE/AFTER triggers to sync primary
company to users.company_id. Dashboard shows all user's companies with
edit buttons. Company edit routes accept optional company_id parameter.
Admin API endpoints for managing user-company associations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add BoardMeeting model with JSON fields for flexible data storage
- Add migration 049_board_meetings.sql
- Add routes for creating, editing, viewing meetings
- Add publish workflows for agenda and protocol
- Add templates: meetings_list, meeting_form (with tabs), meeting_view
- Support for: agenda items, attendance tracking, proceedings
- Pre-filled defaults for chairperson, secretary, location
- Quorum calculation (9/16 for majority)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add @rada_member_required decorator for access control
- Add BoardDocument model for storing protocols and documents
- Create document upload service (PDF, DOCX, DOC up to 50MB)
- Add /rada/ blueprint with list, upload, download endpoints
- Add "Rada" link in navigation (visible only for board members)
- Add "Rada" badge and toggle button in admin user management
- Create SQL migration to set up board_documents table and assign
is_rada_member=True to 16 board members by email
Storage: /data/board-docs/ (outside webroot for security)
Access: is_rada_member=True OR role >= OFFICE_MANAGER
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add access_level field to norda_events (public, members_only, rada_only)
- Add is_rada_member field to users table
- Add can_user_view() and can_user_attend() methods to NordaEvent model
- Update calendar routes to filter events by user permissions
- Add access_level dropdown to admin event form
- Rada Izby events only visible to designated board members
- Regular member meetings visible to all NORDA members
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Benefit and BenefitClick models for tracking affiliate offers
- Create /korzysci blueprint with admin-only access (test mode)
- Add admin panel at /admin/benefits for managing offers
- Include WisprFlow as first benefit with branded link ref.wisprflow.ai/norda
- Add QR code support for printed materials
- Track clicks with user attribution and analytics
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace ~170 manual `if not current_user.is_admin` checks with:
- @role_required(SystemRole.ADMIN) for user management, security, ZOPK
- @role_required(SystemRole.OFFICE_MANAGER) for content management
- current_user.can_access_admin_panel() for admin UI access
- current_user.can_moderate_forum() for forum moderation
- current_user.can_edit_company(id) for company permissions
Add @office_manager_required decorator shortcut.
Add SQL migration to sync existing users' role field.
Role hierarchy: UNAFFILIATED(10) < MEMBER(20) < EMPLOYEE(30) < MANAGER(40) < OFFICE_MANAGER(50) < ADMIN(100)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When admin proposes changes from KRS/CEIDG registry, the application
now goes to 'pending_user_approval' status. User must review and
accept/reject proposed changes before final approval.
Changes:
- New status: pending_user_approval
- New fields: proposed_changes, proposed_changes_at, proposed_changes_by_id
- Admin endpoint: POST /admin/membership/<id>/propose-changes
- User endpoints: GET/POST /membership/review-changes/<id>/accept|reject
- New template: templates/membership/review_changes.html
- Migration: 043_membership_proposed_changes.sql
Workflow: submitted → under_review → pending_user_approval → under_review → approved
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement full online membership application workflow:
- 3-step wizard form with KRS/CEIDG auto-fill
- Admin panel for application review (approve/reject/request changes)
- Company data update requests for existing members
- Dashboard CTA for users without company
- API endpoints for NIP lookup and draft management
New files:
- database/migrations/042_membership_applications.sql
- blueprints/membership/ (routes, templates)
- blueprints/admin/routes_membership.py
- blueprints/api/routes_membership.py
- templates/membership/ and templates/admin/membership*.html
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove confusing "Zweryfikowano 2x | Jakość: 100%" badge
- Create AiEnrichmentProposal model for pending AI suggestions
- Modify AI enrichment to create proposals instead of direct saves
- Add approve/reject API endpoints for proposals
- Update frontend to show approval buttons after AI analysis
- Proposals expire after 30 days if not reviewed
The workflow now requires owner/admin approval before AI-generated
data is applied to company profiles. This prevents unwanted data
from being automatically added.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>