Commit graph

43 commits

Author SHA1 Message Date
Vadym Samoilenko
6ea431bc75 Fix SSE routing: exclude text/event-stream requests from API rewrite
afterFiles ordering was insufficient in Next.js 14 — the catch-all
/api/v1/* rewrite still intercepted SSE requests before route handlers.

Fix: add a `missing` condition on `Accept: text/event-stream` to the
rewrite rule. EventSource always sends this header, so SSE requests now
skip the rewrite entirely and are handled by the existing route handlers
(app/api/v1/ppt/outlines/stream, presentation/stream, jobs/stream).
Normal JSON API requests are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:27:38 +00:00
Vadym Samoilenko
65da74ab13 Fix SSE 500: move API rewrites to afterFiles so route handlers take priority
The flat-array form of rewrites() runs as beforeFiles, intercepting /api/v1/*
requests before Next.js can match route handlers. This caused the SSE stream
endpoints (outlines/stream, presentation/stream, jobs/stream) to be handled
by the buffering HTTP proxy instead of the custom streaming route handlers,
resulting in ECONNRESET → 500 on the browser.

afterFiles rewrites only apply when no matching app/api/ file exists, so
route handlers now win over the backend proxy for all /api/v1/* paths that
have explicit handlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:14:44 +00:00
Vadym Samoilenko
58e738e79b Replace PPTX export pipeline: Puppeteer/python-pptx → PptxGenJS
- New POST /api/generate-pptx route (Next.js) uses PptxGenJS to build
  PPTX directly from the Phase 8 JSON element model — no headless Chrome
- export_utils.py queries DB for slides + layout codes, POSTs payload to
  Next.js, saves binary response to disk (removes python-pptx/Puppeteer)
- Coordinate conversion: px / 96 → inches (1280×720 = 13.333×7.5 in)
- CSS color/font-size parsing (hex, rgb/rgba, px→pt at 0.75pt/px)
- Fallback renderer for slides without a JSON layout schema
- PDF export (Puppeteer) unchanged

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:04:31 +00:00
Vadym Samoilenko
1f5a0c27da Fix SSE proxy: create Next.js route handlers for all streaming endpoints
Next.js rewrites() buffer HTTP responses and drop long-lived connections,
making SSE (text/event-stream) impossible. The backend never even received
the request (no log entry in API, ECONNRESET in web proxy logs).

Create dedicated route.ts files for all 3 SSE endpoints:
- /api/v1/ppt/outlines/stream/[id]
- /api/v1/ppt/presentation/stream/[id]
- /api/v1/ppt/jobs/[job_id]/stream

Each route forwards cookies for auth and returns backend's ReadableStream
directly as a Response, preventing any buffering. Sets X-Accel-Buffering: no
to also disable nginx buffering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 20:43:58 +00:00
Vadym Samoilenko
e360983249 Fix 5 post-Phase8 bugs: SSE crash, custom templates, ordering, persistence, JSON display
- outlines.py: Fix ECONNRESET/socket-hang-up — Depends session closes before
  StreamingResponse generator runs; capture presentation data upfront, use
  async_session_maker() inside inner() for the final DB commit (same pattern as Phase 4)
- useCustomTemplates.ts: Filter null-template items in summary map (crashed on
  presentations without a TemplateModel); use item.layout_count instead of hardcoded 0
- TemplateSelection.tsx: Move custom AI templates section above built-in templates
- presentationGeneration.ts + OutlinePage.tsx: Add selectedTemplateId to Redux so
  template selection persists when navigating away and back to /outline; clearOutlines
  also resets selectedTemplateId for new presentation flows
- DocumentPreviewPage.tsx: Detect JSON file content (table decomposition output) and
  convert to markdown table or pretty-printed code block before passing to MarkdownRenderer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 20:25:28 +00:00
Vadym Samoilenko
df99af91ac Fix migration: move to correct path, update down_revision to c7a3f8e21d4b
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 20:10:36 +00:00
Vadym Samoilenko
ae41562103 Phase 8: Data-driven slide architecture + template management overhaul
Replaces TSX/Babel compilation pipeline with a JSON element model:
- New _do_parse_v2(): 1 LLM call/layout (vs 2) classifies OXML geometry
  elements into placeholder types → JSON stored in layout_code
- SlideRenderer.tsx: renders JSON element model as %-positioned divs,
  no Babel compilation or runtime errors
- parseLayoutSchema.ts: isJsonLayoutCode() / parseLayoutSchema() /
  mergeElementsWithContent() — full JSON schema parsing layer
- useCustomTemplates.ts: transparent dual-format support (JSON + TSX)
  via parsedLayoutToCompiled() adapter

Template management improvements:
- PresentationLayoutCodeModel: +is_enabled (bool) +thumbnail_path (str)
- Migration 005: adds both columns to presentation_layout_codes
- DELETE /master-decks/{id}: hard delete (files + TemplateModel +
  PresentationLayoutCodeModel rows + MasterDeckModel)
- PATCH /template-management/layouts/{db_id}/toggle-enabled: new endpoint
- LayoutData response: +db_id, +is_enabled, +thumbnail_path
- _register_as_template(): stores thumbnail_path + is_enabled per layout

Admin UI:
- /admin/templates/ — list all custom templates with delete
- /admin/templates/[id]/ — layout grid with screenshots + enable/disable
- AdminSidebar: Templates nav item

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 20:05:25 +00:00
Vadym Samoilenko
af95e73806 Fix SSE crash + React layout error boundaries
- documents_loader: skip missing files (print warning + continue) instead
  of raising HTTPException inside SSE generator — prevents "response
  already started" runtime error when temp files are wiped on restart
- V1ContentRender: wrap non-edit mode render in SlideErrorBoundary so
  broken custom layout components show a red placeholder instead of
  crashing the page (React error #62)
- CustomTemplateCard: wrap LayoutPreview in SlideErrorBoundary for the
  same reason — bad compiled TSX from master deck parsing no longer
  crashes the outline template picker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 19:35:27 +00:00
Vadym Samoilenko
5def8f9e84 Phase 7: Apply design system to all admin pages + fix test stubs
Frontend — consistent HSL token usage across remaining pages:
- Users: shared Card, Badge with success/error tokens, h2 typography, animate-fadeIn
- Audit: shared Card, muted-foreground text, animate-fadeIn
- Clients: shared Card, Badge active/inactive, hsl(--primary) icon color
- Storage: shared Card, StatusBadge for status pills, hsl warning/primary
  bars replacing hardcoded amber/blue, all gray text → muted-foreground
- Login: hsl(--surface) bg, hsl(--primary) submit button, brand mark icon,
  animate-scaleIn card entry, hsl(--warning) dev notice

Backend tests — convert print-only stubs to real assertions:
- test_pptx_creator: mkdir, deterministic save path, assert file exists + slide count
- test_gemini_schema_support: direct google.genai client, skipif guard on
  GOOGLE_API_KEY, JSON parse + Pydantic model validation assertions
- test_openai_schema_support: clean skip (OpenAI removed in Phase 6)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 19:01:52 +00:00
Vadym Samoilenko
a74f533043 Fix URL fetch to extract text from JSON response
Backend returns {text, url} object but frontend expected string.
Now properly extracts data.text field.
Fixes [object Object] display issue.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 22:36:34 +00:00
Vadym Samoilenko
fc434ce6a8 Clean up unused import 2026-02-27 22:35:35 +00:00
Vadym Samoilenko
50b4f554d6 Simplify outline error handling
Keep asyncio import for future timeout implementation.
Handle TimeoutError and other exceptions properly.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 22:35:09 +00:00
Vadym Samoilenko
0a5e971bf7 Add timeout protection to outline generation
Prevents socket hang up when LLM is slow or unavailable.
- Timeout: 120 seconds (configurable via OUTLINE_TIMEOUT_SECONDS)
- Returns 504 Gateway Timeout error if exceeded
- Fixes: socket hang up errors in Next.js proxy

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 22:34:26 +00:00
Vadym Samoilenko
8adbc965a4 Parallelize master deck parsing for 2x speedup
BEFORE: Sequential (HTML → React → HTML → React...)
- 25 layouts × 60 sec each = 25 minutes

AFTER: Parallel batching (All HTML together, then all React)
- 25 layouts: HTML batch (2-3 min) + React batch (2-3 min) = 5-6 minutes
- 2x-4x faster depending on Google API concurrency limits

Implementation:
- asyncio.gather() for parallel HTML generation
- asyncio.gather() for parallel React generation
- Maintains error handling per layout

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 22:12:18 +00:00
Vadym Samoilenko
cf7a9ec305 Clean up unused import 2026-02-27 21:50:56 +00:00
Vadym Samoilenko
cf76b8048d Use gemini-2.5-flash-lite for master deck parsing
- Added PARSING_MODEL env var (default: gemini-2.5-flash-lite)
- Master deck parser now uses fast lite model
- 3-4x faster than gemini-3.1-pro: 22 layouts = 8-12 min vs 44-60 min
- Keep gemini-3.1-pro for presentation generation (quality)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 21:50:45 +00:00
Vadym Samoilenko
73d8aa8c7a Increase ARQ job timeout to 90 minutes
Master deck parsing with 20+ layouts requires ~44 LLM calls.
At 60s per call with gemini-3.1-pro = 44-60 minutes total.
Previous 30 min timeout caused failures at layout 19/22.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 21:48:51 +00:00
Vadym Samoilenko
0d616c7a3f Fix slowapi Response parameter issue
Disable headers_enabled to avoid requiring Response parameter.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 20:29:00 +00:00
Vadym Samoilenko
4eb28ae819 Fix RLS session variables syntax
- PostgreSQL SET LOCAL doesn't support parameterized queries
- Use string formatting (safe: user.id is UUID, role is enum)
- Fixes 'syntax error at or near $1' error

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 20:26:03 +00:00
Vadym Samoilenko
b52f2480df Fix Google model name comparison
- Strip 'models/' prefix from Google API response for consistency
- Model names in .env should be without prefix (e.g., gemini-3.1-pro-preview)
- Fixes startup failure when checking model availability

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 20:22:59 +00:00
Vadym Samoilenko
f772097566 Add missing Badge component
Required by StatusBadge component.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 20:17:19 +00:00
Vadym Samoilenko
c5da677986 Apply design system to analytics page
- Updated StatCard to use CSS variables instead of hardcoded colors
- Applied typography classes (caption)
- Added hover shadow transition

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 18:34:56 +00:00
Vadym Samoilenko
4f391a04e8 Complete critical security improvements (P0.5-P0.8)
P0.5: Database Row-Level Security (RLS) - CRITICAL
- Created Alembic migration for RLS policies on all client-scoped tables
- Policies for: presentations, master_decks, brand_configs, slides, templates
- Updated get_async_session to set PostgreSQL session variables
- Multi-tenant isolation now enforced at database level (defense-in-depth)
- Session variables: app.current_user_id, app.user_role

P0.6: Safe Error Messages
- Created safe_exception_handler to prevent info disclosure
- Logs full errors internally with context (user_id, path, method)
- Returns generic "internal error" message to clients
- Preserves HTTPException details (intentional error messages)

P0.7: Security Headers
- Created SecurityHeadersMiddleware with comprehensive headers
- Headers: X-Content-Type-Options, X-Frame-Options, X-XSS-Protection
- CSP, Referrer-Policy, Permissions-Policy, HSTS
- Updated nginx.conf with matching security headers

P0.8: Database Connection Pool Optimization
- Increased pool_size from 5 to 20 connections
- Added max_overflow of 40 for burst traffic
- Enabled pool_pre_ping for connection health checks
- Pool recycle after 1 hour to prevent stale connections
- Configurable via DB_POOL_SIZE, DB_MAX_OVERFLOW, DB_POOL_RECYCLE

All critical pre-launch security tasks complete. System now has:
 CORS protection
 Rate limiting
 Request size limits
 Database-level tenant isolation (RLS)
 Safe error handling
 Security headers
 Optimized connection pooling

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 18:33:58 +00:00
Vadym Samoilenko
c431d4ab45 Implement critical security fixes and modern design system (Pre-launch P0 tasks)
Security Improvements (P0.0-P0.4):
- P0.0: Migrate to Gemini-only AI stack (simplified, single billing)
- P0.1: Fix CORS to restrict allowed origins from env (was *)
- P0.2: Remove hardcoded dev password, require env var
- P0.3: Add rate limiting (slowapi) - 3-10 req/min on sensitive endpoints
- P0.4: Add request size limits (100MB default via middleware)

New Features:
- Unified LLM service with Google Gemini priority
- OXML geometry extractor for layout parsing
- TSX validator for generated React components
- Client ID support in presentation requests with access control
- Configurable LLM/image timeouts via env vars

Modern Design System (P0.9 - partial):
- Enhanced CSS design tokens (primary, semantic colors, shadows)
- Typography scale (h1-h4, body variants, caption)
- Modern animations (fadeIn, slideIn, scaleIn)
- Updated Button component with better variants and hover effects
- Created unified Card and StatusBadge components
- Applied design system to Dashboard and Settings pages

Backend Improvements:
- Master deck parser simplification
- Slide-to-HTML endpoint cleanup (325 lines removed)
- Better error handling in prompts endpoint

Frontend Improvements:
- Settings UI simplified to show only Google/Gemini
- Dashboard uses CSS variables instead of hardcoded colors
- Improved button transitions and hover states

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 18:28:24 +00:00
Vadym Samoilenko
69b18a218f Improve storage purge and fix outline parsing
- Fix image path handling in purge (remove incorrect lstrip)
- Add hard-delete of presentation records from database after file cleanup
- Add debug logging throughout purge process
- Fix outline parsing when LLM returns slides as JSON string
- Fix purge success message to show total files count

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 17:33:27 +00:00
Vadym Samoilenko
1280e40eb2 Fix image generation model and purge logic
- Change NanoBanana Pro model from gemini-3-pro-image-preview to gemini-2.0-flash-exp-image (previous model doesn't exist)
- Purge endpoint now deletes generated images from /app_data/images/ when soft-deleted presentations are purged
- Add purged_images counter to purge response

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:18:34 +00:00
Vadym Samoilenko
8cbe01dfa6 Add project documentation: User Manual and System Administration Guide
PDF documents with Mermaid diagrams, styled with purple theme.
Includes build script for regenerating PDFs from Markdown sources.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:06:28 +00:00
Vadym Samoilenko
ff9cdffc32 Phase 5: Fix export, slide edit, static files; add README
- Fix PPTX/PDF export: Puppeteer URL port mismatch (80 → 3000)
- Fix backend export_utils to use NEXT_INTERNAL_URL env var
- Add Chromium to frontend Dockerfile for Docker-based export
- Fix slide edit socket hang up with asyncio.wait_for() timeouts
- Add FastAPI StaticFiles mounts for /static and /app_data
- Add Next.js rewrite for /static/ to proxy to backend
- Show template thumbnail in master decks admin page
- Add error logging to ReviewWorkflow component
- Add Docker env vars for web service (APP_DATA_DIRECTORY, app_data volume)
- Add project README in English

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 15:40:36 +00:00
Vadym Samoilenko
71ebbf3626 Fix layout-to-screenshot mapping in master deck parser
In layouts mode, screenshots were matched by array index (0,1,2...)
which broke when PPTX had more slideLayouts than actual slides.
Now builds an explicit mapping from slideLayout filename to the
first slide that uses it, so each layout gets the correct screenshot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:46:10 +00:00
Vadym Samoilenko
e8295d6e71 Phase 4: Fix critical bugs, improve document parsing, add vision OCR
- Fix SSE stream 500: use async_session_maker inside StreamingResponse generator
  (Depends session closes when endpoint returns, before streaming starts)
- Fix template application: store template_name in prepare endpoint so worker
  uses the selected custom template instead of defaulting to "general"
- Fix OverlayLoader: replace loading.gif with HamsterLoader component
- Fix parse_mode default: change from "slides" to "layouts" to avoid 70+ layouts
- Update Gemini Flash model to gemini-3.1-flash-image-preview
- Improve DOCX parsing: python-docx for structured table extraction, OCR enabled
- Add vision-based image text extraction via Gemini for uploaded images
- Add LayoutParser integration for slide layout structure analysis
- Add Phase 4 MVP features: transfer ownership, URL input, follow-up questions,
  attachment-to-slide mapping, content router

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:07:00 +00:00
Vadym Samoilenko
69a8829750 Phase 3: Bug fixes, feature enhancements, and polish
P0 Critical: presentation isolation (client scoping), storage super_admin fix,
template selection in worker, IMAGE_PROVIDERS list fix.

P1 High: template layout management UI (delete/filter/bulk), slide-based parsing
mode, LLM model listing & connection test, settings persistence to DB (Fernet
encryption), logout button.

P2 Polish: storage improvements (master deck files, per-client breakdown, bulk
delete, hard purge, client selector), image generation error visibility
(__image_error__ badge), hamster wheel loading animation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 12:58:52 +00:00
Vadym Samoilenko
d3d1667a79 Phase 2: Admin panel, analytics, storage, template pipeline, multi-provider LLM
- Fix admin sidebar: remove duplicate Teams, add Storage nav item
- Analytics: client-scoped queries, super_admin sees all (including NULL client_id)
- Storage management: list/download/delete presentations with file metadata
- Settings page with brand config router
- AI usage tracking: new AIUsageModel, ai_usage_service, analytics endpoint
- Master deck → template bridge: _register_as_template creates TemplateModel
  + PresentationLayoutCodeModel so parsed layouts appear in template picker
- Multi-provider LLM vision in parser: Anthropic/Google/OpenAI with asyncio.to_thread
- Fix PPTX upload 400: accept by .pptx extension (browser sends octet-stream)
- Fix reparse FK violation: presentation_id=None for parse_master_deck jobs
- Worker job_timeout increased to 1800s for LLM-heavy master deck parsing
- PYTHONUNBUFFERED=1 in docker-compose worker for real-time log output
- Auth: clientId in /me response, dev-login cookie improvements
- Frontend: auth slice clientId, master-deck thumbnails, storage page

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:39:34 +00:00
Vadym Samoilenko
2ecacacb3f Fix build: remove unused usePathname from editor Header
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:36:21 +00:00
Vadym Samoilenko
8238462707 Wire Oliver DeckForge UI: AuthGuard, routing, logo, remove Presenton branding
- Connect AuthGuard in providers.tsx so all pages enforce authentication
- Root page redirects to /dashboard instead of rendering old Home.tsx
- ConfigurationInitializer and login page redirect to /dashboard (not /upload)
- Create reusable Logo component with "Oliver DeckForge" text branding
- Replace Presenton logo-white.png with Logo component in all 3 headers
- Remove old "Create Template" / "Templates" nav links from dashboard header
- Replace presenton@gmail.com/www.presenton.com in template placeholders
- Fix DashboardPage heading "Slide Presentation" → "Recent Presentations"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:34:55 +00:00
Vadym Samoilenko
1293826226 Rebrand Presenton to Oliver DeckForge, pre-configure models, use NanoBanana Pro
- Replace all Presenton branding with Oliver DeckForge (metadata, headers, titles, logos)
- Pass CAN_CHANGE_KEYS=false to web container so setup page redirects to /upload
- Switch image provider from gemini_flash to nanobanana_pro
- Update default fallback paths from /tmp/presenton to /tmp/deckforge
- Rename packages: presenton → oliver-deckforge, presenton-backend → oliver-deckforge-backend
- Remove external presenton.ai URLs from metadata (canonical, OG, Twitter)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:17:11 +00:00
Vadym Samoilenko
bdf6e4b4d0 Fix Docker build, test suite, and runtime issues for local deployment
- Fix UV index strategy: mark PyTorch CPU index as explicit with name
- Add --index-strategy unsafe-best-match to Dockerfile uv pip install
- Fix redis version constraint (>=5.0,<6) for ARQ compatibility
- Fix Anthropic model name (claude-sonnet-4-5-20250929)
- Fix IMAGE_PROVIDER enum value (gemini_flash, not google)
- Resolve middlewares.py vs middlewares/ package conflict
- Fix worker import paths (models.sql.presentation, models.sql.slide, utils split)
- Fix seed script FK resolution by importing all related models
- Fix test suite: async fixture scoping, greenlet dep, regex patterns, fixture params
- Fix frontend TypeScript error (Boolean cast for layout.react_code)
- Regenerate package-lock.json with i18n packages
- Add initial Alembic migration (autogenerated from all models)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:56:30 +00:00
Vadym Samoilenko
76a4e41e3b Phase 7: Testing Suite — backend unit tests + Cypress E2E framework
Backend:
- conftest with async SQLite DB, factory fixtures for all models
- pytest-asyncio config in pyproject.toml
- Tests: auth (JWT, dev login), RBAC (access service), audit (query, export),
  brand enforcement (colors, fonts, logos, contrast), retention (cleanup, purge),
  content intelligence (regex classifiers), slide mapping, review workflow,
  analytics data queries

Frontend:
- Cypress E2E config with baseUrl and viewport settings
- Custom commands (devLogin, createPresentation)
- E2E specs: login flow, wizard navigation, admin panel, review workflow
- Test scripts in package.json

Infrastructure:
- Makefile: test-e2e and test-all targets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:49:23 +00:00
Vadym Samoilenko
c97841f6d1 Phase 6: Export & Polish — brand export, client dashboard, retention, analytics
- Brand-enforced export pipeline (PPTX/PDF with auto brand fonts/colors/logo)
- Client library dashboard with two-level navigation (client grid → detail tabs)
- Data retention service with ARQ cron jobs (daily cleanup + weekly purge)
- Brand-adaptive UI theme via CSS custom properties (dynamic per client)
- Analytics dashboard with overview, usage, quality, and performance metrics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:41:58 +00:00
Vadym Samoilenko
ad65f6fe2d Phase 5: Frontend Wizard & Editor — 5-step generation wizard, review workflow
- New 5-step wizard flow at /generate/ (Upload → Configure → Outline → Generate → Edit)
- wizardSlice with localStorage persistence for cross-session state
- Upload page: drag & drop files, brief text input, file type badges
- Configure page: client/deck selectors, slide count slider, tone, language, instructions
- Outline review page: split-view with source content + outline editor, template selection
- Progress page: SSE streaming + polling fallback for real-time job progress
- Review workflow: status badge (Draft/In Review/Approved) with popover transitions
- Backend review endpoints: PUT status, POST comment, GET review info with audit logging
- Wizard API helpers: clients, master decks, file upload/decompose, job status/cancel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:31:28 +00:00
Vadym Samoilenko
a0d73b3b63 Phase 4: Generation Pipeline — brand enforcement, enhanced LLM calls, ARQ job queue
- Step 14: Brand enforcement service (font/color/logo replacement, WCAG contrast check, LLM prompt context)
- Step 15: Enhanced outline & slide content generation with brand context, content summary, "no hallucination" instructions
- Step 15b: LLM auto-fallback retry logic across providers (FALLBACK_LLM_PROVIDERS env)
- Step 16: Redis/ARQ job queue — worker entry point, presentation & master deck workers, job status/SSE endpoints, graceful fallback to BackgroundTasks when Redis unavailable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:15:25 +00:00
Vadym Samoilenko
a2bd4cfefa Phase 3: Content Pipeline — file parsing, content intelligence, slide mapping, native charts
- Step 10: Extended file upload for Excel/CSV/images/URLs (openpyxl, trafilatura)
- Step 11: Content intelligence service with rule-based + LLM classification
- Step 12: Slide mapping engine mapping content blocks to master deck layouts
- Step 13: Chart data extractor, native PPTX chart service (bar/line/pie/gantt/waterfall), ChartDataEditor skeleton

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 15:54:04 +00:00
Vadym Samoilenko
cf21ba4516 Phase 1-2: Foundation + Admin Panel & Client Management
Phase 1 (Foundation):
- Project restructure (presenton-main → backend/ + frontend/)
- Database schema (8 new models, Alembic config, seed script)
- Auth (Azure AD SSO + dev bypass, JWT sessions, AuthMiddleware)
- RBAC (access_service, rbac_middleware, admin routers)
- Audit logging (fire-and-forget, AuditMiddleware, admin router)
- i18n (react-i18next with 5 namespace files)

Phase 2 (Admin Panel & Client Management):
- Admin panel shell (sidebar layout, role guard, 12 pages)
- Redux admin slice with 18 async thunks
- User management (role changes, deactivation)
- Client management (CRUD, brand config, team management)
- Brand config editor (colors, fonts, logos, voice rules)
- Master deck upload & parser (PPTX → HTML → React pipeline)
- Audit log viewer with filters and CSV/JSON export

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 15:37:17 +00:00
Vadym Samoilenko
26d999314e Initial commit 2026-02-26 13:06:38 +00:00