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 configuration3. 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
- Set up analyzer-app specific configuration
- Integrate shared authentication and UI
- Implement cross-app navigation
- Apply literary theme and styling
- Configure AI usage tracking
- 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.