You are an expert AI assistant tasked with building a fully functional MVP of a SaaS application called 'HackerNews Insights'. This application will scrape popular articles from Hacker News, analyze their content, and provide concise, insightful summaries in both English and Turkish. The goal is to make complex research findings accessible to a broad audience interested in social psychology, behavioral science, technology, and related fields.
PROJECT OVERVIEW:
'HackerNews Insights' aims to solve the problem of information overload and the difficulty of accessing and understanding complex research findings. By leveraging Hacker News's trending topics, the platform will identify significant articles and generate digestible summaries, helping users stay informed on cutting-edge developments without needing to read through lengthy academic papers or dense articles. The core value proposition is to provide curated, summarized knowledge from the tech and science community in an easily consumable format, catering to both English and Turkish speakers.
TECH STACK:
- Framework: Next.js (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: shadcn/ui
- ORM: Drizzle ORM (with PostgreSQL via Vercel Postgres or Supabase)
- Authentication: NextAuth.js (with credentials provider for email/password and Google OAuth)
- State Management: Zustand or React Context API for global state, component-local state where appropriate.
- API Calls: React Query (TanStack Query) for efficient data fetching and caching.
- Web Scraping (Backend): Cheerio.js or similar for parsing HTML on the server.
- LLM Integration (Backend): OpenAI API (or similar) for text summarization. Use gpt-4o-mini or similar for cost-efficiency in MVP.
DATABASE SCHEMA:
(Using Drizzle ORM syntax for PostgreSQL)
1. **Users Table**
- `id`: uuid @id @default(cuid())
- `name`: varchar(255)
- `email`: varchar(255) @unique
- `emailVerified`: timestamp
- `image`: text
- `hashedPassword`: text
- `createdAt`: timestamp @default(now())
- `updatedAt`: timestamp @default(now())
2. **Accounts Table** (for NextAuth.js)
- `userId`: uuid @index
- `type`: varchar(255)
- `provider`: varchar(255)
- `providerAccountId`: varchar(255)
- `refresh_token`: text
- `access_token`: text
- `expires_at`: timestamp
- `token_type`: varchar(255)
- `scope`: varchar(255)
- `id_token`: text
- `session_state`: varchar(255)
- `createdAt`: timestamp @default(now())
- `updatedAt`: timestamp @default(now())
- @unique([provider, providerAccountId])
3. **Sessions Table** (for NextAuth.js)
- `sessionToken`: varchar(255) @id
- `userId`: uuid @index
- `expires`: timestamp
- `createdAt`: timestamp @default(now())
- `updatedAt`: timestamp @default(now())
4. **VerificationTokens Table** (for NextAuth.js)
- `identifier`: varchar(255)
- `token`: varchar(255)
- `expires`: timestamp
- `createdAt`: timestamp @default(now())
- `updatedAt`: timestamp @default(now())
- @unique([identifier, token])
5. **Articles Table**
- `id`: uuid @id @default(cuid())
- `hnId`: bigint @unique // Hacker News Item ID
- `title`: varchar(255) @index
- `url`: text // Original URL
- `author`: varchar(255)
- `score`: integer
- `hnUrl`: text // Direct link to HN discussion
- `createdAt`: timestamp @default(now())
- `summaryEn`: text // English summary
- `summaryTr`: text // Turkish summary
- `fetchStatus`: varchar(50) @default('pending') // 'pending', 'processing', 'completed', 'failed'
- `tags`: json[] // Array of tags, e.g., ['psychology', 'ai']
6. **UserSavedArticles Table** (Many-to-Many relationship between Users and Articles)
- `userId`: uuid @index
- `articleId`: uuid @index
- `savedAt`: timestamp @default(now())
- @primaryKey([userId, articleId])
7. **UserPreferences Table**
- `userId`: uuid @id @index
- `preferredLanguage`: varchar(10) @default('en') // 'en' or 'tr'
- `followedTags`: json[] // Array of tags user wants to follow
- `notificationsEnabled`: boolean @default(true)
CORE FEATURES & USER FLOW:
1. **Article Fetching & Summarization (Backend - Scheduled Job/API Trigger):**
* **Flow:** A scheduled server job or an API endpoint triggered periodically (e.g., every hour).
* Fetches the top stories IDs from Hacker News API (`https://hacker-news.firebaseio.com/v0/topstories.json`).
* For each ID, fetches item details (`https://hacker-news.firebaseio.com/v0/item/{id}.json`).
* Filters out jobs, comments, and items with missing URLs or very low scores.
* Checks if the article (based on `hnId`) already exists in the `Articles` table.
* If new, creates an entry in `Articles` table with `fetchStatus: 'pending'`. If processing is needed, updates status to `'processing'`.
* For articles with `fetchStatus: 'pending'`, fetches the full article content using a scraping tool (e.g., Cheerio) from the article's `url`.
* Extracts the main text content from the scraped HTML.
* Sends the extracted text to the OpenAI API to generate an English summary.
* Sends the extracted text (or English summary) to OpenAI API to generate a Turkish summary.
* Updates the `Articles` table entry with the generated `summaryEn`, `summaryTr`, `tags` (extracted from content or inferred), and sets `fetchStatus: 'completed'`. Handles potential errors by setting `fetchStatus: 'failed'` and logging the error.
2. **User Authentication:**
* **Flow:** Users can sign up using email/password or Google OAuth. They can log in using either method.
* **Signup:** User navigates to `/signup`. Enters email, password, confirm password. Backend validation. If valid, user record created, email verification sent (optional for MVP). Password hashed and stored. Google OAuth redirects to Google for authentication, then callback creates/logs in user.
* **Login:** User navigates to `/login`. Enters credentials or clicks Google Login. Backend validates credentials or handles OAuth callback. Session created using NextAuth.js. User redirected to dashboard.
* **Logout:** User clicks logout button. Session destroyed. Redirected to login page.
3. **Article Listing & Display:**
* **Flow:** Authenticated users land on the main dashboard (`/dashboard`).
* Fetches a list of `completed` articles from the `Articles` table using React Query.
* Displays articles in a feed, showing title, author, score, and a snippet of the summary (English by default, or user's preferred language).
* Provides options to view the full summary, read the original article, or view the HN discussion.
* **Turkish Translation:** UI elements (titles, buttons) and summaries are displayed based on `userPreferences.preferredLanguage`.
4. **Article Filtering & Search:**
* **Flow:** On the dashboard, users can filter articles by `tags` (e.g., 'psychology', 'AI', 'neuroscience') or search by keywords in the title or summary.
* UI includes dropdowns/multi-select for tags and a search input field.
* On input change/submit, the frontend sends filter/search parameters to an API endpoint.
* The API endpoint queries the `Articles` table with appropriate `WHERE` clauses (e.g., `tags @> ARRAY['psychology']` or `title ILIKE '%keyword%'`).
* Returns filtered/searched articles, which are then displayed.
5. **Saving Articles (Bookmarking):**
* **Flow:** Users can save articles they find interesting.
* On an article card, a 'Save' button/icon is present. Clicking it triggers an API call.
* API endpoint (`POST /api/save-article`) receives `articleId`. It creates a record in the `UserSavedArticles` table linking the current `userId` to the `articleId`.
* If the article is already saved, the button state changes to 'Saved', and clicking again removes the entry (handled by the `DELETE` API call).
* A dedicated page (`/saved-articles`) displays all articles saved by the user, queried from `UserSavedArticles` joined with `Articles`.
6. **User Preferences:**
* **Flow:** Users can configure their preferences.
* A `/settings` page allows users to select their `preferredLanguage` ('en' or 'tr') and choose `followedTags`.
* Changes are saved via an API call to update the `UserPreferences` table for the logged-in user.
* The application UI (e.g., summary language) dynamically updates based on these preferences.
API & DATA FETCHING:
- **API Routes (Next.js App Router):**
- `POST /api/auth/...`: Handled by NextAuth.js for login, signup, logout.
- `GET /api/articles`: Fetches a list of articles (paginated, filtered, searchable). Accepts query params like `?page=1&limit=10&tag=psychology&q=obedience`.
- `GET /api/articles/[id]`: Fetches a single article details.
- `POST /api/save-article`: Saves an article for the logged-in user. Requires `articleId` in the request body. Returns `{ success: true }`.
- `DELETE /api/save-article`: Unsaves an article. Requires `articleId` in the request body. Returns `{ success: true }`.
- `GET /api/saved-articles`: Fetches articles saved by the current user.
- `PUT /api/settings`: Updates user preferences (`preferredLanguage`, `followedTags`).
- `GET /api/tags`: Fetches a list of all unique tags from the `Articles` table for filtering UI.
- **Data Fetching (Client-side):** Use React Query (`useQuery`, `useMutation`) hooks in components to interact with the API routes. Cache data, manage loading/error states, and implement background refetching.
- **Data Flow:** Components call React Query hooks. Hooks trigger API calls. API routes interact with the database via Drizzle ORM. Results are returned to the client and managed by React Query's state.
COMPONENT BREAKDOWN (Next.js App Router Structure):
- **`app/`**
- **`layout.tsx`**: Root layout (HTML, Head, Body, global providers like NextAuth, QueryClientProvider).
- **`page.tsx`**: Landing page (public, introduces the app, CTA to sign up/login).
- **`login/page.tsx`**: Login form (email/password, Google OAuth button).
- **`signup/page.tsx`**: Signup form (email/password).
- **`dashboard/page.tsx`**: Main application view after login. Displays the list of articles. Includes filtering and search components.
- `components/ArticleList.tsx`: Fetches and displays `ArticleCard` components.
- `components/ArticleFilter.tsx`: Contains tag selection and search input.
- **`articles/[id]/page.tsx`**: Dynamic route for viewing a single article's full details and summary.
- **`saved-articles/page.tsx`**: Displays articles saved by the user.
- **`settings/page.tsx`**: User settings page (language, followed tags).
- **`api/auth/[...nextauth]/route.ts`**: NextAuth.js API route handler.
- **`api/articles/route.ts`**: API route for GET `/api/articles`.
- **`api/articles/[id]/route.ts`**: API route for GET `/api/articles/[id]`.
- **`api/save-article/route.ts`**: API routes for POST/DELETE `/api/save-article`.
- **`api/settings/route.ts`**: API route for PUT `/api/settings`.
- **`api/tags/route.ts`**: API route for GET `/api/tags`.
- **`components/`**
- **`ui/`**: Re-exports from shadcn/ui (e.g., `Button`, `Input`, `Card`, `DropdownMenu`, `Sheet`, `Avatar`).
- **`Navbar.tsx`**: Top navigation bar (logo, links, user avatar/logout button).
- **`ArticleCard.tsx`**: Renders a single article preview in the list.
- **`Footer.tsx`**: Application footer.
- **`LoadingSpinner.tsx`**: Generic loading indicator.
- **`ErrorBoundary.tsx`**: Component for handling errors gracefully.
UI/UX DESIGN & VISUAL IDENTITY:
- **Design Style:** Modern Minimalist Clean with a focus on readability and clarity.
- **Color Palette:**
- Primary: `#0077CC` (Clean Blue)
- Secondary: `#333333` (Dark Gray for text)
- Accent: `#FF6F61` (Coral Red for CTAs, highlights)
- Background: `#F8F9FA` (Light Gray/Off-white)
- Card Background: `#FFFFFF` (White)
- **Typography:**
- Headings: Inter (Variable Font), weight 700
- Body Text: Inter (Variable Font), weight 400
- **Layout:** Single-column feed on mobile, expanding to a two-column layout on larger screens (e.g., dashboard with feed and filters side-by-side). Use Max-width container for content.
- **Interactions:** Subtle hover effects on buttons and cards. Smooth transitions for loading states and route changes.
- **Responsiveness:** Mobile-first design. Ensure usability across all screen sizes using Tailwind CSS's responsive modifiers (`sm:`, `md:`, `lg:`).
ANIMATIONS:
- **Page Transitions:** Use `AnimatePresence` from `framer-motion` (if needed, or rely on Next.js App Router's built-in transitions) for smooth fade-ins/outs between pages.
- **Loading States:** `LoadingSpinner.tsx` displayed while data is fetching (controlled by React Query's `isFetching` state). Shimmer effect placeholders for cards could be used for a more advanced feel.
- **Hover Effects:** Slight scale-up or shadow change on `ArticleCard` and buttons on hover.
- **Button Interactions:** Subtle press effect on click.
EDGE CASES:
- **No Articles Found:** Display a clear message on the dashboard/saved articles page if no articles match the filters or if the user hasn't saved any.
- **API Errors:** Gracefully handle API errors (e.g., network issues, server errors) using React Query's `isError` state and display user-friendly error messages. Use `ErrorBoundary` component.
- **Authentication:** Redirect unauthenticated users to the login page. Protect API routes that require authentication.
- **Empty States:** The dashboard should show a placeholder or informative message if no articles have been summarized yet.
- **Scraping Failures:** If an article's content cannot be scraped, mark it as `fetchStatus: 'failed'` and potentially log the URL for review.
- **Summarization Failures:** If the LLM fails to generate a summary, mark as `fetchStatus: 'failed'`. Implement retries or fallback mechanisms.
- **Validation:** Implement robust client-side and server-side validation for forms (login, signup, settings).
SAMPLE DATA (for `Articles` table):
1. `{ hnId: 39123456, title: 'AI breakthroughs in protein folding', url: 'https://example.com/ai-protein', author: 'ai_researcher', score: 550, hnUrl: 'https://news.ycombinator.com/item?id=39123456', summaryEn: 'Recent advancements show AI models achieving near-perfect accuracy in predicting protein structures, accelerating drug discovery.', summaryTr: 'Yapay zeka modellerinin protein yapılarını tahmin etmede neredeyse mükemmel doğruluk sağlayan son gelişmeler, ilaç keşfini hızlandırıyor.', fetchStatus: 'completed', tags: ['ai', 'biology', 'research'] }`
2. `{ hnId: 39123500, title: 'The psychology of remote work productivity', url: 'https://example.com/remote-psych', author: 'psych_prof', score: 320, hnUrl: 'https://news.ycombinator.com/item?id=39123500', summaryEn: 'A study explores factors influencing productivity in remote work environments, highlighting the importance of autonomy and clear communication.', summaryTr: 'Uzaktan çalışma ortamlarında üretkenliği etkileyen faktörleri inceleyen bir çalışma, özerklik ve net iletişimin önemini vurguluyor.', fetchStatus: 'completed', tags: ['psychology', 'work', 'remote'] }`
3. `{ hnId: 39123600, title: 'New study on dark matter distribution', url: 'https://example.com/dark-matter', author: 'astro_phys', score: 780, hnUrl: 'https://news.ycombinator.com/item?id=39123600', summaryEn: 'Astronomers have mapped dark matter with unprecedented detail using gravitational lensing techniques, revealing new insights into cosmic structure formation.', summaryTr: 'Astronomlar, kütleçekimsel merceklenme tekniklerini kullanarak karanlık maddeyi benzeri görülmemiş bir ayrıntıyla haritalandırarak kozmik yapı oluşumu hakkında yeni bilgiler ortaya koydu.', fetchStatus: 'completed', tags: ['physics', 'astronomy', 'cosmology'] }`
4. `{ hnId: 39123700, title: 'Ethical considerations in AI development', url: 'https://example.com/ai-ethics', author: 'ethicist_ai', score: 410, hnUrl: 'https://news.ycombinator.com/item?id=39123700', summaryEn: 'This article discusses the ethical challenges posed by advanced AI, including bias, transparency, and accountability, and proposes frameworks for responsible development.', summaryTr: 'Bu makale, yapay zeka (YZ) alanındaki önyargı, şeffaflık ve hesap verebilirlik gibi etik zorlukları tartışıyor ve sorumlu geliştirme için çerçeveler öneriyor.', fetchStatus: 'completed', tags: ['ai', 'ethics', 'technology'] }`
5. `{ hnId: 39123800, title: 'Urban planning and sustainable cities', url: 'https://example.com/urban-sustain', author: 'urban_planner', score: 250, hnUrl: 'https://news.ycombinator.com/item?id=39123800', summaryEn: 'Examining the role of innovative urban planning in creating sustainable, livable cities for the future, focusing on green infrastructure and smart technology.', summaryTr: 'Gelecek için sürdürülebilir, yaşanabilir şehirler yaratmada yenilikçi şehir planlamasının rolünü inceleyerek, yeşil altyapı ve akıllı teknolojiye odaklanıyor.', fetchStatus: 'completed', tags: ['urbanism', 'sustainability', 'technology', 'policy'] }`
6. `{ hnId: 39123900, title: 'The impact of social media on mental health', url: 'https://example.com/social-media-mental', author: 'social_psych', score: 600, hnUrl: 'https://news.ycombinator.com/item?id=39123900', summaryEn: 'A comprehensive review of studies linking social media usage patterns to various mental health outcomes, including depression, anxiety, and loneliness.', summaryTr: 'Sosyal medya kullanım biçimlerini depresyon, anksiyete ve yalnızlık dahil olmak üzere çeşitli ruh sağlığı sonuçlarıyla ilişkilendiren çalışmaların kapsamlı bir incelemesi.', fetchStatus: 'completed', tags: ['psychology', 'social media', 'mental health'] }`
7. `{ hnId: 39124000, title: 'Quantum computing advancements', url: 'https://example.com/quantum-adv', author: 'quantum_guru', score: 480, hnUrl: 'https://news.ycombinator.com/item?id=39124000', summaryEn: 'New research demonstrates significant progress in qubit stability and error correction, paving the way for more powerful quantum computers.', summaryTr: 'Yeni araştırmalar, kübit kararlılığı ve hata düzeltmede önemli ilerlemeler kaydederek daha güçlü kuantum bilgisayarlarının yolunu açıyor.', fetchStatus: 'completed', tags: ['technology', 'physics', 'computing', 'quantum'] }`