PROJECT OVERVIEW:
Build a Next.js MVP SaaS application called 'KeyFix' (formerly FixMyKeys) designed to solve the problem of expensive and difficult MacBook keyboard repairs. The core value proposition is to empower users to overcome keyboard malfunctions (like stuck or non-responsive keys) through software-based key remapping and a supportive community, thereby avoiding costly hardware replacements. The application will provide an intuitive interface for remapping keys, offer guidance on workarounds, and foster a community for sharing solutions and experiences.
This is not a landing page or a simple SPA. It's a fully functional multi-page application with user authentication, database persistence, and CRUD operations for user-defined key mappings and community posts.
TECH STACK:
- Frontend Framework: React with Next.js (App Router)
- Styling: Tailwind CSS
- ORM: Drizzle ORM (PostgreSQL compatible - e.g., with Neon, Vercel Postgres, or Supabase)
- Database: PostgreSQL
- Authentication: NextAuth.js (for email/password and potentially Google/Apple OAuth)
- UI Components: shadcn/ui for accessible, reusable components
- State Management: React Context API / Zustand (for global state if needed)
- Form Handling: React Hook Form with Zod for validation
- Other Libraries: React-hot-toast for notifications, uuid for unique IDs, clsx for conditional class names.
DATABASE SCHEMA (PostgreSQL with Drizzle ORM):
1. `users` table:
- `id`: UUID (Primary Key, default: uuid_generate_v4())
- `name`: VARCHAR(255)
- `email`: VARCHAR(255) UNIQUE NOT NULL
- `emailVerified`: TIMESTAMP WITH TIME ZONE
- `image`: TEXT
- `createdAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
- `updatedAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
2. `keyMappings` table:
- `id`: UUID (Primary Key, default: uuid_generate_v4())
- `userId`: UUID (Foreign Key to `users.id` ON DELETE CASCADE)
- `sourceKey`: VARCHAR(50) NOT NULL COMMENT 'The key that is pressed (e.g., "CapsLock", "ArrowRight", "KeyA")'
- `targetKeys`: JSONB NOT NULL COMMENT 'Array of target keys or key combinations (e.g., [{"key": "j", "modifiers": ["alt"]}, {"key": "Home"}])'
- `description`: TEXT COMMENT 'User-defined description for this mapping (e.g., "Remap CapsLock to Ctrl")'
- `isEnabled`: BOOLEAN DEFAULT TRUE
- `createdAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
- `updatedAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
3. `communityPosts` table:
- `id`: UUID (Primary Key, default: uuid_generate_v4())
- `userId`: UUID (Foreign Key to `users.id` ON DELETE CASCADE)
- `title`: VARCHAR(255) NOT NULL
- `content`: TEXT NOT NULL
- `tags`: TEXT[] COMMENT 'Array of tags (e.g., {"troubleshooting", "workaround", "repair")'
- `createdAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
- `updatedAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
4. `postComments` table:
- `id`: UUID (Primary Key, default: uuid_generate_v4())
- `postId`: UUID (Foreign Key to `communityPosts.id` ON DELETE CASCADE)
- `userId`: UUID (Foreign Key to `users.id` ON DELETE CASCADE)
- `content`: TEXT NOT NULL
- `createdAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
- `updatedAt`: TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
(Optional: `userSettings` table for app-specific preferences)
CORE FEATURES & USER FLOW:
1. User Authentication:
- Flow: User visits the site -> Clicks 'Sign In'/'Sign Up' -> Enters email/password or uses OAuth (Google/Apple) -> Receives verification email (if email/password) -> Logs in -> Is redirected to Dashboard.
- Protected Routes: All routes except auth pages require authentication.
- Session Management: Use NextAuth.js callbacks to manage user sessions and extend them.
2. Key Mapping Management:
- User Flow:
1. User navigates to 'Key Mappings' page.
2. Sees a list of their existing mappings (if any).
3. Clicks 'Add New Mapping'.
4. A modal or dedicated form appears.
5. User selects the 'Source Key' (e.g., from a visual keyboard representation or dropdown).
6. User defines 'Target Keys/Combination' (e.g., clicks on target keys, selects modifiers like Shift, Ctrl, Alt, Cmd).
7. User adds an optional 'Description' (e.g., 'Remap Right Arrow to CapsLock+RightArrow').
8. User clicks 'Save'.
9. The new mapping is added to their list and becomes active (Note: Actual OS-level remapping might require a companion background app/script the user installs and runs, or deep OS integration if possible via specific APIs - the MVP will focus on defining the mappings within the app, with clear instructions on how users can implement them using tools like Karabiner-Elements).
10. User can toggle mappings ON/OFF, Edit, or Delete existing mappings.
- Data Persistence: Mappings are saved to the `keyMappings` table associated with the logged-in user.
3. Community Forum:
- User Flow:
1. User navigates to the 'Community' page.
2. Sees a list of recent posts, sortable by date, tags, or popularity.
3. Clicks 'Create New Post'.
4. A form appears to enter Title, Content, and select Tags.
5. User submits the post. Saved to `communityPosts` table.
6. User can click on a post to view its details and comments.
7. On the post detail page, the user can see comments and add their own comment (Saved to `postComments` table).
8. Users can reply to comments.
- Moderation: Basic moderation features (reporting posts/comments) can be considered for future iterations.
4. Guidance & Resources:
- Dedicated pages/sections for:
- Explaining the technical challenge of MacBook keyboard repairs.
- Comparing repair costs (Apple vs. third-party).
- Providing step-by-step guides on how to use tools like Karabiner-Elements to implement the defined mappings.
- Troubleshooting common keyboard issues.
API & DATA FETCHING:
- API Routes: Use Next.js API Routes (App Router handlers in `app/api/...`) for backend logic.
- Authentication: NextAuth.js handles auth routes (`/api/auth/...`).
- Key Mappings API:
- `POST /api/mappings`: Create a new key mapping.
- `GET /api/mappings`: Get all mappings for the current user.
- `PUT /api/mappings/[id]`: Update an existing mapping.
- `DELETE /api/mappings/[id]`: Delete a mapping.
- `PATCH /api/mappings/[id]/toggle`: Enable/disable a mapping.
- Community API:
- `POST /api/community`: Create a new post.
- `GET /api/community`: Get list of posts (with pagination).
- `GET /api/community/[id]`: Get single post details.
- `POST /api/community/[id]/comments`: Add a comment to a post.
- `GET /api/community/[id]/comments`: Get comments for a post.
- Data Fetching: Use Server Components for initial data loading where possible. Use Client Components with `fetch` or libraries like SWR/React Query for dynamic updates and mutations. Pass necessary data via props to components.
- Request/Response: JSON format. Use Zod for request validation on API routes.
UI/UX DESIGN & VISUAL IDENTITY:
- Design Style: Minimalist Clean with subtle tech-inspired elements.
- Color Palette:
- Primary: `#0A0A0A` (Dark background)
- Secondary: `#1E1E1E` (Slightly lighter dark for cards/sections)
- Accent: `#007AFF` (Apple-like blue for interactive elements, links, buttons)
- Subtle Accent: `#5E5E5E` (For secondary text, borders)
- Text: `#F5F5F7` (Light grey for primary text)
- Success: `#34C759`
- Warning: `#FF9500`
- Error: `#FF3B30`
- Typography:
- Headings: Inter (Bold, SemiBold)
- Body Text: Inter (Regular)
- Layout: Clean, spacious layout using Tailwind CSS utility classes. Focus on clarity and ease of navigation. Use card-based UI for mappings and forum posts.
- Responsiveness: Mobile-first approach. Ensure usability on various screen sizes (smartphones, tablets, desktops).
- Key Visuals: Abstract keyboard key graphics, subtle line animations.
COMPONENT BREAKDOWN (Next.js App Router Structure):
- `app/`
- `(auth)/` (Auth Layout)
- `login/page.tsx`: Login form page.
- `signup/page.tsx`: Signup form page.
- `reset-password/page.tsx`: Password reset page.
- `(app)/` (Authenticated App Layout)
- `layout.tsx`: Main app layout with sidebar/header.
- `dashboard/page.tsx`: Overview, quick actions, recent activity.
- `mappings/page.tsx`: List of user's key mappings.
- `mappings/[id]/edit/page.tsx`: Form to edit a specific mapping.
- `mappings/new/page.tsx`: Form to create a new mapping.
- `community/page.tsx`: Community forum - list of posts.
- `community/[postId]/page.tsx`: Single community post view with comments.
- `community/new/page.tsx`: Form to create a new community post.
- `resources/page.tsx`: Guidance and resource articles.
- `settings/page.tsx`: User profile and application settings.
- `api/`
- `auth/[...nextauth]/route.ts`: NextAuth.js handler.
- `mappings/route.ts`: API routes for mappings CRUD.
- `mappings/[id]/route.ts`: API routes for single mapping operations.
- `community/route.ts`: API routes for community posts.
- `community/[postId]/route.ts`: API routes for single post/comments.
- `layout.tsx`: Root layout (html, body, providers).
- `page.tsx`: Landing page (for unauthenticated users).
- `components/`
- `ui/`: Re-usable shadcn/ui components (Button, Input, Card, Dialog, etc.).
- `auth/`: Auth related components (LoginForm, SignupForm).
- `mappings/`: Components specific to key mappings (MappingList, MappingForm, KeySelector).
- `community/`: Components for the forum (PostCard, PostList, CommentSection, CommentForm).
- `layout/`: Header, Sidebar, Footer components.
- `common/`: General purpose components (Toast, LoadingSpinner, ErrorMessage).
- `lib/`:
- `db.ts`: Drizzle ORM connection and schema definition.
- `auth.ts`: NextAuth.js configuration.
- `utils.ts`: Utility functions.
- `validation.ts`: Zod schemas for validation.
- `styles/`:
- `globals.css`: Tailwind CSS setup and global styles.
State Management:
- Local component state for UI interactions.
- React Context or Zustand for global state like user authentication status, theme settings.
- Server Component props for data fetching.
ANIMATIONS:
- Subtle page transitions using Next.js's built-in features or libraries like Framer Motion (if needed, keep it light).
- Hover effects on buttons and interactive elements using Tailwind CSS (`hover:` variants).
- Smooth transitions for modals and dropdowns.
- Loading states indicated by spinners or skeleton loaders within components.
- Fade-in animations for dynamically loaded content.
EDGE CASES:
- Authentication:
- Unauthenticated users blocked from accessing protected routes.
- Email verification flow.
- Password reset functionality.
- Handling OAuth callback errors.
- Validation:
- Client-side and server-side validation for all forms (mappings, posts, comments, auth).
- Clear error messages displayed to the user.
- Empty States:
- Display user-friendly messages and CTAs when `keyMappings` or `communityPosts` are empty (e.g., 'You haven't created any mappings yet. Click here to add one!').
- Placeholder content for loading states.
- API Errors:
- Graceful error handling for API requests (e.g., network errors, server errors).
- Display informative error messages using toast notifications.
- Data Integrity:
- Ensure foreign key constraints are maintained.
- Handle potential race conditions if necessary.
- Key Input Handling:
- Robust handling of various key inputs, including special characters and modifier keys.
- Clear UI feedback during key selection.
SAMPLE DATA (for `keyMappings`):
1. {
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"userId": "user-uuid-123",
"sourceKey": "ArrowRight",
"targetKeys": [
{"key": "j", "modifiers": ["alt"]}
],
"description": "Remap Right Arrow to Alt+J",
"isEnabled": true
},
2. {
"id": "f0e9d8c7-b6a5-4321-fedc-ba0987654321",
"userId": "user-uuid-123",
"sourceKey": "CapsLock",
"targetKeys": [
{"key": "Control", "modifiers": []}
],
"description": "CapsLock as Control key",
"isEnabled": true
},
3. {
"id": "11223344-5566-7788-99aa-bbccddeeff00",
"userId": "user-uuid-456",
"sourceKey": "Space",
"targetKeys": [
{"key": " ", "modifiers": ["shift"]}
],
"description": "Space bar stuck, using Shift+Space as fallback",
"isEnabled": false
},
4. {
"id": "abcdef12-3456-7890-abcd-ef1234567890",
"userId": "user-uuid-123",
"sourceKey": "KeyA",
"targetKeys": [
{"key": "a", "modifiers": ["cmd"]}
],
"description": "Quickly trigger Cmd+A",
"isEnabled": true
},
5. {
"id": "98765432-fedc-ba09-8765-4321fedcba09",
"userId": "user-uuid-789",
"sourceKey": "ArrowUp",
"targetKeys": [
{"key": "k", "modifiers": ["alt"]},
{"key": "ArrowUp", "modifiers": []}
],
"description": "Alt+K as primary Up Arrow, original ArrowUp as backup",
"isEnabled": true
}
SAMPLE DATA (for `communityPosts`):
1. {
"id": "post-uuid-001",
"userId": "user-uuid-456",
"title": "My right arrow key is constantly pressing itself! Help!",
"content": "It started yesterday, now my MacBook Pro is almost unusable. I've tried cleaning it but nothing works. Does anyone know a cheap fix or a good software workaround? Repair quotes are insane.",
"tags": ["troubleshooting", "hardware issue", "macbook pro"],
"createdAt": "2023-10-26T10:00:00Z"
},
2. {
"id": "post-uuid-002",
"userId": "user-uuid-789",
"title": "Karabiner-Elements Setup for Stuck Keys",
"content": "Found a great guide on setting up Karabiner-Elements to disable stuck keys and remap them. Sharing the link here for anyone facing similar issues. It saved me hundreds of dollars!",
"tags": ["software", "karabiner elements", "workaround", "guide"],
"createdAt": "2023-10-25T14:30:00Z"
},
3. {
"id": "post-uuid-003",
"userId": "user-uuid-123",
"title": "Thinking of replacing the whole top case myself - any tips?",
"content": "The official repair cost is through the roof. I'm considering buying the part and doing it myself, but I'm a bit nervous. Has anyone done this? How hard is it really?",
"tags": ["repair", "diy", "hardware"],
"createdAt": "2023-10-24T09:15:00Z"
}
(Include sample comments for posts as well for `postComments` table examples.)
TURKISH TRANSLATIONS (Key elements):
- App Title: KeyFix (AnahtarDüzelt)
- Sign In: Giriş Yap
- Sign Up: Kayıt Ol
- Dashboard: Kontrol Paneli
- Key Mappings: Tuş Eşlemeleri
- Add New Mapping: Yeni Eşleme Ekle
- Source Key: Kaynak Tuş
- Target Keys: Hedef Tuşlar
- Save: Kaydet
- Edit: Düzenle
- Delete: Sil
- Enable: Etkinleştir
- Disable: Devre Dışı Bırak
- Community: Topluluk
- Create New Post: Yeni Gönderi Oluştur
- Title: Başlık
- Content: İçerik
- Tags: Etiketler
- Post: Gönderi
- Comments: Yorumlar
- Add Comment: Yorum Ekle
- Resources: Kaynaklar
- Settings: Ayarlar
- Profile: Profil
- Sign Out: Çıkış Yap
- Error: Hata
- Success: Başarılı
- Warning: Uyarı
- No mappings found: Eşleme bulunamadı.
- Add your first mapping: İlk eşlemenizi ekleyin.
- What's on your mind?: Aklınızdakiler neler?
- Post details: Gönderi detayları.
- You are viewing post by: Gönderi sahibi:
- No comments yet: Henüz yorum yok.
- Be the first to comment!: Yorum yapan ilk siz olun!
- High repair costs: Yüksek tamir masrafları.
- Software Workaround: Yazılımsal Çözüm.
- Community Forum: Topluluk Forumu.
- Keyboard Repair Guide: Klavye Tamir Rehberi.