The logo path was hardcoded to .webp even when the actual file was .svg,
causing broken image display for SVG logos like Orlex Design.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Logo check only looked for .webp files, missing SVG logos like
Orlex Design. Now checks both extensions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CEIDG enrichment now creates individual CompanyPKD records from the PKD
list, matching the pattern used by KRS enrichment for consistency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KRS API returns two date formats for za_okres field:
"01.01.2011 - 31.12.2011" (older) and "OD 01.01.2013 DO 31.12.2013" (newer).
Use regex to extract all date patterns instead of splitting on ' - '.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Map remaining KRS API fields: registration date, company agreement date,
duration, capital currency, OPP status, representation rules, shareholders
(wspólnicy), and financial reports (sprawozdania finansowe).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KRS API returns kontakt_krs with www and email fields. These were not
being mapped to Company.website and Company.email. Now enrichment
extracts these and normalizes the URL (adds https:// prefix, lowercase).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The KRS enrichment function was only mapping forma_prawna, legal_name
and capital. Now maps REGON, address (ulica + nr_domu), city, postal,
primary PKD code on Company model, and NIP if missing. Fixed field
name mismatches: nr_domu (not numer), opis (not nazwa), glowna (not
glowny). City names are title-cased from KRS uppercase format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New admin page at /admin/companies/{id}/detail showing company data,
completeness score, and action buttons for registry data (CEIDG/KRS),
logo fetch, SEO audit, social media audit, and GBP audit.
Includes "Uzbrój firmę" master button for sequential execution.
Company list now links to detail page with "NOWA" badge for recent entries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PDF files: "Otwórz" (inline in browser) + "Pobierz" (download)
DOCX files: "Pobierz" only (browsers can't display DOCX inline)
Removes LibreOffice on-the-fly conversion - simpler and more reliable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use /usr/bin/libreoffice (Gunicorn has limited PATH)
- Set HOME=/tmp (LibreOffice needs writable home dir)
- Handle FileNotFoundError with user-friendly message
- Improve error flash messages in Polish
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DOCX/DOC documents are now converted to PDF using LibreOffice headless
when the user clicks "Otwórz". The converted PDF is cached next to the
original file so subsequent views are instant.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PDF documents now have an "Otwórz" button that opens
the file in the browser's built-in PDF viewer.
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>
Charts now render automatically on page load via AJAX from DB cache
(no click needed). Info bar above charts shows post count, cache date,
and hint to refresh. GET cache endpoint now returns cached_at date.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes slow page load for non-admin users (919KB inline JSON).
Route now sends max 10 posts inline with total_count metadata.
New GET endpoint serves full cache via AJAX for Analityka button.
loadAllFbPosts tries DB cache first (instant), falls back to FB API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin's _get_user_company_ids returns None meaning all companies,
but iterating over None gave empty list. Now falls back to fb_stats keys.
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>
Previously get_page_posts returned a flat list with no pagination support.
Now returns dict with posts and next_cursor, enabling infinite scrolling
through all Facebook page posts via the after query parameter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display last 10 posts from connected Facebook page with engagement
data (likes, comments, shares, reactions). On-demand insights button
loads impressions, reach, engaged users, and clicks per post.
In-memory cache with 5-min TTL prevents API rate limit issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- select-page now saves page token to SocialMediaConfig.access_token
- _get_publish_token prefers config page token over OAuthToken
- Prevents breakage when OAuth reconnect overwrites OAuthToken with USER token
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Social Publisher: blue gradient panel with followers, engagement,
completeness, contact pills, and refresh button.
Integracje: "Synchronizuj dane" button next to Disconnect for Facebook.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Batch-query confirmed attendee counts per event and display as
subtle cyan number with people icon in event meta line.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After connecting a FB page via OAuth, automatically fetch page stats
(followers, engagement, bio) from Graph API and persist to
CompanySocialMedia table. Adds manual refresh endpoint and UI badge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same bug as discover-pages: select-page was using page token to call
me/accounts, which returns empty. Now uses user_access_token from
metadata_json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OAuth integrations page was hardcoded to maciej.pienczyn@inpi.pl.
Now accessible to any user with MANAGER role or higher.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After selecting a FB page, the user token was overwritten with page
token. me/accounts requires user token to list pages, so page discovery
returned empty. Now stores user_access_token in oauth metadata_json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Facebook Graph API returns error 100 when setting is_published=false on
already-published posts. Replaced "Zmień na debug" with "Usuń z Facebooka"
which deletes the post from FB and resets status to draft for re-publishing.
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>
- New force_live parameter in publish_post() overrides config.debug_mode
- Red "Publikuj na żywo" button with confirmation dialog
- Visible when company has debug_mode enabled
- Works for new posts, drafts, and re-publishing debug-published posts
- "Publikuj teraz" shows "(debug)" label when in debug mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Query company_social_media table for valid profiles (Facebook, Instagram,
LinkedIn, YouTube, etc.) and pass them as context to AI prompts.
Member spotlight posts now include social media links at the end.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass user_id, company_id, and feature name to generate_text() calls:
- 'social_publisher_content' for post content generation
- 'social_publisher_hashtags' for hashtag generation
All costs logged to AIUsageLog and AIAPICostLog with user/company context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two render_template calls were missing ai_models/default_ai_model
causing UndefinedError on template render (500 error).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 models available: Gemini 3 Flash (default, cheap), Gemini 3 Pro
(best quality, 4x cost), Gemini 2.5 Flash (stable previous gen).
Model selection applies to both content and hashtag generation.
Shows which model was used after generation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove hashtag instructions from AI prompts (content-only generation)
- Add _split_hashtags() to extract any hashtags AI still includes
- generate_content() now returns (content, hashtags, model) tuple
- Prevents duplicate hashtags when publishing (content + hashtags field)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6 tones: Profesjonalny (default), Przyjazny, Oficjalny, Entuzjastyczny,
Informacyjny, Inspirujący. Tone instruction is appended to the AI prompt.
Dropdown appears next to "Generuj AI" button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New generate_hashtags() method in SocialPublisherService
- New /social-publisher/generate-hashtags AJAX endpoint
- "Generuj hashtagi AI" button next to hashtags field
- Small print info about AI engine (Gemini 3 Flash) with note
about future model selection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix AttributeError: Company.city -> Company.address_city in get_company_context
- Default publishing_company_id to first available company when not selected
- Replace alert() with inline error message for AI generation failures
- Return user-friendly error messages instead of internal exceptions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Managers can now access Social Publisher to create posts and configure
Facebook only for their assigned company. Admins see all companies.
Added nav menu link visible for MANAGER+ role.
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>
- Check content-type before parsing JSON in runAudit() to show
helpful message when NPM proxy times out (returns HTML)
- Replace abort(404) with jsonify in audit trigger endpoint
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>
Instead of auto-selecting one logo candidate, the service now downloads
up to 6 candidates and displays them in a gallery. User sees all options
(including their current logo if exists) and picks the best one.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a company already has a logo, the fetch shows both old and new
logos side-by-side so the user can choose to keep or replace. Uses
preview file mechanism (slug_preview.webp) with confirm/cancel actions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New "Pobierz logo" button on company detail page that automatically
downloads and converts company logos from their websites. Uses 4-strategy
approach (DOM scan, meta tags, favicon, Google API fallback) with
animated progress overlay showing 6 steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CEIDG enrichment was broken due to key mismatches (expected adres_ulica but API
returns adresDzialalnosci.ulica), writes to non-existent columns (address_building,
address_postal_code), and missing saves for ceidg_id/status/owner/PKD fields.
Now fetches full details via /firma/{id} endpoint (Phase 2) for complete data
including PKD list, correspondence address, and succession manager.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>