## AI Coding Master Prompt: AI Chronicle MVP
**1. PROJECT OVERVIEW:**
AI Chronicle is a web application designed to help users document and organize their journey through the rapidly evolving AI era, starting from the launch of ChatGPT. The application addresses the problem of fragmented information and fleeting experiences users have with AI tools. It provides a structured platform for individuals to record their interactions, experiments, generated content, prompts, and personal reflections related to AI. The core value proposition is to offer a personal AI timeline, a digital journal for the AI age, enabling users to track their learning, creativity, and the impact of AI on their lives and work in a coherent and accessible manner. This is not just a note-taking app; it's a personal archive of the AI revolution.
**2. TECH STACK:**
- **Framework:** Next.js (App Router)
- **Language:** TypeScript
- **Styling:** Tailwind CSS
- **ORM:** Drizzle ORM with a PostgreSQL database (using Vercel Postgres or a similar managed solution)
- **UI Library:** shadcn/ui for accessible and customizable components
- **Authentication:** NextAuth.js (with Google, GitHub, and Email/Password providers)
- **State Management:** React Context API / Zustand (for global state if needed, otherwise component state)
- **Form Handling:** React Hook Form + Zod for validation
- **Date Handling:** date-fns or Day.js
- **Deployment:** Vercel
**3. DATABASE SCHEMA (Drizzle ORM - PostgreSQL):**
```typescript
import { pgTable, serial, text, timestamp, varchar, uuid, primaryKey, integer, jsonb } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// Users Table
export const users = pgTable('users', {
id: uuid('id').primaryKey(),
name: varchar('name'),
email: varchar('email', { length: 255 }).notNull().unique(),
emailVerified: timestamp('emailVerified', { mode: 'date' }),
image: text('image'),
createdAt: timestamp('createdAt', { mode: 'date', withTimezone: true }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date', withTimezone: true }).defaultNow(),
});
export const accounts = pgTable(
'accounts',
{
access_token: text('access_token'),
expires_at: integer('expires_at'),
id_token: text('id_token'),
provider: varchar('provider', { length: 255 }).notNull(),
providerAccountId: varchar('providerAccountId', { length: 255 }).notNull(),
refresh_token: text('refresh_token'),
scope: text('scope'),
session_state: varchar('session_state', { length: 255 }).putters,
type: varchar('type', { length: 255 }).$type<"oauth" | "email" | "credentials">().notNull(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
},
(account) => ({
compoundKey: primaryKey(account.provider, account.providerAccountId),
})
);
export const sessions = pgTable('sessions', {
sessionToken: text('sessionToken').primaryKey(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
expires: timestamp('expires', { mode: 'date', withTimezone: true }).notNull(),
});
export const verificationTokens = pgTable(
'verificationTokens',
{
identifier: text('identifier').notNull(),
token: text('token').notNull(),
expires: timestamp('expires', { mode: 'date', withTimezone: true }).notNull(),
},
(vt) => ({
compoundKey: primaryKey(vt.identifier, vt.token),
})
);
// AI Chronicle Entry Table
export const aiEntries = pgTable('ai_entries', {
id: uuid('id').primaryKey(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
title: varchar('title', { length: 255 }).notNull(),
content: text('content').notNull(),
entryType: varchar('entryType', { length: 50 }).$type<"Note" | "Experiment" | "GeneratedContent" | "Prompt" | "Reflection">().notNull(), // e.g., 'Note', 'Experiment', 'GeneratedContent', 'Prompt', 'Reflection'
tags: jsonb('tags').default([]), // Array of strings for tags
createdAt: timestamp('createdAt', { mode: 'date', withTimezone: true }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date', withTimezone: true }).defaultNow(),
});
// Relations
export const usersRelations = relations(users, ({ many }) => ({
aiEntries: many(aiEntries),
}));
export const aiEntriesRelations = relations(aiEntries, ({ one }) => ({
user: one(users, {
fields: [aiEntries.userId],
references: [users.id],
}),
}));
// Types (for Drizzle)
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
export type Account = typeof accounts.$inferSelect;
export type NewAccount = typeof accounts.$inferInsert;
export type Session = typeof sessions.$inferSelect;
export type NewSession = typeof sessions.$inferInsert;
export type VerificationToken = typeof verificationTokens.$inferSelect;
export type NewVerificationToken = typeof verificationTokens.$inferInsert;
export type AiEntry = typeof aiEntries.$inferSelect;
export type NewAiEntry = typeof aiEntries.$inferInsert;
```
**4. CORE FEATURES & USER FLOW:**
* **Authentication (NextAuth.js):**
* **Flow:** User lands on the homepage. Clicks 'Sign In'. Presented with Google, GitHub, and Email/Password options. Upon successful authentication, redirected to the dashboard. Sign out option available in user menu.
* **Edge Cases:** Invalid credentials, email verification flow for email/password, provider errors.
* **Dashboard (`/dashboard`):**
* **Flow:** Authenticated user lands here. Displays a summary: recent entries, total entries, quick links to create new entries. Shows a chronological feed of the user's AI entries, sortable by date. If no entries, shows a prompt to create the first one.
* **Components:** `DashboardLayout`, `RecentEntries`, `EntryFeed`, `CreateEntryButton`.
* **Create/Edit Entry (`/dashboard/entries/new` or `/dashboard/entries/[id]/edit`):**
* **Flow:** User clicks 'Create New Entry'. A form appears with fields: Title (required), Content (rich text editor preferred, or markdown), Entry Type (dropdown: Note, Experiment, Generated Content, Prompt, Reflection), Tags (input with suggestions/creation).
* **Saving:** 'Save' button submits the form. On success, user is redirected to the entry view or dashboard. 'Cancel' button discards changes.
* **Editing:** User navigates to an entry, clicks 'Edit'. The form pre-populates with existing data.
* **Components:** `EntryForm` (reusable for new and edit), `RichTextEditor` (or Markdown editor), `TagInput`, `EntryTypeSelector`.
* **View Entry (`/dashboard/entries/[id]`):**
* **Flow:** User clicks on an entry from the dashboard or feed. Displays the entry details: title, content, type, tags, creation/update dates.
* **Actions:** 'Edit' button, 'Delete' button (with confirmation modal).
* **Components:** `EntryDetailView`, `TagDisplay`, `ActionButtons`.
* **Tagging & Filtering:**
* **Flow:** When creating/editing an entry, users can add multiple tags. On the dashboard or a dedicated `/tags` page, users can click on a tag to see all entries associated with it.
* **Components:** `TagInput`, `TagList`, `FilteredEntryFeed`.
**5. API & DATA FETCHING (Next.js App Router - Server Actions & Route Handlers):**
* **Authentication:** Handled by NextAuth.js. Server components can access session data via `auth()`.
* **Create Entry:** Use a Server Action (`'use server'`) within `EntryForm`. Takes form data, validates with Zod, inserts into `aiEntries` table via Drizzle.
* **Update Entry:** Similar Server Action, finds entry by ID and updates.
* **Delete Entry:** Server Action, finds and deletes entry by ID.
* **Fetch Entries (Dashboard/Feed):** Server Component fetches entries using Drizzle (`db.query.aiEntries.findMany({ where: eq(aiEntries.userId, session.user.id), orderBy: desc(aiEntries.createdAt) })`). Data is directly passed to the component.
* **Fetch Single Entry:** Server Component fetches a single entry by ID for the view/edit page.
* **Fetch Entries by Tag:** Route Handler (`/api/entries/tag/[tag]`) or Server Action that accepts a tag and returns filtered entries for a specific user.
* **Data Structure Examples:**
* `POST /api/entries` (Server Action equivalent): `{ title: string, content: string, entryType: string, tags: string[] }` -> `{ success: boolean, id: string | null }`
* `GET /api/entries` (Server Component Fetch): `[]AiEntry`
* `GET /api/entries/[id]` (Server Component Fetch): `AiEntry | null`
* `DELETE /api/entries/[id]` (Server Action equivalent): `{ success: boolean }`
**6. COMPONENT BREAKDOWN (Next.js App Router):**
* **`app/layout.tsx`:** Root layout, includes `<html>`, `<body>`, global providers (e.g., ThemeProvider), and potentially global loading states.
* **`app/page.tsx`:** Landing page (before login). Brief intro, feature highlights, CTA to sign up/in.
* **`app/dashboard/layout.tsx`:** Dashboard layout, includes `Header`, `Sidebar` (if applicable), and `main` content area. Handles authentication checks.
* **`app/dashboard/page.tsx`:** Dashboard main view. Fetches and displays `EntryFeed` and `RecentEntries` components. Includes `CreateEntryButton`.
* **`app/dashboard/entries/new/page.tsx`:** Page for creating a new entry. Renders `EntryForm` component.
* **`app/dashboard/entries/[id]/page.tsx`:** Page to view a single entry. Fetches entry data and renders `EntryDetailView`.
* **`app/dashboard/entries/[id]/edit/page.tsx`:** Page for editing an existing entry. Fetches entry data and renders `EntryForm` pre-populated.
* **`app/dashboard/tags/[tag]/page.tsx`:** Page to view entries filtered by a specific tag.
* **`app/auth/signin/page.tsx`:** Sign-in page using NextAuth.js.
* **Reusable UI Components (located in `components/ui/` and `components/`):**
* `Header.tsx`: Navigation, user profile dropdown, sign out button.
* `Sidebar.tsx`: Navigation links (Dashboard, All Entries, Tags, Settings).
* `EntryCard.tsx`: Displays a summary of an entry in the feed.
* `EntryForm.tsx`: The core form for creating/editing entries. Uses `ReactHookForm`, `Zod`, `RichTextEditor`, `TagInput`.
* `TagInput.tsx`: Component for adding/managing tags.
* `TagDisplay.tsx`: Renders a list of tags for an entry.
* `TagLink.tsx`: A clickable tag that links to the filtered view.
* `RichTextEditor.tsx`: Wrapper around a rich text editor library (e.g., TipTap, Quill, or a simple textarea for MVP).
* `DataTable.tsx`: Potentially for a more advanced entry list with sorting/filtering (future MVP).
* `AlertDialog.tsx`: For confirmations (e.g., delete entry).
* `Button.tsx`, `Input.tsx`, `Label.tsx`, `DropdownMenu.tsx`, `Select.tsx` (from shadcn/ui).
* **State Management:** Primarily server-driven with Server Components fetching data. Client-side state for form inputs, UI toggles (modals, dropdowns) using `useState`, `useReducer`, or Zustand for simpler global needs.
**7. UI/UX DESIGN & VISUAL IDENTITY:**
* **Design Style:** "Minimalist Clean with Subtle AI Accents". Focus on clarity, readability, and a professional yet approachable feel.
* **Color Palette:**
* Primary: `#0A84FF` (Vibrant Blue)
* Secondary: `#5856D6` (Muted Purple)
* Background: `#F2F2F7` (Light Gray)
* Card/Surface: `#FFFFFF` (White)
* Text (Primary): `#1C1C1E` (Near Black)
* Text (Secondary): `#8E8E93` (Gray)
* Accent/AI Element: `#64D2FF` (Light Cyan - used sparingly for highlights, loading indicators)
* **Typography:** System fonts for maximum readability and performance. SF Pro (macOS/iOS), Roboto (Android), Inter (Web fallback).
* Headings: Bold, varying weights.
* Body Text: Regular weight, comfortable line height (e.g., 1.6).
* **Layout:** Clean, card-based design for entries. Responsive sidebar/header. Content area with ample whitespace. Use Next.js App Router's layout conventions.
* **Sections:** Header with logo and user menu. Main content area displaying feeds, forms, or entry details. Optional sidebar for navigation.
* **Responsiveness:** Mobile-first approach. Single column on small screens, expanding to two or more columns and potentially a sidebar on larger screens.
* **Visual Elements:** Subtle gradients in accents, clean icons, possibly a minimalist, abstract visualization of data connections or timelines on loading states or empty states.
**8. SAMPLE/MOCK DATA (for `ai_entries` table):**
1. **Type:** Experiment, **Title:** 'Testing GPT-4o for Code Generation', **Content:** 'Tried asking GPT-4o to write a Python script for web scraping using BeautifulSoup. It produced functional code but missed error handling for missing elements. Accuracy improved significantly compared to previous models.', **Tags:** ['GPT-4o', 'code generation', 'Python', 'web scraping']
2. **Type:** GeneratedContent, **Title:** 'Sci-Fi Short Story: The Last Starlight', **Content:** 'A short story about the final moments of a dying star, from the perspective of an ancient alien observer. Prompt used: "Write a 500-word melancholic sci-fi short story about the last starlight reaching an observer, focusing on themes of time and loss.".', **Tags:** ['creative writing', 'AI story', 'sci-fi', 'prompt']
3. **Type:** Prompt, **Title:** 'Complex D&D World Building Prompt', **Content:** '/imagine prompt: A sprawling medieval fantasy city built into the side of a giant, ancient tree, with bioluminescent flora lighting the winding streets. The inhabitants are a mix of elves and dwarves who have learned to coexist. Focus on architectural details and the atmosphere of wonder and mystery. Style: detailed illustration, volumetric lighting --ar 16:9', **Tags:** ['D&D', 'world building', 'prompt engineering', 'fantasy']
4. **Type:** Reflection, **Title:** 'Initial Thoughts on AI Image Generation Costs', **Content:** 'The cost of generating high-quality images with tools like Midjourney or Stable Diffusion is still a barrier for casual users. While the output is amazing, the credits/subscription model can add up quickly for hobbyists.', **Tags:** ['AI art', 'Midjourney', 'Stable Diffusion', 'cost analysis', 'reflection']
5. **Type:** Note, **Title:** 'Remember to check Hugging Face for new models', **Content:** 'Discovered a new open-source LLM on Hugging Face, 'Llama-3-8B-Instruct'. Worth testing for summarization tasks.', **Tags:** ['LLM', 'Hugging Face', 'model testing']
6. **Type:** GeneratedContent, **Title:** 'React Component Snippet for Modal', **Content:** '```jsx
import React, { useState } from 'react';
const Modal = ({ isOpen, onClose, children }) => {
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
<div className="bg-white p-6 rounded-lg shadow-lg">
{children}
<button onClick={onClose} className="mt-4 px-4 py-2 bg-gray-200 rounded">Close</button>
</div>
</div>
);
};
export default Modal;
```', **Tags:** ['React', 'code snippet', 'frontend', 'component']
**9. TURKISH TRANSLATIONS:**
* **App Title:** AI Günlüğü (AI Chronicle)
* **Navigation:** Pano (Dashboard), Tüm Kayıtlar (All Entries), Etiketler (Tags), Ayarlar (Settings), Oturumu Kapat (Sign Out)
* **Buttons:** Yeni Kayıt Oluştur (Create New Entry), Kaydet (Save), İptal (Cancel), Düzenle (Edit), Sil (Delete), Onayla (Confirm), Kapat (Close)
* **Form Fields:** Başlık (Title), İçerik (Content), Kayıt Türü (Entry Type), Etiketler (Tags)
* **Entry Types:** Not (Note), Deney (Experiment), Üretilen İçerik (Generated Content), Prompt, Yansıma (Reflection)
* **Placeholders/Empty States:** 'AI yolculuğunuzu belgelemeye başlayın.' (Start documenting your AI journey.), 'Henüz kayıt yok.' (No entries yet.), 'Bu etikete sahip kayıt bulunamadı.' (No entries found with this tag.)
* **Auth:** Google ile Giriş Yap (Sign in with Google), GitHub ile Giriş Yap (Sign in with GitHub), E-posta ile Giriş Yap (Sign in with Email)
**10. ANIMATIONS:**
* **Page Transitions:** Subtle fade-in/slide-in animations for new pages or content loading.
* **Hover Effects:** Slight scale or background color change on interactive elements like buttons and links.
* **Loading Indicators:** Use shadcn/ui's `SkeletonLoader` or a subtle spinner/progress bar during data fetching.
* **Form Transitions:** Smooth appearance/disappearance of form elements or success/error messages.
* **Entry Card:** Subtle hover effect, perhaps a slight shadow increase.
**11. EDGE CASES:**
* **Authentication:** Handle expired sessions, failed login attempts gracefully. Implement email verification for email/password signups.
* **Empty States:** Design informative and encouraging empty states for the dashboard, tag views, and search results.
* **Data Validation:** Robust validation on all form inputs (title, content length, entry type selection) using Zod and React Hook Form.
* **Error Handling:** Display user-friendly error messages for API failures or validation errors. Use toasts or inline messages.
* **Permissions:** Ensure users can only access and modify their own entries (enforced server-side).
* **Large Content:** Handle potentially long text content and rich text editor state efficiently.
* **Tag Management:** Ensure tags are cleaned (trimmed, consistent casing if needed) before saving.
* **Rate Limiting:** Consider basic rate limiting on auth endpoints if using email/password. (Less critical for MVP with Vercel).