Previously only SUPERADMIN could access audit pages (SEO, GBP,
Social Media, IT). Now MANAGER+ of a company can view audits for
their own company. Route-level can_edit_company() check still
restricts to own company only.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Person profiles (/osoba/, /profil/) now require membership
- Company detail shows limited "business card" for guests: name, logo,
category, short description — full content hidden behind membership CTA
- Banner "Złóż deklarację członkowską" for guests on company page
- Edit/AI buttons hidden for guests
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>
URLs in messages are now automatically converted to clickable links
opening in a new tab. Works for both old plain-text and new Quill
HTML messages. Uses linkify Jinja2 filter that only processes text
nodes outside existing <a>/<img> tags.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use stopImmediatePropagation + capture phase to prevent Quill's
built-in clipboard handler from also inserting the image as base64.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace plain textarea with Quill editor in compose and reply forms
- Support Ctrl+V paste of screenshots directly into message body
- Image toolbar button for file picker upload
- New endpoint POST /api/messages/upload-image for inline images
- Content sanitized via sanitize_html (bleach) with img tag support
- Messages rendered as HTML (|safe) instead of plain text
- Links clickable, images displayed inline in message body
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ICS export, RSS feed, and admin creation now correctly use
external_source (e.g. "Agencja Rozwoju Pomorza") as the organizer
instead of defaulting to "Norda Biznes" for external events.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Downloads page text and images from external event URLs so Claude
can visually analyze posters/banners for location, times, and other
details not present in page text (e.g. venue address in graphics).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Filter label hidden when no external events exist. Shows count
like "Pokaż zewnętrzne (3)" when they do.
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>
Three public feeds: /feed/events.xml (upcoming events),
/feed/news.xml (announcements), /feed/pej.xml (nuclear news).
RSS 2.0 format with KIG custom fields (thumbnail, datawydarzenia).
RSS discovery links added to base.html head.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added description_full, core_values, services_offered, and
technologies_used to the AI context builder. Previously only
description_short and founding_history were used by NordaGPT.
Added "Wykorzystywany przez NordaGPT" hints to all relevant fields
in the company edit form so users know their content feeds the AI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CDN (cdn.jsdelivr.net) was being blocked, causing all WYSIWYG editors
to fail silently — description, history, values, and services fields
were not editable. Now served from static/js/vendor/ like D3 and Chart.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allows company managers to set or correct the founding year. Field is
read-only when the year comes from KRS/CEIDG registry data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ICS format requires plain text (not HTML) in DESCRIPTION field and
lines must not exceed 75 octets per RFC 5545. This fixes "preview
unavailable" when importing ICS into Outlook/macOS Calendar.
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>
The actual analytics code in app.py had no bot filtering — all sessions
(including scanners, crawlers, empty UAs) were saved as is_bot=False.
Added the same 25+ pattern bot filter that was in utils/analytics.py.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
utils/analytics.py and utils/middleware.py are not used for page tracking.
The real analytics code is in app.py:get_or_create_analytics_session().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows detected display-mode, navigator.standalone, and PWA cookies
as a small green text at bottom of screen. Only visible for admin users.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frontend now sends pwa_display cookie with the actual detected mode
(standalone/minimal-ui/fullscreen/browser/unknown/ios-standalone).
Backend logs this to diagnose why WebAPK detection fails.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Chrome WebAPK may not report display-mode: standalone. Added fallback
checks: minimal-ui, android-app:// referrer, and inverse browser mode
detection (if browser mode is supported but not matched, we're in PWA).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cookie pwa_mode=1 is set by JS after page load, so it's not available
on the first request that creates the session. Now also check on
subsequent requests and update is_pwa=True retroactively.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Purple "PWA" badge next to browser name when session was from installed
PWA app. Also reflected in browser grouping as "Chrome Mobile (PWA)" etc.
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>
The sort direction check was done AFTER clearing all sort classes,
so it always read false and defaulted to descending. Now reads the
current state before clearing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 6 columns clickable: # and numeric columns default desc,
name defaults asc, last login sorts by date value.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Events shown as red 📅(N) above bars with attendee count
- Monday bars have dashed left border as week separator
- Weekend bars (Sat/Sun) in gray to distinguish from weekdays
- Hover tooltip shows event title and attendee count
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each group-by view now has clickable column headers with sort arrows,
allowing sorting by name, sessions, total duration, and total pageviews.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clickable column headers with sort arrows (▲▼) for all 6 columns.
Group tabs: "Wg użytkownika", "Wg urządzenia", "Wg przeglądarki" show
summary with session count, total duration and total pageviews per group.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bar area now has fixed 160px height with a wrapper div, so bars are clearly
visible even at low values. Added gradient fill and minimum 5% height for
non-zero days. Value labels are bolder.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
"Zapisano ✓" (green) for events user is attending, with hover changing to
"Wypisz się" (red). "Zapisz się" (blue) for events not yet joined.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Company names like "Portal", "Joker", "Wakat" are also common Polish words
and cause false positive matches in event descriptions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Name linking now handles Polish declensions (Iwonę/Iwoną/Iwony → Iwona)
using stem-based regex matching. ICS and Google Calendar exports now include
full event description, speaker name, and properly formatted newlines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>