Add 5 new SQLAlchemy models (Conversation, ConversationMember, ConvMessage,
MessageReaction, MessagePin) and extend MessageAttachment with conv_message_id FK.
Migration 091 creates all tables with indexes, FKs, and grants.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dodano pole previous_years_debt w modelu Company. Kolumna widoczna w widoku
rocznym składek — kliknięcie kwoty otwiera pole edycji. Legenda zaktualizowana.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added chamber_role column to User model (prezes, wiceprezes, czlonek_rady, komisja_rewizyjna, sad_kolezenski)
- Migration 089 sets roles for all known members from norda-biznes.info/wladze-izby
- Role badges on user profile, person detail, and company contact persons
- New page /izba/wladze showing all chamber authorities grouped by organ
- Color-coded badges: gold (prezes), blue (wiceprezes), green (rada), purple (komisja), gray (sąd)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Search bar in inbox/sent: filters by subject, content, sender/recipient
- Group chats: create named or ad-hoc groups with Norda members
- Group roles: owner, moderator, member with permission hierarchy
- Group management: add/remove members, change roles
- Photo avatars in message list (fallback to initials)
- Unread count API extended to include group messages
- Migration 088: message_group, message_group_member, group_message tables
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Forum: add @forum_access_required to ALL public routes (read+write)
- Reports: add @member_required to all report routes
- Announcements: add @member_required to list and detail
- Education: add @member_required to all routes
- Calendar: guests can VIEW all events but cannot RSVP (public+members_only)
- PEJ and ZOPK remain accessible (as intended for outreach)
UNAFFILIATED users (registered but not Izba members) are now properly
restricted from internal community features.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
External events from partner organizations (ARP, KIG, etc.) can now
be added to the calendar with distinct visual treatment:
- Grey badge "ZEWNĘTRZNE" and muted date box in list view
- Grey color in grid view with border accent
- "Jestem zainteresowany" instead of "Zapisz się" (no commitment)
- Prominent "Przejdź do rejestracji" button linking to external organizer
- "Zainteresowani" section instead of "Uczestnicy"
- Toggle filter "Pokaż zewnętrzne" with localStorage persistence
- Admin form checkbox to mark events as external
New fields: is_external, external_url, external_source on NordaEvent.
Migration: 086_external_events.sql
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds organizer_name and organizer_email columns to NordaEvent with
defaults (Norda Biznes). ICS calendar exports now use per-event
organizer instead of hardcoded value.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds file attachment capability to NordaEvent model (attachment_filename,
attachment_path columns). Admin can upload PDF/DOCX when creating events.
Users see a download link on the event detail page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. PWA: frontend sets pwa_mode=1 cookie when in standalone mode,
backend reads it and stores is_pwa=True in user_sessions.
Migration 063 adds is_pwa column.
2. Bot filter: added 13 new patterns (GoogleAssociationService,
Censys, Palo Alto, Netcraft, fasthttp, Apple WebKit prefetch,
etc.) + flag empty/bare "Mozilla/5.0" UA as bot. This eliminates
~800 false sessions from analytics.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users can now pin favorite conversations (shown at top with section header)
and rename them with inline editing. Adds is_pinned, pinned_at, custom_name
columns to ai_chat_conversations table.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
External monitoring via UptimeRobot (free tier) with internal health
logger to differentiate ISP outages from server issues. Includes:
- 4 new DB models (UptimeMonitor, UptimeCheck, UptimeIncident, InternalHealthLog)
- Migration 082 with tables, indexes, and permissions
- Internal health logger script (cron */5 min)
- UptimeRobot sync script (cron hourly) with automatic cause correlation
- Admin dashboard /admin/uptime with uptime %, response time charts,
incident log with editable notes/causes, pattern analysis, monthly report
- SLA comparison table (99.9%/99.5%/99%)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded email check for audit panels with role-based
SUPERADMIN check. ADMIN retains all management capabilities but
SUPERADMIN adds access to technical audits (SEO, IT, GBP, Social,
Access Control).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
- 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>
Model had columns (overall_score, on_page_score, etc.) that didn't exist
in the migration. Updated model and templates to match the actual table.
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>
Previously all new permission records had contacts/social/analytics
disabled by default regardless of role. Now MANAGER+ users get
full permissions automatically.
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>
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>
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>
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>
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>
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 @role_required to 2 missing routes (krs_api PDF download, zopk milestones)
- Add role-based menu visibility in admin bar (hide Users, Security, Benefits,
Model Comparison, Debug from OFFICE_MANAGER users)
- Inject SystemRole into Jinja2 context processor for template role checks
- Replace is_admin checkbox with role select dropdown in user creation form
- Migrate routes.py and routes_users_api.py from is_admin to SystemRole-based
role assignment via set_role()
- Add deprecation notice to is_admin database column
- Add 23 RBAC unit tests (hierarchy, has_role, set_role, permissions)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>