# PROJECT OVERVIEW
**Project Name:** Open Source Insights
**Goal:** To create a robust SaaS platform that analyzes and reports on the internal dynamics, corporate conflicts, and community-management issues within open-source projects. The platform aims to provide an unbiased, external perspective, identifying root causes of problems, offering strategic recommendations, and highlighting potential risks and opportunities in the open-source ecosystem.
**Problem Solved:** Many open-source projects suffer from internal disagreements, corporate interference, and management complexities, leading to public speculation and potential project failure (as exemplified by the LibreOffice situation). This platform provides clarity by dissecting these complex situations, offering data-driven insights, and fostering transparency.
**Value Proposition:** Empowering developers, project managers, companies, and analysts with deep, actionable intelligence on the health and dynamics of open-source projects, enabling better decision-making and risk mitigation.
# TECH STACK
* **Frontend:** React (Next.js App Router)
* **Styling:** Tailwind CSS
* **Backend/ORM:** Drizzle ORM (with PostgreSQL as the database)
* **Authentication:** NextAuth.js (or Clerk for easier setup)
* **UI Components:** shadcn/ui
* **State Management:** React Context API / Zustand
* **Data Fetching:** React Server Components (RSC) with Server Actions, SWR/React Query for client-side caching if needed.
* **Charting:** Recharts or Chart.js
* **Deployment:** Vercel
# DATABASE SCHEMA (PostgreSQL with Drizzle ORM)
```typescript
// Schema definition file (e.g., schema.ts)
import { pgTable, serial, text, timestamp, varchar, boolean, jsonb, integer, primaryKey, foreignKey, uniqueIndex }
from 'drizzle-orm/pg-core';
// Users Table for Authentication
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name'),
email: varchar('email', { length: 255 }).notNull().unique(),
emailVerified: timestamp('emailVerified', { mode: 'date' }),
image: text('image'),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// Projects Table
export const projects = pgTable('projects', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 255 }).notNull().unique(),
sourceUrl: text('sourceUrl'), // e.g., GitHub repo URL
description: text('description'),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// Analysis Entities (Posts, Articles, Comments)
export const analysisEntities = pgTable('analysis_entities', {
id: serial('id').primaryKey(),
projectId: integer('project_id').notNull().references(() => projects.id, { onDelete: 'cascade' }),
title: text('title'),
content: text('content'),
author: varchar('author', { length: 255 }),
source: varchar('source', { length: 255 }), // e.g., 'Hacker News', 'Blog', 'Internal Memo'
url: text('url'),
publishedAt: timestamp('publishedAt', { mode: 'date' }),
sentiment: varchar('sentiment', { length: 50 }), // e.g., 'Positive', 'Negative', 'Neutral', 'Conflict'
tags: jsonb('tags'), // Array of strings for categorization
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// Conflict/Issue Tracking Table
export const issues = pgTable('issues', {
id: serial('id').primaryKey(),
projectId: integer('project_id').notNull().references(() => projects.id, { onDelete: 'cascade' }),
entityId: integer('entity_id').references(() => analysisEntities.id, { onDelete: 'set null' }), // Link to the source entity if applicable
issueType: varchar('issue_type', { length: 100 }).notNull(), // e.g., 'Corporate Conflict', 'Management Dispute', 'Community Uprising', 'Licensing Issue'
description: text('description'),
severity: varchar('severity', { length: 50 }), // e.g., 'Low', 'Medium', 'High', 'Critical'
status: varchar('status', { length: 50 }).default('Open'), // 'Open', 'Investigating', 'Resolved', 'Closed'
assignedToUserId: integer('assigned_to_user_id').references(() => users.id, { onDelete: 'set null' }),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// Relationships (can be inferred or explicitly defined in Drizzle)
// One Project has many AnalysisEntities
// One Project has many Issues
// One AnalysisEntity can be linked to an Issue
// Users can be assigned to Issues
// Example for defining relations (in a separate relations.ts or alongside)
// import { relations } from 'drizzle-orm';
// export const projectRelations = relations(projects, {
// analysisEntities: oneToMany(analysisEntities, analysisEntities.projectId),
// issues: oneToMany(issues, issues.projectId)
// });
```
# CORE FEATURES & USER FLOW
1. **User Authentication:**
* **Flow:** User lands on the homepage -> Clicks 'Sign Up' or 'Login' -> Redirected to authentication provider (e.g., Google, GitHub) or enters email/password -> Upon successful authentication, redirected to the dashboard.
* **Features:** Secure login/signup, session management, password reset (if using email/password).
* **Edge Cases:** Invalid credentials, existing email, social login errors, session expiry.
2. **Project Dashboard:**
* **Flow:** Authenticated user logs in -> Sees a dashboard listing projects they are tracking or have analyzed -> Option to 'Add New Project' or click on an existing project to view details.
* **Features:** Project list view, quick stats (e.g., number of issues, recent activity), search/filter projects, button to add new project.
* **Edge Cases:** Empty dashboard state (no projects added).
3. **Add New Project:**
* **Flow:** User clicks 'Add New Project' -> Enters Project Name, Source URL (e.g., GitHub), and a brief Description -> Clicks 'Save'. System attempts to fetch basic repo info. -> Project is added to the user's dashboard.
* **Features:** Project creation form, basic validation (URL format).
* **Edge Cases:** Invalid URL, duplicate project name, network errors during fetch.
4. **Project Analysis View:**
* **Flow:** User clicks on a project from the dashboard -> Navigates to the project's dedicated analysis page. This page displays:
* **Overview Tab:** Project name, description, source URL, key stats (activity, contributors, recent issues).
* **Analysis Feed Tab:** A chronological list of analyzed entities (posts, articles, comments) related to this project. Each entry shows title, source, author, date, detected sentiment/issue type, and a snippet of content.
* **Issues Tab:** A list of identified conflicts or significant issues within the project, with details on type, severity, status, and potentially assigned personnel.
* **Entity Detail View:** Clicking an item in the Analysis Feed or Issues list opens a modal or dedicated page showing the full content, detailed analysis (sentiment, key entities, relationships), and associated issues.
* **Features:** Tabbed interface, data visualization (charts for sentiment trends, issue frequency), filtering/sorting for entities and issues, detailed entity/issue views.
* **Edge Cases:** Project with no analysis data, project with no identified issues, large datasets requiring pagination/virtual scrolling.
5. **Manual Entity Analysis/Submission:**
* **Flow:** Within a project view, user can manually add an analysis entity -> Clicks 'Add Analysis Item' -> Fills a form with Title, Content, Source, Author, URL, Published Date -> Clicks 'Analyze & Save'. The system processes the content (simulated or via future AI integration) to detect sentiment and potential issues.
* **Features:** Form for manual data entry, basic content validation.
* **Edge Cases:** Large content input, invalid date formats.
6. **AI-Powered Analysis (Future MVP/V2):**
* **Flow:** When an entity is added (manually or via scraper), the backend triggers an AI analysis function.
* **Features:** Sentiment analysis, conflict detection, key entity extraction, relationship mapping (corporate vs. community).
* **Backend Task:** This would involve calling external LLM APIs or using local models.
# API & DATA FETCHING
* **API Routes (Next.js App Router - Server Actions & API Routes):**
* `POST /api/auth/*`: Handled by NextAuth.js.
* `POST /api/projects`: Server Action to create a new project.
* `GET /api/projects`: Server Action/RSC to fetch list of projects for the dashboard.
* `GET /api/projects/[projectId]`: RSC to fetch project details, analysis entities, and issues for the project page.
* `POST /api/projects/[projectId]/entities`: Server Action to add a new analysis entity manually.
* `GET /api/entities/[entityId]`: RSC/API Route to fetch details for a single analysis entity.
* `POST /api/projects/[projectId]/issues`: Server Action to manually add an issue.
* **(Internal/Background):** API endpoints or functions for AI analysis processing.
* **Data Fetching Strategy:**
* **Server Components (RSC):** Use directly in page components (`app/dashboard/[projectId]/page.tsx`) to fetch data needed for the initial render. This leverages Drizzle ORM directly within the component or via utility functions.
* **Server Actions:** Use for data mutations (POST, PUT, DELETE requests) triggered by form submissions or button clicks.
* **Client Components:** Use SWR or React Query for client-side fetching, revalidation, or features requiring real-time updates after initial load (e.g., polling for status updates, though not strictly MVP).
* **Caching:** Leverage Next.js caching mechanisms for RSCs and consider client-side caching for performance.
* **Request/Response Examples:**
* `POST /api/projects` (Server Action):
* Request Body: `{ name: string, sourceUrl: string, description: string }`
* Response: `{ success: boolean, project?: Project, error?: string }`
* `GET /api/projects/[projectId]` (RSC):
* Response (within component props): `{ project: Project, analysisEntities: AnalysisEntity[], issues: Issue[] }`
# COMPONENT BREAKDOWN (Next.js App Router)
* **`app/layout.tsx`**: Root layout (HTML, head, body, global providers, Tailwind CSS setup).
* **`app/page.tsx`**: Landing Page (Marketing, features overview, call to action for sign up).
* **`app/auth/signin/page.tsx`**: Sign-in page (using NextAuth.js components or custom form).
* **`app/dashboard/page.tsx`**: Dashboard (Lists projects, 'Add Project' button). Requires authentication.
* `components/ProjectList.tsx`: Displays the list of projects.
* `components/ProjectListItem.tsx`: Individual project row/card.
* `components/AddProjectForm.tsx`: Modal or dedicated form to add a new project.
* **`app/dashboard/[projectId]/page.tsx`**: Project Detail Page (Displays overview, analysis feed, issues).
* `components/ProjectOverview.tsx`: Displays project metadata.
* `components/AnalysisFeed.tsx`: List of `AnalysisEntity` items.
* `components/AnalysisFeedItem.tsx`: Individual analysis item card.
* `components/IssueList.tsx`: List of `Issue` items.
* `components/IssueListItem.tsx`: Individual issue row/card.
* `components/EntityDetailModal.tsx`: Modal to show full entity details.
* `components/AddAnalysisForm.tsx`: Modal/form for manual entity submission.
* `components/AddIssueForm.tsx`: Modal/form for manual issue submission.
* **`components/ui/`**: Re-usable UI components from shadcn/ui (Button, Input, Card, Table, Tabs, Dialog, etc.).
* **`components/layout/`**: Common layout components (Navbar, Sidebar, Footer).
* **`lib/`**: Utility functions, database connection, Drizzle schema definitions, API client helpers.
* **`hooks/`**: Custom React hooks (e.g., `useAuth`, `useFetchData`).
* **`styles/`**: Global CSS or Tailwind configurations.
**State Management:**
* Global auth state managed by NextAuth.js context.
* Local component state for forms, modals, UI toggles.
* Server-side data fetching via RSCs handles most data needs. Zustand or Context API for shared state across client components if necessary (e.g., complex filters).
# UI/UX DESIGN & VISUAL IDENTITY
* **Design Style:**