## AI Master Prompt for FOSS Laptop Guide MVP (Next.js)
### 1. PROJECT OVERVIEW:
**Project Title:** FOSS Laptop Guide
**Problem:** Users interested in using alternative operating systems (like FreeBSD, Linux distributions) on laptops often face challenges determining hardware compatibility and functionality *before* purchasing or installing. Information is fragmented across forums, blogs, and wikis, making it difficult to get a clear, aggregated view of which laptop models work well and with what specific component support.
**Solution:** FOSS Laptop Guide is a SaaS platform (web application) that aggregates, scores, and displays user-reported compatibility data for laptops with various Operating Systems. It allows users to contribute their findings, rate specific hardware components (Wi-Fi, Graphics, Audio, USB, etc.), and share detailed reviews. The core value proposition is to provide a centralized, community-driven, and easily searchable database for making informed decisions about laptop hardware for non-mainstream OS.
**Core Value Proposition:** Empower users to find, share, and contribute accurate hardware compatibility information for laptops running Free and Open Source Software (FOSS), saving them time, frustration, and potentially costly hardware mistakes.
**Target Audience:** Tech enthusiasts, developers, system administrators, students, and anyone looking to run FOSS on their laptops.
### 2. TECH STACK:
* **Frontend Framework:** React with Next.js (App Router)
* **Styling:** Tailwind CSS
* **UI Component Library:** shadcn/ui (for accessible, reusable components)
* **State Management:** React Context API (for global state) and component-local state (useState, useReducer)
* **Form Handling:** React Hook Form with Zod for validation
* **Authentication:** NextAuth.js (or Clerk for a more managed solution)
* **Database:** PostgreSQL (recommended) or SQLite (for simpler MVP setup)
* **ORM:** Drizzle ORM (for type-safe database interactions with PostgreSQL/SQLite)
* **Data Fetching:** Server Components, Route Handlers (API Routes), and client-side fetching using libraries like SWR or TanStack Query if needed for complex client-side updates.
* **Deployment:** Vercel (recommended for Next.js)
**Required Packages:** `react`, `react-dom`, `next`, `tailwindcss`, `postcss`, `autoprefixer`, `@radix-ui/react-dialog`, `@radix-ui/react-dropdown-menu`, `@radix-ui/react-icons`, `@radix-ui/react-slot`, `class-variance-authority`, `clsx`, `lucide-react`, `next-auth` (or `@clerk/nextjs`), `drizzle-orm`, `pg` (or `better-sqlite3`), `zod`, `react-hook-form`, `swr` (optional)
### 3. DATABASE SCHEMA (Drizzle ORM - PostgreSQL syntax):
```typescript
import { pgTable, serial, varchar, text, integer, numeric, timestamp, boolean, uuid, index, pgEnum } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// User Authentication Table
export const users = pgTable('users', {
id: uuid('id').primaryKey(), // Using UUID for primary key
name: varchar('name'),
email: varchar('email', { length: 255 }).notNull().unique(),
emailVerified: timestamp('emailVerified', { mode: 'date' }),
image: varchar('image', { length: 255 }),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
export const accounts = pgTable('accounts', {
id: uuid('id').primaryKey(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
type: varchar('type', { length: 255 }).$type<string>().notNull(),
provider: varchar('provider', { length: 255 }).notNull(),
providerAccountId: varchar('providerAccountId', { length: 255 }).notNull(),
refresh_token: text('refresh_token'),
access_token: text('access_token'),
expires_at: numeric('expires_at'),
token_type: varchar('token_type'),
scope: varchar('scope'),
id_token: text('id_token'),
session_state: varchar('session_state'),
}, (t) => ({
compoundKey: index('accounts_provider_providerAccountId_idx').on(t.provider, t.providerAccountId),
}));
export const sessions = pgTable('sessions', {
id: uuid('id').primaryKey(),
sessionToken: varchar('sessionToken', { length: 255 }).notNull().unique(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
expires: timestamp('expires', { mode: 'date' }).notNull(),
});
export const verificationTokens = pgTable('verificationTokens', {
identifier: varchar('identifier', { length: 255 }).notNull(),
token: varchar('token', { length: 255 }).notNull(),
expires: timestamp('expires', { mode: 'date' }).notNull(),
}, (t) => ({
compoundKey: index('verificationTokens_identifier_token_idx').on(t.identifier, t.token)
}));
// Operating System Enum
export const osEnum = pgEnum('os', ['FreeBSD', 'Linux', 'Windows', 'macOS']);
// Laptop Model Table
export const laptopModels = pgTable('laptop_models', {
id: serial('id').primaryKey(),
brand: varchar('brand', { length: 100 }).notNull(),
modelName: varchar('model_name', { length: 150 }).notNull(),
cpu: varchar('cpu', { length: 150 }),
ramGB: integer('ram_gb'),
storage: varchar('storage', { length: 100 }),
releaseYear: integer('release_year'),
gpu: varchar('gpu', { length: 150 }),
notes: text('notes'), // General notes about the model
averageScore: numeric('average_score', { precision: 2, scale: 1 }).default(0.0),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
}, (t) => ({
modelNameIndex: index('laptop_models_model_name_idx').on(t.modelName),
}));
// Component Compatibility Score Table
export const componentScores = pgTable('component_scores', {
id: serial('id').primaryKey(),
laptopModelId: integer('laptop_model_id').notNull().references(() => laptopModels.id, { onDelete: 'cascade' }),
operatingSystem: osEnum('operating_system').notNull(),
wifiScore: numeric('wifi_score', { precision: 2, scale: 1 }).default(0.0),
graphicsScore: numeric('graphics_score', { precision: 2, scale: 1 }).default(0.0),
audioScore: numeric('audio_score', { precision: 2, scale: 1 }).default(0.0),
usbScore: numeric('usb_score', { precision: 2, scale: 1 }).default(0.0),
ethernetScore: numeric('ethernet_score', { precision: 2, scale: 1 }).default(0.0),
webcamScore: numeric('webcam_score', { precision: 2, scale: 1 }).default(0.0),
// Add other relevant components as needed (e.g., bluetooth, fingerprint, trackpad)
totalScore: numeric('total_score', { precision: 3, scale: 1 }).default(0.0), // Calculated aggregate
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// User Reviews/Comments Table
export const reviews = pgTable('reviews', {
id: serial('id').primaryKey(),
laptopModelId: integer('laptop_model_id').notNull().references(() => laptopModels.id, { onDelete: 'cascade' }),
userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
operatingSystem: osEnum('operating_system').notNull(),
title: varchar('title', { length: 200 }).notNull(),
comment: text('comment').notNull(),
setupEffort: numeric('setup_effort', { precision: 2, scale: 1 }), // e.g., 1-5 scale
overallExp: numeric('overall_exp', { precision: 2, scale: 1 }), // e.g., 1-5 scale
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// Relations (for Drizzle Kit push and potential ORM queries)
export const usersRelations = relations(users, ({ many }) => ({
reviews: many(reviews)
}));
export const laptopModelsRelations = relations(laptopModels, ({ many }) => ({
componentScores: many(componentScores),
reviews: many(reviews)
}));
export const componentScoresRelations = relations(componentScores, ({ one }) => ({
laptopModel: one(laptopModels, {
fields: [componentScores.laptopModelId],
references: [laptopModels.id]
})
}));
export const reviewsRelations = relations(reviews, ({ one }) => ({
laptopModel: one(laptopModels, {
fields: [reviews.laptopModelId],
references: [laptopModels.id]
}),
user: one(users, {
fields: [reviews.userId],
references: [users.id]
})
}));
```
### 4. CORE FEATURES & USER FLOW:
**Feature 1: Laptop Model Management**
* **User Flow:**
1. User navigates to the 'Add Laptop' page (requires authentication).
2. User fills out a form with Brand, Model Name, CPU, RAM, Storage, Release Year, GPU, and optional general notes.
3. Form uses React Hook Form and Zod for validation (e.g., Model Name is required, Release Year is a number).
4. Upon successful submission, a POST request is sent to `/api/laptops`.
5. Backend creates a new record in the `laptop_models` table.
6. User is redirected to the newly created laptop's detail page or a success message is shown.
* **Admin/Moderator Flow:** (Future enhancement) Ability to edit/delete existing laptop entries.
**Feature 2: Component Compatibility Scoring**
* **User Flow:**
1. On a laptop's detail page, an authenticated user can choose to 'Add Compatibility Score' for a specific OS (e.g., FreeBSD).
2. A modal or dedicated section appears with input fields for each component score (Wi-Fi, Graphics, Audio, USB, Ethernet, Webcam) using a 1-5 scale or predefined options (e.g., 'Fully Functional', 'Degraded', 'Not Working'). Use numeric inputs with step 0.5 for flexibility or select inputs.
3. The system calculates `totalScore` based on predefined weights (e.g., Wi-Fi and Graphics are weighted higher).
4. User submits the score data via a POST request to `/api/laptops/[id]/scores`.
5. Backend saves the `component_scores` record, linking it to the `laptopModelId` and `operatingSystem`.
6. The laptop's `averageScore` in the `laptop_models` table is recalculated (or updated via a trigger/background job).
7. The new scores are displayed on the laptop detail page.
* **Edge Cases:** User submitting a score for an OS/Model combination that already exists (either update existing or prevent duplicate - decision needed. Let's prevent and prompt user to edit existing).
**Feature 3: User Reviews and Comments**
* **User Flow:**
1. On a laptop's detail page, any user (authenticated or not, decision TBD - let's start with authenticated for easier moderation) can add a review.
2. User fills a form: Title, detailed Comment, Setup Effort (1-5), Overall Experience (1-5).
3. Form validation is applied.
4. POST request to `/api/laptops/[id]/reviews`.
5. Backend saves the `reviews` record, linking to `laptopModelId` and `userId`.
6. Reviews are displayed chronologically or by helpfulness (future) on the laptop detail page.
* **Moderation:** Implement flagging for inappropriate content (future).
**Feature 4: Authentication**
* **User Flow (OAuth Example - Google/GitHub):**
1. User clicks 'Sign In' button.
2. User is presented with OAuth provider options (Google, GitHub).
3. User selects a provider.
4. User is redirected to the provider's authentication page.
5. User logs in and authorizes the application.
6. User is redirected back to the FOSS Laptop Guide app.
7. NextAuth.js handles session creation and management. The `users`, `accounts`, `sessions`, `verificationTokens` tables are managed by NextAuth.js.
8. User's profile information (name, email, image) is stored in the `users` table.
* **Edge Cases:** Failed authentication, revoked access, session expiry.
**Feature 5: Search and Filtering**
* **User Flow:**
1. A search bar is present on the homepage and potentially a dedicated search page.
2. Users can type a brand or model name.
3. As the user types (debounced input), an API call is made to `/api/search?q={query}`.
4. Backend queries `laptop_models` table using `LIKE` operator (or full-text search).
5. Search results (list of laptop models) are displayed.
6. A filtering sidebar/dropdown allows users to filter by `operatingSystem` (from `component_scores` table, requires joining) and potentially by `averageScore` range.
7. The URL updates to reflect search/filter parameters (e.g., `/search?os=FreeBSD&minScore=7`).
* **Data Fetching:** Primarily server-side fetching for search results based on URL parameters. Client-side filtering might be added for smaller result sets.
### 5. API & DATA FETCHING:
* **`POST /api/laptops`:** Creates a new laptop model. Requires authentication. Body: `{ brand, modelName, cpu, ramGB, storage, releaseYear, gpu, notes }`. Response: `{ success: true, laptopId: number }` or error.
* **`GET /api/laptops/[id]`:** Fetches details for a specific laptop model, including its associated scores and reviews. Uses Server Components data fetching.
* **`POST /api/laptops/[id]/scores`:** Adds a compatibility score for a laptop and OS. Requires authentication. Body: `{ operatingSystem, wifiScore, graphicsScore, audioScore, usbScore, ethernetScore, webcamScore, setupEffort, overallExp }`. Response: `{ success: true }` or error.
* **`POST /api/laptops/[id]/reviews`:** Adds a review for a laptop. Requires authentication. Body: `{ operatingSystem, title, comment, setupEffort, overallExp }`. Response: `{ success: true }` or error.
* **`GET /api/search?q={query}&os={osFilter}`:** Handles search queries and OS filtering. Returns a list of matching laptop models with their average scores. Can be implemented using Route Handlers.
* **Data Fetching Strategy:**
* Use Next.js Server Components for initial page loads (e.g., `app/page.tsx`, `app/laptops/[id]/page.tsx`) to fetch data directly from the DB based on route parameters.
* Use Route Handlers (`app/api/.../route.ts`) for mutations (POST, PUT, DELETE) and dynamic data fetching (like search).
* Leverage Drizzle ORM for type-safe database queries within Server Components and Route Handlers.
* For real-time updates or complex client-side state, consider SWR or TanStack Query in Client Components.
### 6. COMPONENT BREAKDOWN (Next.js App Router Structure):
* **`app/layout.tsx`:** Root layout (includes `<html>`, `<body>`, global providers, Tailwind CSS setup, shadcn/ui ThemeProvider).
* **`app/page.tsx`:** Homepage.
* **Components:** `HeroSection`, `SearchBar` (debounced input, triggers search API), `FeaturedLaptops` (list of laptops with highest average scores), `CallToAction` (encouraging contributions).
* **State:** Search query state.
* **`app/search/page.tsx`:** Search Results Page.
* **Components:** `SearchBar` (pre-filled with query), `FilterSidebar` (OS, score range checkboxes/sliders), `LaptopList` (displays search results).
* **State:** Search query, filter parameters, list of laptops.
* **`app/laptops/[id]/page.tsx`:** Laptop Detail Page.
* **Components:** `LaptopDetailsCard` (brand, model, specs), `CompatibilityMatrix` (table showing scores per OS), `ScoreFormModal` (modal for adding/editing scores), `ReviewList`, `ReviewForm` (form for adding reviews), `AddReviewButton`.
* **State:** Laptop data, score data, review data, modal open/close state.
* **`app/auth/signin/page.tsx`:** Sign In Page.
* **Components:** `SignInForm` (using NextAuth.js or Clerk components).
* **`app/profile/page.tsx`:** User Profile Page (Future).
* **Components:** Display user info, list of user's reviews/contributions.
* **`app/layout.tsx`:** Root layout.
* **`app/loading.tsx`:** Global loading indicator component.
* **`app/error.tsx`:** Global error boundary component.
* **`components/ui/`:** Directory for all shadcn/ui components and custom wrappers (e.g., `Button`, `Card`, `Input`, `Dialog`, `Table`, `Select`).
* **`components/`:** Shared UI components (e.g., `LaptopListItem`, `ScoreDisplay`, `FilterDropdown`).
* **`lib/`:** Utility functions, database connection setup (`db.ts` using Drizzle), constants, helper functions.
* **`hooks/`:** Custom React hooks (e.g., `useDebounce`).
* **`types/`:** TypeScript interfaces and types (e.g., for API responses, component props).
* **`server/`:** Backend logic, API route handlers (`app/api/.../route.ts`), Zod schemas for validation.
### 7. UI/UX DESIGN & VISUAL IDENTITY:
* **Design Style:** Modern Minimalist Clean with subtle tech-inspired elements.
* **Color Palette:**
* Primary: `#0A7AFF` (Vibrant Blue - for actions, highlights)
* Secondary: `#6C757D` (Muted Gray - for secondary text, borders)
* Background: `#FFFFFF` (White - light mode) / `#121212` (Dark Black - dark mode toggleable)
* Surface: `#F8F9FA` (Light Gray - light mode cards/modals) / `#1E1E1E` (Dark Gray - dark mode cards/modals)
* Text: `#212529` (Dark Gray - light mode) / `#E0E0E0` (Light Gray - dark mode)
* Accent/Success: `#198754` (Green)
* Warning/Error: `#DC3545` (Red)
* **Typography:**:
* Headings: Inter (Bold, Semibold)
* Body Text: Inter (Regular)
* Font Sizes: Scale appropriately (e.g., 16px base, 24px h2, 32px h1).
* **Layout:**:
* Use a responsive grid system (Tailwind CSS default).
* Max-width container for content (e.g., `max-w-7xl mx-auto`).
* Clear visual hierarchy with ample whitespace.
* Sidebar for filters, main content area for lists/details.
* **UI Elements:**:
* Use shadcn/ui components for consistency and accessibility.
* Interactive elements should have clear hover and focus states.
* Use subtle `box-shadow` on cards and interactive elements.
* **Responsive Rules:** Mobile-first approach. Ensure usability on screens from 320px width up to large desktops. Use Tailwind's responsive modifiers ( `sm:`, `md:`, `lg:`).
### 8. SAMPLE/MOCK DATA:
**Laptop Models:**
1. `{ brand: 'Lenovo', modelName: 'ThinkPad X1 Carbon Gen 9', cpu: 'Intel Core i7-1165G7', ramGB: 16, storage: '512GB NVMe SSD', releaseYear: 2021, gpu: 'Intel Iris Xe Graphics' }`
2. `{ brand: 'Framework', modelName: 'Laptop 13 (AMD Ryzen 7040 Series)', cpu: 'AMD Ryzen 7 7840U', ramGB: 32, storage: '1TB NVMe SSD', releaseYear: 2023, gpu: 'AMD Radeon 780M' }`
3. `{ brand: 'ASUS', modelName: 'ROG Zephyrus G14', cpu: 'AMD Ryzen 9 5900HS', ramGB: 16, storage: '1TB NVMe SSD', releaseYear: 2021, gpu: 'NVIDIA GeForce RTX 3060 Mobile' }`
4. `{ brand: 'Apple', modelName: 'MacBook Pro 14" (M1 Pro)', cpu: 'Apple M1 Pro', ramGB: 16, storage: '512GB SSD', releaseYear: 2021, gpu: 'Integrated Apple GPU' }`
5. `{ brand: 'Dell', modelName: 'XPS 13 9310', cpu: 'Intel Core i5-1135G7', ramGB: 8, storage: '256GB SSD', releaseYear: 2021, gpu: 'Intel Iris Xe Graphics' }`
**Component Scores (for FreeBSD on ThinkPad X1 Carbon Gen 9):
**
* `{ laptopModelId: 1, operatingSystem: 'FreeBSD', wifiScore: 4.5, graphicsScore: 3.0, audioScore: 4.0, usbScore: 5.0, ethernetScore: 0.0, webcamScore: 4.0, setupEffort: 3, overallExp: 4.0 }` (Ethernet via dongle, thus 0 for onboard)
**Component Scores (for Linux on Framework Laptop 13 AMD):
**
* `{ laptopModelId: 2, operatingSystem: 'Linux', wifiScore: 5.0, graphicsScore: 5.0, audioScore: 5.0, usbScore: 5.0, ethernetScore: 4.5, webcamScore: 4.5, setupEffort: 1, overallExp: 5.0 }`
**Reviews:**
1. `{ laptopModelId: 1, userId: 'some-user-uuid', operatingSystem: 'FreeBSD', title: 'Mostly works, Wi-Fi can be tricky', comment: 'Great laptop, very light. FreeBSD installed smoothly. Wi-Fi needed some configuration and occasionally drops, but graphics and USB ports work perfectly. Setup was moderate.', setupEffort: 3, overallExp: 4.0 }`
2. `{ laptopModelId: 2, userId: 'another-user-uuid', operatingSystem: 'Linux', title: 'Excellent Linux compatibility', comment: 'The Framework Laptop is a dream for Linux users. Everything worked out of the box with Ubuntu 22.04. Stellar performance and build quality.', setupEffort: 1, overallExp: 5.0 }`
3. `{ laptopModelId: 3, userId: 'dev-user-uuid', operatingSystem: 'Linux', title: 'Gaming Beast on Linux', comment: 'Handles gaming and development tasks on Manjaro Linux with ease. Dedicated GPU requires proprietary drivers but performs well after setup. Sound and Wi-Fi are solid.', setupEffort: 2, overallExp: 4.5 }`
### 9. TURKISH TRANSLATIONS:
* **App Title:** FOSS Dizüstü Bilgisayar Rehberi
* **Hero Section:**
* Heading: Dizüstü Bilgisayarınız İçin En Uygun İşletim Sistemini Bulun
* Subheading: Topluluk tarafından oluşturulan uyumluluk verileriyle donanım kararlarınızı bilinçli verin.
* **Buttons:**
* Sign In: Giriş Yap
* Sign Up: Kayıt Ol
* Add Laptop: Dizüstü Bilgisayar Ekle
* Add Score: Puan Ekle
* Submit Review: Yorum Gönder
* Search: Ara
* Filter: Filtrele
* **Labels/Placeholders:**
* Brand: Marka
* Model Name: Model Adı
* CPU: İşlemci
* RAM (GB): RAM (GB)
* Storage: Depolama
* Release Year: Çıkış Yılı
* Graphics Card: Ekran Kartı
* Operating System: İşletim Sistemi
* Wi-Fi Score: Wi-Fi Puanı
* Graphics Score: Grafik Puanı
* Audio Score: Ses Puanı
* USB Score: USB Puanı
* Ethernet Score: Ethernet Puanı
* Webcam Score: Webcam Puanı
* Setup Effort: Kurulum Kolaylığı (1-5)
* Overall Experience: Genel Deneyim (1-5)
* Title: Başlık
* Comment: Yorum
* Search Laptops: Dizüstü Bilgisayar Ara...
* **Page Titles:**
* Homepage: Ana Sayfa
* Search Results: Arama Sonuçları
* Laptop Details: Dizüstü Bilgisayar Detayları
* **Status Messages:**
* Saving...
: Kaydediliyor...
* Laptop Added Successfully: Dizüstü Bilgisayar Başarıyla Eklendi.
* Score Submitted: Puan Gönderildi.
* Review Posted: Yorum Yayınlandı.
* **Filter Options:**
* All Operating Systems: Tüm İşletim Sistemleri
* Minimum Score: Minimum Puan