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

F000B - Shared Packages Integration

Objective

Integrate MyStoryFlow shared packages into the analyzer-app for consistent functionality across the monorepo.

Package Overview

@mystoryflow/auth

Shared authentication using Supabase SSR.

Integration:

// src/components/providers.tsx import { AuthProvider } from '@mystoryflow/auth' export function Providers({ children }: { children: React.ReactNode }) { return ( <AuthProvider> {children} </AuthProvider> ) }

Usage in Components:

import { useAuth, requireAuth } from '@mystoryflow/auth' export default requireAuth(function ManuscriptsPage() { const { user, signOut } = useAuth() return ( <div> <h1>Welcome, {user.email}</h1> </div> ) })

@mystoryflow/ui

Shared UI components and design system.

Available Components:

  • Button, Input, Select, Textarea
  • Card, Modal, Drawer
  • Table, DataGrid
  • Navigation, Sidebar
  • LoadingSpinner, ErrorBoundary
  • Toast notifications

Usage:

import { Button, Card, PageHeader, DataTable } from '@mystoryflow/ui' export function ManuscriptsList() { return ( <div> <PageHeader title="My Manuscripts" action={ <Button href="/manuscripts/new"> Upload Manuscript </Button> } /> <Card> <DataTable columns={columns} data={manuscripts} /> </Card> </div> ) }

@mystoryflow/analytics

Privacy-first analytics with AI usage tracking.

Setup AI Tracking:

// src/lib/ai-tracker.ts import { createAITracker } from '@mystoryflow/analytics' export const aiTracker = createAITracker({ appName: 'analyzer', trackingEndpoint: process.env.NEXT_PUBLIC_ADMIN_APP_URL + '/api/ai-usage' }) // Usage in AI services import { aiTracker } from '@/lib/ai-tracker' async function analyzeManuscript(content: string) { const startTime = Date.now() try { const result = await openai.chat.completions.create({ model: 'gpt-4-turbo', messages: [{ role: 'user', content }], max_tokens: 4000 }) // Track AI usage await aiTracker.track({ feature: 'manuscript-analysis', model: 'gpt-4-turbo', tokens: result.usage?.total_tokens || 0, duration: Date.now() - startTime, success: true }) return result } catch (error) { await aiTracker.track({ feature: 'manuscript-analysis', model: 'gpt-4-turbo', tokens: 0, duration: Date.now() - startTime, success: false, error: error.message }) throw error } }

@mystoryflow/database

Shared database types and utilities.

Extend for Analyzer:

// src/types/database.ts import { Database as BaseDatabase } from '@mystoryflow/database' export interface AnalyzerTables { manuscripts: { Row: { id: string user_id: string title: string // ... analyzer specific fields } } // ... other analyzer tables } export type Database = BaseDatabase & { analyzer: AnalyzerTables }

@mystoryflow/shared

Common utilities and constants.

Available Utilities:

  • Date formatting
  • File size formatting
  • URL utilities
  • Validation schemas
  • Error handling
import { formatDate, formatFileSize, createErrorResponse, validateEmail } from '@mystoryflow/shared' // Use throughout the app const displayDate = formatDate(manuscript.created_at) const fileSize = formatFileSize(manuscript.file_size)

@mystoryflow/admin

Admin dashboard components and utilities.

Admin Integration for Analyzer:

// apps/web/src/app/(admin)/admin/manuscripts/page.tsx import { AdminLayout, StatsCard, DataTable, AnalyticsChart } from '@mystoryflow/admin' export default function ManuscriptsAdminPage() { return ( <AdminLayout> <div className="grid grid-cols-1 md:grid-cols-4 gap-4"> <StatsCard title="Total Manuscripts" value={stats.totalManuscripts} icon="document" /> <StatsCard title="Analyses Today" value={stats.analysesToday} icon="chart" trend={stats.analysisTrend} /> <StatsCard title="AI Tokens Used" value={stats.tokensUsed} icon="cpu" /> <StatsCard title="Success Rate" value={`${stats.successRate}%`} icon="check-circle" /> </div> <AnalyticsChart title="Analysis Trends" data={analysisData} type="line" /> <DataTable title="Recent Manuscripts" columns={manuscriptColumns} data={manuscripts} searchable exportable /> </AdminLayout> ) }

Admin API Integration:

// apps/web/src/app/api/admin/manuscripts/route.ts import { adminService } from '@mystoryflow/admin' import { requireAdminAuth } from '@mystoryflow/auth/admin' export async function GET(request: Request) { // Verify admin access const { user } = await requireAdminAuth(request) // Use admin service for data fetching const stats = await adminService.getManuscriptStats() const manuscripts = await adminService.getRecentManuscripts() return Response.json({ stats, manuscripts }) }

AI Usage Tracking in Admin:

// apps/web/src/app/(admin)/admin/ai-usage/page.tsx import { AdminLayout, MetricsTable, UsageChart, ExportButton } from '@mystoryflow/admin' import { aiTracker } from '@/lib/ai-tracker' export default function AIUsageAdminPage() { const usage = await aiTracker.getAdminMetrics() return ( <AdminLayout> <div className="flex justify-between items-center mb-6"> <h1 className="text-2xl font-bold">AI Usage Analytics</h1> <ExportButton data={usage} filename="ai-usage-report" /> </div> <UsageChart data={usage.byModel} groupBy="model" metric="tokens" /> <MetricsTable title="Usage by Feature" data={usage.byFeature} columns={[ { key: 'feature', label: 'Feature' }, { key: 'calls', label: 'API Calls' }, { key: 'tokens', label: 'Tokens Used' }, { key: 'cost', label: 'Estimated Cost' } ]} /> </AdminLayout> ) }

Reference Data Management:

// apps/web/src/app/(admin)/admin/reference-data/page.tsx import { AdminLayout, FilterPanel, BulkActions } from '@mystoryflow/admin' import { useReferenceData } from '@/lib/reference-data' export default function ReferenceDataAdminPage() { const collections = [ 'manuscript-genres', 'analysis-statuses', 'consultation-types', 'coach-specialties' ] return ( <AdminLayout> <h1 className="text-2xl font-bold mb-6">Reference Data Management</h1> <FilterPanel filters={[ { key: 'collection', label: 'Collection', type: 'select', options: collections.map(c => ({ label: c.replace(/-/g, ' ').toUpperCase(), value: c })) } ]} values={filterValues} onChange={handleFilterChange} onReset={handleReset} /> <ReferenceDataEditor collection={selectedCollection} onSave={handleSave} /> </AdminLayout> ) }

Cross-App Navigation

// src/components/app-navigation.tsx import { Navigation } from '@mystoryflow/ui' import { useAuth } from '@mystoryflow/auth' const navigationItems = [ { label: 'Dashboard', href: '/dashboard', icon: 'dashboard' }, { label: 'My Manuscripts', href: '/manuscripts', icon: 'document' }, { label: 'Analysis History', href: '/analysis', icon: 'chart' } ] const appSwitcher = [ { label: 'Main App', href: 'https://app.mystoryflow.com', icon: 'home' }, { label: 'Tools', href: 'https://tools.mystoryflow.com', icon: 'tools' }, { label: 'Analyzer', href: 'https://analyzer.mystoryflow.com', icon: 'analyze', active: true } ] export function AppNavigation() { const { user } = useAuth() return ( <Navigation items={navigationItems} appSwitcher={appSwitcher} user={user} appName="Analyzer" /> ) }

Styling Integration

Use Shared Tailwind Config

// tailwind.config.ts import baseConfig from '@mystoryflow/ui/tailwind.config' export default { ...baseConfig, content: [ './src/**/*.{js,ts,jsx,tsx}', '../../packages/ui/src/**/*.{js,ts,jsx,tsx}' ], theme: { extend: { ...baseConfig.theme.extend, colors: { ...baseConfig.theme.extend.colors, // Analyzer-specific colors 'analyzer': { 50: '#f0f9ff', 500: '#3b82f6', 900: '#1e3a8a' } } } } }

Testing Integration

Use Shared Test Utilities

// __tests__/manuscripts.test.ts import { createMockUser, createMockSupabase, setupTestDatabase } from '@mystoryflow/shared/test-utils' describe('Manuscripts', () => { beforeEach(async () => { await setupTestDatabase('analyzer') }) it('should create manuscript', async () => { const user = createMockUser() const supabase = createMockSupabase() // Test implementation }) })

Build Configuration

Update package.json Scripts

{ "scripts": { "dev": "next dev -p 3005", "build": "next build", "test": "jest", "lint": "eslint . --ext .ts,.tsx", "type-check": "tsc --noEmit", "with-env": "dotenv -e ../../.env.local --", "analyze:bundle": "ANALYZE=true next build" } }

Verification Checklist

  • Auth flows work (sign in/up/out)
  • UI components render correctly
  • Analytics tracking fires
  • AI usage appears in admin dashboard
  • Cross-app navigation works
  • Shared styles apply correctly
  • Database types extend properly

Next Steps

Proceed to F001-PROJECT-SETUP to configure analyzer-specific branding and features.