newsforge-api / docs /04_user_admin_flows.md
warmsyntax
Commit full newsforge prototype
e5e1997
|
Raw History Blame Contribute Delete
20.2 kB
# NewsForge β€” User & Admin Flows
**Agent Assignment:** πŸ”€ **Flow / UX-Logic Agent**
**Source:** Extracted from [newsforge_prd.md](file:///f:/newsapp/newsforge_prd.md) Β§6.5 (User Flow), Β§9.3 (Template Publishing Workflow), Β§10.3 (AI Pipeline), Β§8.4 (Rendering Pipeline), Β§2.4 ("Aha" Moment)
**Scope:** All user journeys, admin workflows, state transitions, edge cases, and interaction sequences.
**Last Updated:** 2026-06-24
---
## 1. User Flows (Mobile App)
### 1.1 Primary Flow: Template Selection β†’ Export
This is the **core product loop**. Every user session follows this path.
```
Home β†’ Browse templates by category
β†’ Tap template card β†’ See full preview + "Use Template" button
β†’ [Use Template] β†’ Fill screen with live preview
β†’ Type headline, upload photo, fill required fields
β†’ [Optional] Tap "AI Script" β†’ Generate script β†’ Copy to script field
β†’ [Optional] Tap "AI Voice" β†’ Paste/type script β†’ Select voice β†’ Generate audio
β†’ Tap "Export" β†’ Choose format + quality
β†’ [If video] β†’ Select AI voice track β†’ Set duration
β†’ [Export] β†’ Processing spinner (client-side for images, server-side for video)
β†’ Save to gallery + Share sheet
β†’ [AHA MOMENT: Professional news content in < 60 seconds]
```
**Critical Metric:** Time to first export must be **< 90 seconds**.
---
### 1.2 User Registration / Onboarding Flow
```
App Launch (first time)
β†’ Splash Screen (branded, 2s)
β†’ Onboarding Carousel (3 slides):
Slide 1: "Pick a template" (template browser preview)
Slide 2: "Fill in the blanks" (fill screen preview)
Slide 3: "Export in 60 seconds" (final output preview)
β†’ "Get Started" CTA
β†’ Auth Screen:
β†’ [Google Sign In] β†’ Firebase Auth popup β†’ Google OAuth β†’ Firebase ID Token
β†’ POST /auth/google β†’ Backend verifies β†’ Custom JWT issued β†’ Logged in
β†’ [Email Sign Up] β†’ Name + Email + Password form
β†’ POST /auth/email/register β†’ Custom JWT issued β†’ Logged in
β†’ [Email Login] β†’ Email + Password form
β†’ POST /auth/email/login β†’ Custom JWT issued β†’ Logged in
β†’ Home Screen (Template Browser)
```
---
### 1.3 Template Browsing & Selection Flow
```
Home Screen
β†’ Category Pills at top: [All] [Breaking News] [Sports] [Weather] [Politics] [Entertainment] [Business]
β†’ Tapping a category filters the grid (API: GET /api/templates?category=breaking_news)
β†’ Search bar: free-text search across template name/tags
β†’ Grid of template cards:
Each card shows: thumbnail, name, format badge (Image/Video), size badge, pricing badge
β†’ Tap a card:
β†’ Full-screen template preview
β†’ Template metadata: Name, Category, Available sizes, Supported languages
β†’ "Use Template" button (full-width, sticky bottom)
β†’ [Use Template] β†’ Navigates to Fill Screen
```
---
### 1.4 Template Fill & Live Preview Flow
```
Fill Screen
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LIVE PREVIEW (top 60% of screen)β”‚
β”‚ Shows template with current β”‚
β”‚ input values rendered in β”‚
β”‚ real-time via Fabric.js β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ INPUT FORM (scrollable) β”‚
β”‚ - Headline: [text input] β”‚
β”‚ "Max 80 characters" β”‚
β”‚ - Main Photo: [image picker] β”‚
β”‚ "Square crop recommended" β”‚
β”‚ - Source: [text input] β”‚
β”‚ - Date: [date picker] β”‚
β”‚ - Category: [select dropdown] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ [Preview] [Export] β”‚ ← Sticky bottom bar
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Each input change:
β†’ JS maps slot value to target_object_id
β†’ Fabric.js re-renders canvas (150ms debounce)
β†’ Preview updates in real-time
Image input:
β†’ Tap "Main Photo" β†’ Options: [Gallery] [Camera]
β†’ User selects/captures image
β†’ Client-side crop to template's aspect_ratio_hint
β†’ Image placed into Fabric.js canvas layer
β†’ Image NEVER uploaded to server
Validation:
β†’ Required fields checked before "Export" enabled
β†’ Character limits enforced with live counter
β†’ Export button disabled until all required fields filled
```
---
### 1.5 AI Script Writer Flow
```
AI Tools Screen β†’ AI Script Writer card
β†’ Input Form:
- Topic/Headline: [text input, required]
- Tone: [Formal | Casual | Dramatic | Neutral]
- Target Length: [30s | 60s | 90s]
- Key Points: [optional text area]
- Language: [EN | HI | TA | TE | ...]
β†’ "Generate Script" button
β†’ Loading spinner (~500ms β€” Groq/Mistral is fast)
β†’ Generated script displayed in scrollable text area
β†’ Actions:
β†’ [Copy to Clipboard]
β†’ [Use for Voice] β†’ Auto-fills AI Voice input with script text
β†’ [Edit] β†’ User can modify the generated script
β†’ [Regenerate] β†’ New generation with same inputs
β†’ Usage counter: "3 of 5 scripts remaining today" (v1.1+ only, v1 = unlimited)
```
---
### 1.6 AI Voice Generation Flow
```
AI Tools Screen β†’ AI Voice Generator card
β†’ Input Form:
- Script Text: [text area, required] (can be auto-filled from AI Script)
- Voice: [dropdown β€” language β†’ gender β†’ style]
- Speed: [slider 0.8Γ— to 1.2Γ— for free, 0.5Γ— to 2.0Γ— for Pro]
β†’ "Generate Voice" button
β†’ Loading indicator (~3s for Edge TTS)
β†’ Audio player appears with generated voice preview
β†’ Actions:
β†’ [Play / Pause] β†’ Preview the voice
β†’ [Attach to Template] β†’ Voice audio blob stored in client memory
β†’ Returns to Fill Screen with voice track attached
β†’ [Download Audio] β†’ Save MP3 to device
β†’ [Regenerate] β†’ New generation with same/different voice
β†’ Usage counter: "2 of 5 voices remaining today" (v1.1+ only)
```
---
### 1.7 Full AI Pipeline Flow (Script β†’ Voice β†’ Video)
This is the **killer UX** β€” seamless from idea to finished video:
```
User taps "AI Script" β†’ enters topic β†’ gets generated script (Groq/Mistral, ~500ms)
β†’ Taps "Use for Voice" β†’ script auto-fills voice input
β†’ Selects voice β†’ Taps "Generate Voice" β†’ hears preview (Edge TTS, ~3s)
β†’ Taps "Attach to Template" β†’ voice audio blob stored in client memory
β†’ Returns to Fill Screen β†’ voice indicator shows "AI Voice attached βœ“"
β†’ Taps "Export" β†’ Choose MP4 format
β†’ FFmpeg.wasm composites video + voice on-device (~15-30s)
β†’ Progress bar: "Rendering video... 45%"
β†’ Complete β†’ Save to gallery + Share sheet
β†’ 4 taps from idea to finished news video β€” ZERO server rendering
```
---
### 1.8 Export Flow
```
Fill Screen β†’ Tap "Export"
β†’ Export Modal:
- Format: [PNG] [JPG] [MP4 (video templates only)]
- Size: [Instagram Story 1080Γ—1920] [Instagram Post 1080Γ—1080] [YouTube Thumbnail 1280Γ—720]
- Quality: [720p (Free)] [1080p (Pro)] [4K (Newsroom)]
- [If video + voice attached] β†’ "Include AI Voice: βœ“"
- [If video] β†’ Duration indicator
β†’ "Export Now" button
For Image Templates:
β†’ Fabric.js canvas.toDataURL('image/png', quality)
β†’ Blob saved to device via Capacitor Filesystem
β†’ 100% client-side, instant (~1-2s)
β†’ POST /api/exports/log (analytics only)
For Video Templates:
β†’ FFmpeg.wasm lazy-loaded (first time: download ~25MB, show progress)
β†’ Each scene rendered as frames via Fabric.js
β†’ FFmpeg composites frames + voice audio + background music
β†’ Progress bar: "Rendering video... XX%"
β†’ MP4 saved to device
β†’ POST /api/exports/log (analytics only)
Post-Export:
β†’ "Saved to Gallery βœ“" confirmation
β†’ Quick share buttons: [Instagram] [WhatsApp] [YouTube] [More...]
β†’ "Create Another" button β†’ returns to template browser
```
---
### 1.9 My Projects Flow
```
Bottom Nav β†’ "My Projects"
β†’ List of recent projects with:
- Template thumbnail
- Template name
- Last edited date
- Export status (exported / draft)
β†’ Tap project:
β†’ Re-opens Fill Screen with saved slot values
β†’ Text/select/date values restored from server (JSONB)
β†’ Images NOT restored (user must re-upload if has_user_images=true)
β†’ User can modify and re-export
β†’ Swipe to delete project
β†’ Long-press for options: [Re-export] [Duplicate] [Delete]
```
---
### 1.10 Profile & Settings Flow
```
Bottom Nav β†’ "Profile"
β†’ User info: Name, Email, Plan (Free in v1)
β†’ Usage stats: Exports today, AI credits remaining
β†’ Settings:
- Language preference β†’ dropdown
- Download quality β†’ 720p / 1080p / 4K
- Clear cached templates β†’ confirmation dialog β†’ clears IndexedDB
β†’ Account:
- "My Data" β†’ shows all stored data (GDPR)
- "Export My Data" β†’ GET /api/account/export β†’ JSON download
- "Delete My Account" β†’ confirmation dialog β†’ immediate hard delete
β†’ [v1.1+] Plan management:
- Current plan display
- "Upgrade to Pro" CTA with feature comparison
- Subscription management (cancel, change plan)
```
---
### 1.11 OTA Template Sync Flow
```
App Launch
β†’ GET /api/templates/sync?since_timestamp={last_sync}
β†’ Response: { templates: [...], deleted_ids: [...], sync_timestamp }
β†’ New/updated templates added to local IndexedDB cache
β†’ Deleted template IDs removed from cache
β†’ sync_timestamp saved for next call
β†’ Repeats every 30 minutes while app is open
Result: Admin publishes template β†’ appears in user's app within minutes.
No Play Store update required.
```
---
### 1.12 Offline Degradation Flow (v1)
```
Network lost (detected via @capacitor/network)
β†’ App shows cached templates from IndexedDB (browse-only)
β†’ Template fill screen works for cached templates (Fabric.js is local)
β†’ Image export works (100% client-side)
β†’ AI Voice β†’ "Offline β€” voice generation requires internet" message
β†’ AI Script β†’ "Offline β€” script generation requires internet" message
β†’ Video export with voice β†’ "Attach voice while online, then export offline"
β†’ Projects cannot sync until online
β†’ Banner at top: "You're offline. Some features are limited."
Network restored
β†’ Banner dismissed
β†’ Sync triggered
β†’ Full features restored
```
---
## 2. Admin Flows (Web Dashboard)
### 2.1 Admin Login Flow
```
admin.newsforge.app
β†’ Login screen: Email + Password
β†’ POST /admin/auth/login β†’ bcrypt verify β†’ Admin JWT issued
β†’ Redirect to Dashboard Home
β†’ IP allowlisting check (if enabled)
β†’ Failed login: rate limit after 5 attempts (lockout 15 min)
```
---
### 2.2 Template Creation Flow
```
Dashboard β†’ "Create Template" button
β†’ Template Editor opens:
β†’ Blank canvas (choose size: 1080Γ—1920, 1080Γ—1080, 1280Γ—720)
β†’ Toolbar: Text, Image, Shape, Icon, Line, Background
β†’ Design Phase:
β†’ Add objects (text, images, shapes)
β†’ Style (colors, fonts, effects, positioning)
β†’ Arrange layers (drag to reorder, lock, group)
β†’ Input Slot Definition:
β†’ Select an object β†’ Properties Panel
β†’ Check "Is Input Slot" β˜‘
β†’ Define: Label, Type (text/image/select/date/etc.), Constraints
β†’ Object gets blue dashed border indicator
β†’ Metadata:
β†’ Name, Category, Pricing (free in v1), Tags, Languages
β†’ [For video templates]:
β†’ Add scenes (Intro, Body, Outro)
β†’ Set durations, transitions, animations per scene
β†’ "Preview as User" β†’ opens modal showing mobile fill screen UX
β†’ "Save Draft" β†’ template saved, not visible to users
β†’ "Publish" β†’ template goes live in the app (OTA sync)
```
---
### 2.3 Template Management Flow
```
Dashboard β†’ Template Manager
β†’ Table/Grid view of all templates:
Columns: Thumbnail, Name, Category, Format, Status, Downloads, Last Modified
β†’ Filters: Category, Status (Draft/Published/Archived), Pricing, Format
β†’ Actions per template:
β†’ [Edit] β†’ opens Template Editor with existing data
β†’ [Publish] β†’ status: draft β†’ published (appears in app)
β†’ [Unpublish] β†’ status: published β†’ draft (removed from app)
β†’ [Archive] β†’ hidden from users, admin can restore
β†’ [Delete] β†’ permanent deletion (confirmation dialog)
β†’ Bulk actions: Select multiple β†’ Publish / Archive / Change pricing
```
---
### 2.4 Template Publishing Workflow (State Machine)
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”
β”‚ Draft β”‚ ← Initial state when created
β””β”€β”€β”€β”¬β”€β”€β”€β”˜
β”‚ [Publish]
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Published β”‚ ← Visible in app, synced via OTA
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
β”‚ [Unpublish] β”‚ [Archive]
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Draft β”‚ β”‚ Archived β”‚ ← Hidden from users, restorable
β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ [Restore]
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”
β”‚ Draft β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
### 2.5 Asset Management Flow
```
Template Editor β†’ Upload asset (image, font, audio)
β†’ POST /admin/templates/:id/assets
β†’ File validated (max 5MB, image-only for images)
β†’ Uploaded to Cloudflare R2:
β†’ Images: /templates/assets/{template_id}/{filename}
β†’ Fonts: /fonts/{filename}
β†’ Audio: /templates/audio/{filename}
β†’ R2 URL stored in template_assets table
β†’ Asset available in editor's asset library
β†’ Asset URL referenced in Fabric.js canvas JSON
Thumbnail generation:
β†’ On template save β†’ auto-render canvas as thumbnail image
β†’ Upload to R2: /templates/thumbs/{template_id}.png
β†’ thumbnail_url stored in templates table
```
---
### 2.6 Analytics Dashboard Flow
```
Dashboard β†’ Analytics
β†’ Overview tab:
- DAU / MAU charts (from daily_metrics_snapshot)
- Total exports today
- AI usage (voice + script generations)
- New signups
β†’ Templates tab:
- Table: Template name, downloads, exports, conversion rate
- Sort by: Most popular, Most exported, Newest
- Identify top performers and underperformers
β†’ Users tab:
- Total users, new vs returning
- Plan distribution (Free/Pro/Newsroom)
- Retention curves (Day 1, Day 7)
β†’ AI Usage tab:
- Voice generations: count, languages, voices used
- Script generations: count, tones, lengths
- Cost tracking (Groq tokens consumed)
```
---
## 3. Edge Cases & Error Handling
### 3.1 FFmpeg.wasm Failures
```
Video export initiated
β†’ FFmpeg.wasm loads (first time: ~25MB download with progress bar)
β†’ IF out-of-memory (OOM):
β†’ Catch error gracefully
β†’ Show message: "Your device doesn't support video export. Try image templates instead."
β†’ Log error: POST /api/errors/log { type: 'ffmpeg_oom', device_info }
β†’ IF SharedArrayBuffer not available:
β†’ Show message: "Video export requires a newer version of Android (10+)."
β†’ Offer image export as alternative
```
### 3.2 AI Service Failures
```
Voice generation fails (Edge TTS down):
β†’ Show error: "Voice generation is temporarily unavailable. Please try again in a few minutes."
β†’ Backend auto-switches to Piper TTS after 3 consecutive failures
β†’ Log in ai_usage_log with error code
Script generation fails (Groq API down):
β†’ Show error: "Script generation is temporarily unavailable."
β†’ Offer manual script input as alternative
β†’ Log error
```
### 3.3 Network Errors
```
API call fails (timeout, 5xx, network error):
β†’ Show non-blocking toast: "Connection issue. Retrying..."
β†’ Auto-retry: 3 attempts with exponential backoff (1s, 2s, 4s)
β†’ If all retries fail: Show persistent banner with "Retry" button
β†’ Template data served from IndexedDB cache when possible
```
### 3.4 Cold Start Handling
```
First API call after HuggingFace Space sleep:
β†’ Response takes 15-30s (cold start)
β†’ Show animated "Preparing NewsForge..." screen with progress indication
β†’ Do NOT show error until > 45s timeout
β†’ Subsequent calls are fast (<500ms)
```
### 3.5 App Version Check
```
App launch β†’ GET /api/app/config
β†’ Response: { min_supported_version, latest_version, maintenance_mode }
β†’ IF app_version < min_supported_version:
β†’ Force-update dialog (blocking): "Please update NewsForge to continue."
β†’ Link to Play Store
β†’ IF maintenance_mode == true:
β†’ Maintenance screen: "NewsForge is under maintenance. We'll be back shortly."
β†’ IF app_version < latest_version:
β†’ Optional update banner: "A new version is available. Update now?"
```
---
## 4. State Diagrams
### 4.1 User Session States
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Anonymous β”‚ ← App opened, not logged in
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ [Login / Register]
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Authenticated β”‚ ← Full access to all features
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ [Token expired + refresh failed]
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Logged Out β”‚ ← Must re-authenticate
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
### 4.2 Export States
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Filling β”‚ ← User editing input slots
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
β”‚ [All required fields filled]
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Ready β”‚ ← Export button enabled
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
β”‚ [Tap Export]
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Processing β”‚ ← Rendering (image: ~1s, video: ~15-30s)
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ [Complete] β”‚ [Error]
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Exported β”‚ β”‚ Failed β”‚ β†’ Error message + retry option
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
*This document defines all user journeys and admin workflows for NewsForge. The Flow/UX-Logic Agent should reference this for implementing navigation, state management, and interaction sequences.*