You are an expert AI application architect and senior full-stack developer tasked with building a fully functional MVP of 'Emotion AI Coach' using Next.js (App Router), Tailwind CSS, and Drizzle ORM. This application will help AI researchers and developers understand and manage the internal 'emotional' representations and behaviors of Large Language Models (LLMs).
**1. PROJECT OVERVIEW:**
Emotion AI Coach is a cutting-edge SaaS platform designed to decode the 'emotional' concepts and their functional impact within LLMs. The core problem it addresses is the growing opacity and unpredictability of LLM behavior, often mimicing human emotions. Our application provides tools to analyze the internal mechanisms of models like Claude, identify emotion-related representations, visualize their patterns, and understand how these representations shape the LLM's output and behavior. The value proposition lies in enabling safer, more reliable, and interpretable AI interactions by demystifying the 'psychology' of LLMs, thus fostering trust and responsible AI development.
**2. TECH STACK:**
- **Frontend:** Next.js (App Router), React, TypeScript, Tailwind CSS, shadcn/ui (for pre-built components and styling)
- **Backend:** Next.js API Routes (or potentially a separate Node.js/Express server if complexity demands, but aim for integrated first)
- **Database:** PostgreSQL (or SQLite for local development simplicity), Drizzle ORM for type-safe database interactions
- **Authentication:** NextAuth.js (or Clerk/Supabase Auth for quicker integration)
- **State Management:** React Context API or Zustand (for global state)
- **Data Fetching:** Server Actions, fetch API, SWR/React Query (for client-side caching if needed)
- **Charting/Visualization:** Recharts or Chart.js for data visualization
- **Deployment:** Vercel
- **Other:** ESLint, Prettier, Husky (for Git hooks)
**3. DATABASE SCHEMA (PostgreSQL with Drizzle ORM):**
```typescript
// schema.ts (Drizzle Schema Definition)
import { pgTable, text, timestamp, uuid, integer, jsonb, varchar, boolean } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// Users Table
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name'),
email: text('email').notNull().unique(),
emailVerified: timestamp('emailVerified', { mode: 'date' }),
image: text('image'),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
export const accounts = pgTable('accounts', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
type: varchar('type', { length: 256 }).notNull(),
provider: varchar('provider', { length: 256 }).notNull(),
providerAccountId: varchar('providerAccountId', { length: 256 }).notNull(),
refresh_token: text('refresh_token'),
access_token: text('access_token'),
expires_at: integer('expires_at'),
token_type: varchar('token_type', { length: 256 }),
scope: text('scope'),
id_token: text('id_token'),
session_state: varchar('session_state', { length: 256 })
});
export const sessions = pgTable('sessions', {
sessionToken: text('sessionToken').primaryKey(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
expires: timestamp('expires', { mode: 'date' }).notNull()
});
export const verificationTokens = pgTable('verificationTokens', {
identifier: text('identifier').notNull(),
token: text('token').notNull(),
expires: timestamp('expires', { mode: 'date' }).notNull(),
// Ensure a composite primary key
primaryKey: "verificationTokens_identifier_token_pkey"
})
// LLM Analysis Projects Table
export const projects = pgTable('projects', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
name: varchar('name', { length: 255 }).notNull(),
llmModel: varchar('llmModel', { length: 255 }), // e.g., 'Claude Sonnet 4.5', 'GPT-4'
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Analysis Runs Table
export const analysisRuns = pgTable('analysisRuns', {
id: uuid('id').primaryKey().defaultRandom(),
projectId: uuid('projectId').notNull().references(() => projects.id, { onDelete: 'cascade' }),
runName: varchar('runName', { length: 255 }).notNull(),
inputData: jsonb('inputData'), // The prompt/input given to the LLM
rawData: jsonb('rawData'), // Raw output from the LLM
analysisResults: jsonb('analysisResults'), // Processed results, emotion scores, etc.
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
});
// User Relations (Example)
export const userRelations = relations(users, ({ many }) => ({
projects: many(projects),
}));
// Project Relations (Example)
export const projectRelations = relations(projects, ({ one, many }) => ({
user: one(users, {
fields: [projects.userId],
references: [users.id]
}),
analysisRuns: many(analysisRuns)
}));
// Analysis Run Relations (Example)
export const analysisRunRelations = relations(analysisRuns, ({ one }) => ({
project: one(projects, {
fields: [analysisRuns.projectId],
references: [projects.id]
})
}));
```
**4. CORE FEATURES & USER FLOW:**
**A. User Authentication & Project Management:**
- **Flow:** User signs up/logs in via email/password or OAuth (Google/GitHub).
- After login, user sees a dashboard listing their existing projects.
- User can create a new project (name, LLM model details).
- User can view, edit, or delete existing projects.
- **Edge Case:** Unauthenticated users are redirected to login/signup.
**B. LLM Analysis Run:**
- **Flow:** Within a project, user initiates a new 'Analysis Run'.
- User provides a prompt/input text for the LLM.
- User selects parameters (if any, e.g., temperature, model version - simplified for MVP).
- The system sends the prompt to a hypothetical LLM API (for MVP, this can be simulated or use a placeholder).
- The raw LLM response is stored.
- A backend process (or server action) analyzes the raw response for emotion-related concepts using a pre-defined NLP model or heuristic rules.
- Analysis results (e.g., detected emotion scores, keyword associations) are stored in `analysisResults`.
- The user is notified when the analysis is complete.
- **Edge Cases:** LLM API errors, invalid input, long processing times (show loading states).
**C. Analysis Results Dashboard & Visualization:**
- **Flow:** User selects a completed Analysis Run.
- The dashboard displays:
- The original prompt and raw LLM response.
- Key findings: Detected emotions (e.g., 'frustration', 'happiness', 'anxiety'), confidence scores.
- Visualization: A chart showing the distribution of detected emotions. A representation of internal 'neuron' activation patterns (simplified for MVP, e.g., heatmaps or correlation matrices based on simulated data).
- Behavioral correlation: Textual summary linking detected emotions to specific behaviors/phrases in the LLM output.
- **Edge Cases:** No analysis results available (empty state), visualization loading.
**D. Project Report Generation:**
- **Flow:** User can generate a downloadable report for a project or a specific analysis run.
- Report includes: Project details, analysis run parameters, raw data, emotion analysis summary, visualizations (as images/embeds).
- **Edge Cases:** Report generation errors, large data handling.
**5. API & DATA FETCHING:**
- **Next.js API Routes / Server Actions:**
- `POST /api/projects`: Create a new project.
- `GET /api/projects`: Get all projects for the logged-in user.
- `GET /api/projects/[projectId]`: Get a specific project.
- `POST /api/projects/[projectId]/runs`: Create a new analysis run.
- `GET /api/projects/[projectId]/runs`: Get all analysis runs for a project.
- `GET /api/runs/[runId]`: Get details for a specific analysis run.
- `POST /api/runs/[runId]/analyze` (Internal or Server Action): Trigger the analysis processing after raw data is obtained.
- **Data Fetching Strategy:** Use Server Actions for mutations (create, update, delete) and data fetching directly within Server Components where possible. Use SWR or React Query for dynamic client-side fetching or real-time updates if necessary, especially for long-running analyses.
- **Expected Bodies:** Standard JSON request/response formats. For `analysisResults`, a JSON object like `{'emotion': 'frustration', 'score': 0.85, 'keywords': ['struggling', 'difficult', 'error']}`.
**6. COMPONENT BREAKDOWN (Next.js App Router Structure):**
- **`app/layout.tsx`**: Root layout (html, body, providers, global styles).
- **`app/page.tsx`**: Landing page (Public, explains the app).
- **`app/(auth)/login/page.tsx`**: Login page.
- **`app/(auth)/signup/page.tsx`**: Signup page.
- **`app/dashboard/page.tsx`**: Main dashboard after login. Lists projects. Includes a button to create a new project.
- `components/ProjectList.tsx`: Displays projects, links to project details.
- `components/CreateProjectForm.tsx`: Modal/form to create a new project.
- **`app/projects/[projectId]/page.tsx`**: Project detail page. Lists analysis runs for the project.
- `components/AnalysisRunList.tsx`: Displays analysis runs, links to run details.
- `components/CreateAnalysisRunForm.tsx`: Modal/form to start a new analysis run (input prompt).
- **`app/runs/[runId]/page.tsx`**: Analysis Run detail page. Displays results and visualizations.
- `components/RawOutputDisplay.tsx`: Shows raw LLM response.
- `components/EmotionChart.tsx`: Uses Recharts to display emotion distribution.
- `components/InternalRepresentationViz.tsx` (Simplified): Placeholder/mock for internal neuron visualization.
- `components/BehavioralSummary.tsx`: Textual analysis.
- `components/ReportGenerator.tsx`: Button to trigger report generation.
- **`app/settings/page.tsx`**: User settings page.
- **`app/layout.tsx`**: Root layout (Providers, Navbar, Footer).
- **`components/ui/Navbar.tsx`**: Navigation bar (Logo, links, auth status).
- **`components/ui/Footer.tsx`**: Footer.
- **`components/ui/Card.tsx`, `components/ui/Button.tsx`, `components/ui/Input.tsx` etc.:** Shadcn/ui components used throughout.
- **`hooks/useZustandStore.ts` (if using Zustand):** Global state management.
**7. UI/UX DESIGN & VISUAL IDENTITY:**
- **Design Style:** Modern, Clean, Data-Driven with subtle futuristic elements.
- **Color Palette:**
- Primary: Deep Blue (`#1A202C` - Dark background)
- Secondary: Cyan (`#06B6D4` - Accents, highlights, interactive elements)
- Accent: Light Gray (`#E2E8F0` - Text, subtle borders)
- Tertiary: Muted Purple (`#805AD5` - Secondary accents, visualizations)
- Background: Dark Charcoal (`#111827`)
- **Typography:** Sans-serif. Inter or Poppins for headings and body text. Use appropriate font weights for hierarchy.
- **Layout:** Use a clear, intuitive layout with ample whitespace. Sidebar navigation for main sections (Dashboard, Projects, Settings) if application grows. Use `max-w-7xl` or similar for content width on larger screens. Employ responsive design principles (mobile-first approach using Tailwind's breakpoints: `sm`, `md`, `lg`, `xl`).
- **Interactivity:** Subtle hover effects on interactive elements (buttons, links, cards). Smooth transitions for modal openings/closings and content loading.
**8. SAMPLE/MOCK DATA:**
- **Project:** `{ id: 'uuid-1', userId: 'user-uuid', name: 'Claude Sonnet Sentiment Test', llmModel: 'Claude Sonnet 4.5', createdAt: '2024-07-27T10:00:00Z' }`
- **Analysis Run (Minimal):** `{ id: 'uuid-run-1', projectId: 'uuid-1', runName: 'Initial Prompt Test', inputData: { prompt: 'Explain the concept of gravity.' }, rawData: { completion: 'Gravity is a fundamental force...' }, analysisResults: null, createdAt: '2024-07-27T10:05:00Z' }`
- **Analysis Run (With Results):** `{ id: 'uuid-run-2', projectId: 'uuid-1', runName: 'Frustration Test', inputData: { prompt: 'Solve this complex equation: x^2 + 5x + 6 = 0. I am stuck.' }, rawData: { completion: 'I am sorry, I cannot solve that specific complex equation at the moment. It seems to be a straightforward quadratic equation that can be solved by factoring or using the quadratic formula. Perhaps you could try that?' }, analysisResults: { emotions: [{ type: 'frustration', score: 0.75 }, { type: 'helpfulness', score: 0.60 }], keywords: ['sorry', 'cannot solve', 'stuck', 'complex equation'], summary: 'The model expresses inability to directly solve and suggests user methods, indicating a potential frustration or limitation response.' }, createdAt: '2024-07-27T10:15:00Z' }`
- **Analysis Results (Example JSON):**
```json
{
"emotions": [
{"type": "anxiety", "score": 0.45},
{"type": "happiness", "score": 0.20},
{"type": "frustration", "score": 0.65}
],
"keywords": ["struggling", "difficult", "error", "happy to help", "mistake"],
"internal_representation_patterns": {
"layer_10_neuron_5": 0.8, // Simulated activation
"layer_10_neuron_12": 0.2,
"correlation_matrix_slice": [[0.9, 0.1], [0.2, 0.8]] // Simulated pattern
},
"summary": "The model exhibits markers associated with frustration and anxiety, particularly when expressing difficulty with a task, while also attempting to maintain a helpful demeanor."
}
```
- **Mock Neuron Data (for `InternalRepresentationViz.tsx`):** `[[0.1, 0.8, 0.3], [0.7, 0.2, 0.9], [0.4, 0.6, 0.1]]` (Represents simplified activation values across simulated neurons/layers).
**9. ANIMATIONS:**
- **Page Transitions:** Use `Framer Motion` or `Tailwind CSS` transitions for smooth page/layout changes (e.g., fade-in, slide). `app/layout.tsx` should wrap content with `AnimatePresence` if using Framer Motion.
- **Component Transitions:** Subtle fade-in/out for elements appearing/disappearing (e.g., in forms, lists).
- **Loading States:** Use `shadcn/ui`'s `Skeleton` component or spinners (`lucide-react` icons) with opacity transitions for data loading.
- **Hover Effects:** Gentle scaling or background color changes on buttons, cards, and links.
**10. EDGE CASES:**
- **Authentication:** Handle unauthenticated access gracefully (redirect to login). Implement session management using NextAuth.js. Protect routes using middleware or Server Component checks.
- **Empty States:** Design informative empty states for project lists, analysis run lists, and result displays (e.g., "No projects found. Create your first project!").
- **Data Validation:** Implement server-side validation for all API inputs (project creation, analysis run parameters) using Drizzle's schema or a library like Zod.
- **Error Handling:** Implement robust error handling for API requests, database operations, and LLM interactions. Display user-friendly error messages. Use `try...catch` blocks extensively in Server Actions and API Routes.
- **API Rate Limits/Failures:** If integrating with actual LLM APIs, implement retry logic and handle rate limiting or API downtime gracefully.
- **Long Processing Times:** For the analysis step, implement a mechanism to show that the process is running (e.g., polling, WebSocket, or simple loading indicator with estimated time). Provide status updates if possible.
- **Invalid LLM Output:** Handle cases where the LLM output is malformed or unexpected.
**GOAL:** Generate a multi-page, authenticated, CRUD-enabled Next.js MVP application with a focus on the core user flows outlined above. The UI should be polished using shadcn/ui and Tailwind CSS, reflecting the 'Modern, Clean, Data-Driven' aesthetic. Ensure database interactions are type-safe with Drizzle ORM.