Skip to Content
📚 MyStoryFlow Docs — Your guide to preserving family stories

F001 - Analyzer App Configuration & Branding

Objective

Configure the analyzer-app within MyStoryFlow monorepo with appropriate branding and settings for the Manuscript Analyzer platform (analyzer.mystoryflow.com).

Requirements

Functional Requirements

  • Configure analyzer-app branding as “MyStoryFlow Analyzer”
  • Set up URLs and domain references for analyzer.mystoryflow.com
  • Integrate with MyStoryFlow’s existing user system
  • Configure environment variables specific to manuscript analysis
  • Ensure consistent branding with other MyStoryFlow apps

Technical Requirements

  • Configure analyzer-app package.json
  • Set up app metadata and SEO content
  • Integrate with @mystoryflow/ui design system
  • Configure cross-app navigation
  • Set up shared authentication

Database Changes

None required for this feature.

Configuration Changes

1. Analyzer App Package Configuration

File: apps/analyzer-app/package.json

{ "name": "analyzer-app", "description": "AI-powered manuscript analysis for MyStoryFlow authors", "version": "1.0.0", "private": true, "scripts": { "dev": "next dev -p 3005", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@mystoryflow/auth": "*", "@mystoryflow/ui": "*", "@mystoryflow/analytics": "*", "@mystoryflow/database": "*", "@mystoryflow/shared": "*" } }

2. Environment Variables

File: apps/analyzer-app/.env.local

# App Configuration (extends root .env) NEXT_PUBLIC_APP_URL=http://localhost:3005 NEXT_PUBLIC_APP_NAME=MyStoryFlow Analyzer NEXT_PUBLIC_APP_DESCRIPTION=AI-powered manuscript analysis for authors # Analysis Configuration NEXT_PUBLIC_MAX_MANUSCRIPT_SIZE=150000 # 150k words NEXT_PUBLIC_FREE_TIER_LIMIT=5000 # 5k words for free tier NEXT_PUBLIC_FREE_TIER_ANALYSES=3 # 3 analyses per month # AI Processing Settings AI_PROCESSING_TIMEOUT=300000 # 5 minutes max processing ANALYZER_RATE_LIMIT_PER_HOUR=10 # Feature Flags NEXT_PUBLIC_ENABLE_GENRE_DETECTION=true NEXT_PUBLIC_ENABLE_REVISION_TRACKING=true NEXT_PUBLIC_ENABLE_BETA_FEATURES=false # Shared services (from root .env) # - Supabase credentials # - AI API keys (OpenAI, Anthropic, Gemini, xAI) # - Backblaze storage # - Analytics configuration

3. App-Specific Configuration

Root Layout (apps/analyzer-app/src/app/layout.tsx)

import { Inter, Merriweather } from 'next/font/google' import { Providers } from '@/components/providers' import { AppNavigation } from '@/components/app-navigation' import { AnalyticsProvider } from '@mystoryflow/analytics' import '@mystoryflow/ui/styles/globals.css' import './analyzer.css' const inter = Inter({ subsets: ['latin'], variable: '--font-sans' }) const merriweather = Merriweather({ weight: ['300', '400', '700'], subsets: ['latin'], variable: '--font-serif' }) export const metadata = { title: 'MyStoryFlow Analyzer - Professional Manuscript Analysis', description: 'AI-powered manuscript analysis with 200+ evaluation points', keywords: 'manuscript analysis, book editing, AI writing assistant' } export default function RootLayout({ children }) { return ( <html lang="en" className={`${inter.variable} ${merriweather.variable}`}> <body> <AnalyticsProvider appName="analyzer"> <Providers> <AppNavigation /> <main className="min-h-screen bg-gradient-to-br from-amber-50 to-orange-50"> {children} </main> </Providers> </AnalyticsProvider> </body> </html> ) }

App Navigation Integration

// apps/analyzer-app/src/components/app-navigation.tsx import { Navigation } from '@mystoryflow/ui' import { useAuth } from '@mystoryflow/auth' const navItems = [ { label: 'Dashboard', href: '/dashboard', icon: 'dashboard' }, { label: 'Manuscripts', href: '/manuscripts', icon: 'document' }, { label: 'Analysis History', href: '/analysis', icon: 'chart' }, { label: 'Settings', href: '/settings', icon: 'settings' } ] const appSwitcher = [ { label: 'Stories', href: process.env.NEXT_PUBLIC_MAIN_APP_URL }, { label: 'Tools', href: process.env.NEXT_PUBLIC_TOOLS_APP_URL }, { label: 'Analyzer', href: '/', active: true }, { label: 'Admin', href: process.env.NEXT_PUBLIC_ADMIN_APP_URL, adminOnly: true } ] export function AppNavigation() { const { user } = useAuth() return ( <Navigation items={navItems} appSwitcher={appSwitcher} user={user} appName="Analyzer" appIcon="📚" /> ) }

UI Customization

1. Analyzer-Specific Styles

File: apps/analyzer-app/src/app/analyzer.css

/* Extend MyStoryFlow design system with literary theme */ :root { /* Override primary colors for analyzer */ --analyzer-primary: #2C1810; /* Deep brown (like old books) */ --analyzer-secondary: #8B4513; /* Saddle brown */ --analyzer-accent: #DAA520; /* Golden rod (like gilt edges) */ --analyzer-paper: #FFFEF7; /* Aged paper */ --analyzer-ink: #1A1A1A; /* Dark ink */ } /* Typography for literary feel */ .manuscript-content { font-family: var(--font-serif); line-height: 1.8; color: var(--analyzer-ink); } /* Paper-like containers */ .paper-card { background: var(--analyzer-paper); box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); border: 1px solid rgba(139, 69, 19, 0.1); }

2. Component Overrides

// apps/analyzer-app/src/components/ui-overrides.tsx import { Button as BaseButton, Card as BaseCard } from '@mystoryflow/ui' import { cn } from '@mystoryflow/shared' export const Button = ({ className, ...props }) => ( <BaseButton className={cn( 'analyzer-button', 'hover:shadow-md transition-all', className )} {...props} /> ) export const ManuscriptCard = ({ className, ...props }) => ( <BaseCard className={cn('paper-card', className)} {...props} /> )

3. Dashboard Customization

// apps/analyzer-app/src/app/dashboard/page.tsx import { PageHeader, StatsGrid } from '@mystoryflow/ui' import { ManuscriptCard } from '@/components/ui-overrides' export default function DashboardPage() { return ( <div className="container mx-auto p-6"> <PageHeader title="Manuscript Analysis Dashboard" subtitle="Transform your writing with AI-powered insights" icon="📚" /> <StatsGrid> <StatsGrid.Item label="Manuscripts Analyzed" value="12" trend="+2 this month" icon="📖" /> <StatsGrid.Item label="Average Score" value="78%" trend="+5% improvement" icon="📊" /> <StatsGrid.Item label="Words Analyzed" value="425.3k" icon="✍️" /> </StatsGrid> <ManuscriptCard className="mt-8"> <h2>Recent Manuscripts</h2> {/* Manuscript list */} </ManuscriptCard> </div> ) }

API Endpoints (Future)

This feature focuses on configuration only. No new endpoints required.

Testing Requirements

Unit Tests

// apps/analyzer-app/__tests__/config.test.ts describe('Analyzer Configuration', () => { it('loads analyzer-specific env vars', () => { expect(process.env.NEXT_PUBLIC_APP_NAME).toBe('MyStoryFlow Analyzer') expect(process.env.NEXT_PUBLIC_MAX_MANUSCRIPT_SIZE).toBe('150000') }) it('integrates with shared packages', () => { expect(() => import('@mystoryflow/ui')).not.toThrow() expect(() => import('@mystoryflow/auth')).not.toThrow() }) })

Integration Tests

  • Test authentication flow with shared auth
  • Verify cross-app navigation works
  • Test AI tracking integration with admin-app
  • Verify shared UI components render correctly

E2E Tests

// apps/analyzer-app/e2e/navigation.spec.ts test('cross-app navigation', async ({ page }) => { await page.goto('http://localhost:3005') // Test app switcher await page.click('[data-testid="app-switcher"]') await expect(page.locator('text=Stories')).toBeVisible() await expect(page.locator('text=Tools')).toBeVisible() await expect(page.locator('text=Analyzer')).toHaveClass(/active/) })

Acceptance Criteria

Must Have

  • Analyzer app runs on port 3005
  • Integrates with @mystoryflow packages
  • Shares authentication with other apps
  • Cross-app navigation works
  • Literary-themed styling applied
  • AI usage tracked in admin dashboard

Should Have

  • Custom manuscript-specific components
  • Analyzer-specific color overrides
  • SEO metadata optimized for manuscript analysis
  • Performance optimizations for large texts

Could Have

  • Dark mode for extended writing sessions
  • Keyboard shortcuts for power users
  • PWA support for offline access

Dependencies

  • F000-MONOREPO-SETUP - Analyzer app must be created first
  • F000B-SHARED-PACKAGES - Shared packages must be integrated
  • Access to MyStoryFlow monorepo and shared packages

Estimated Effort

  • Development: 2 days
  • Testing: 1 day
  • Documentation: 0.5 days
  • Total: 3.5 days

Implementation Notes

Priority Order

  1. Set up analyzer-app specific configuration
  2. Integrate shared authentication and UI
  3. Implement cross-app navigation
  4. Apply literary theme and styling
  5. Configure AI usage tracking
  6. Test integration with other apps

Integration Points

  • Auth: Uses @mystoryflow/auth for SSO
  • UI: Extends @mystoryflow/ui components
  • Analytics: Reports to @mystoryflow/analytics
  • Admin: AI usage appears in admin-app dashboard

Admin Integration Details

// apps/analyzer-app/src/lib/admin-integration.ts import { adminService } from '@mystoryflow/admin' import { aiTracker } from '@/lib/ai-tracker' export const adminIntegration = { // Report manuscript analysis to admin async reportAnalysis(manuscriptId: string, stats: AnalysisStats) { await adminService.reportAnalysis({ appName: 'analyzer', manuscriptId, wordCount: stats.wordCount, tokensUsed: stats.tokensUsed, processingTime: stats.duration, success: stats.success, model: stats.model }) }, // Get admin-specific metrics async getAdminMetrics() { return adminService.getAnalyzerMetrics({ includeUsage: true, includeRevenue: true, includeTrends: true }) } }

Admin Dashboard Access

// apps/analyzer-app/src/middleware.ts import { isAdmin } from '@mystoryflow/auth/admin' export async function middleware(request: Request) { const pathname = new URL(request.url).pathname // Admin routes require admin privileges if (pathname.startsWith('/admin')) { const adminAccess = await isAdmin(request) if (!adminAccess) { return Response.redirect(new URL('/', request.url)) } } return NextResponse.next() }

Configuration Management

// apps/analyzer-app/src/lib/config.ts import { createConfig } from '@mystoryflow/shared' export const analyzerConfig = createConfig({ app: { name: 'MyStoryFlow Analyzer', version: '1.0.0', port: 3005 }, features: { genreDetection: process.env.NEXT_PUBLIC_ENABLE_GENRE_DETECTION === 'true', revisionTracking: process.env.NEXT_PUBLIC_ENABLE_REVISION_TRACKING === 'true', betaFeatures: process.env.NEXT_PUBLIC_ENABLE_BETA_FEATURES === 'true' }, limits: { maxManuscriptSize: parseInt(process.env.NEXT_PUBLIC_MAX_MANUSCRIPT_SIZE || '150000'), freeTierLimit: parseInt(process.env.NEXT_PUBLIC_FREE_TIER_LIMIT || '5000'), freeTierAnalyses: parseInt(process.env.NEXT_PUBLIC_FREE_TIER_ANALYSES || '3') } })

Next Feature

After completion, proceed to F002-DATABASE-SCHEMA to create the analyzer schema in the existing MyStoryFlow database.