You are an expert full-stack developer and AI product consultant. Your task is to generate a complete, functional MVP of a SaaS application using Next.js (App Router), Tailwind CSS, and Drizzle ORM. The application, named 'RoboFill', aims to manage and optimize the deployment of physical AI robots in Japan, primarily to fill labor shortage gaps in undesirable or dangerous jobs.
**1. PROJECT OVERVIEW:**
RoboFill is a SaaS platform designed to address the critical labor shortages in Japan's industrial sectors (manufacturing, logistics, infrastructure maintenance, etc.). It enables companies to efficiently deploy, manage, monitor, and optimize fleets of physical AI robots. The core value proposition is to provide businesses with a seamless solution to maintain productivity, ensure operational continuity, and gain insights into robot performance, thereby overcoming the challenges posed by an aging and shrinking workforce. The application will focus on intuitive fleet management, intelligent task assignment, real-time monitoring, performance analytics, and proactive maintenance scheduling.
**2. TECH STACK:**
- **Framework:** Next.js (App Router for server components, routing, and API routes)
- **Styling:** Tailwind CSS (with shadcn/ui for pre-built, accessible components)
- **Database ORM:** Drizzle ORM (PostgreSQL compatibility assumed for this prompt)
- **Database:** PostgreSQL (can be swapped with other supported Drizzle adapters like SQLite for local dev)
- **Authentication:** NextAuth.js (integrating with Google Provider and email/password for MVP)
- **State Management:** React Context API for global state, local component state where appropriate.
- **UI Libraries:** shadcn/ui (for Buttons, Dialogs, Forms, Tables, Input, Select, DatePicker, Toaster, etc.)
- **Charting:** Recharts or similar for displaying performance metrics.
- **Form Handling:** React Hook Form (integrated with Zod for validation)
- **Deployment:** Vercel (or any standard Next.js compatible platform)
- **Language:** TypeScript
**3. DATABASE SCHEMA (Drizzle ORM - PostgreSQL):**
```typescript
// schema.ts
import { pgTable, serial, text, timestamp, integer, boolean, varchar, pgEnum } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// User Roles Enum
export const userRoleEnum = pgEnum('user_role', ['admin', 'manager', 'technician', 'viewer']);
// Users Table
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name'),
email: text('email').unique().notNull(),
emailVerified: timestamp('emailVerified', { mode: 'date' }),
image: text('image'),
role: userRoleEnum('role').notNull().default('viewer'),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Robots Table
export const robots = pgTable('robots', {
id: serial('id').primaryKey(),
serialNumber: varchar('serialNumber', { length: 255 }).unique().notNull(),
model: varchar('model', { length: 255 }).notNull(),
type: varchar('type', { length: 255 }), // e.g., 'warehouse', 'inspection', 'transport'
location: text('location'), // Current or assigned location
status: pgEnum('robot_status', ['online', 'offline', 'maintenance', 'in_use', 'error'])
.notNull()
.default('offline'),
lastMaintenance: timestamp('lastMaintenance', { mode: 'date' }),
assignedTaskId: integer('assignedTaskId').references(() => tasks.id),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Tasks Enum
export const taskPriorityEnum = pgEnum('task_priority', ['low', 'medium', 'high', 'critical']);
export const taskStatusEnum = pgEnum('task_status', ['pending', 'assigned', 'in_progress', 'completed', 'failed', 'cancelled']);
// Tasks Table
export const tasks = pgTable('tasks', {
id: serial('id').primaryKey(),
title: varchar('title', { length: 255 }).notNull(),
description: text('description'),
priority: taskPriorityEnum('priority').notNull().default('medium'),
status: taskStatusEnum('status').notNull().default('pending'),
assignedRobotId: integer('assignedRobotId').references(() => robots.id),
scheduledAt: timestamp('scheduledAt', { mode: 'date' }),
completedAt: timestamp('completedAt', { mode: 'date' }),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Maintenance Records Table
export const maintenanceRecords = pgTable('maintenanceRecords', {
id: serial('id').primaryKey(),
robotId: integer('robotId').notNull().references(() => robots.id),
technicianId: integer('technicianId').references(() => users.id), // Optional: link to user who performed maintenance
scheduledDate: timestamp('scheduledDate', { mode: 'date' }).notNull(),
completionDate: timestamp('completionDate', { mode: 'date' }),
notes: text('notes'),
isCompleted: boolean('isCompleted').default(false),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
});
// Performance Metrics Table (Simplified for MVP - could be expanded significantly)
export const performanceMetrics = pgTable('performanceMetrics', {
id: serial('id').primaryKey(),
robotId: integer('robotId').notNull().references(() => robots.id),
taskId: integer('taskId').references(() => tasks.id), // Link to specific task if applicable
timestamp: timestamp('timestamp', { mode: 'date' }).defaultNow(),
metricName: varchar('metricName', { length: 255 }).notNull(), // e.g., 'battery_level', 'operational_time', 'error_count', 'task_duration'
metricValue: varchar('metricValue', { length: 255 }).notNull(), // Store as text for flexibility, parse as needed
});
// Relations (for easier data fetching)
export const usersRelations = relations(users, ({ many }) => ({
maintenanceRecords: many(maintenanceRecords),
}));
export const robotsRelations = relations(robots, ({ one, many }) => ({
assignedTask: one(tasks, {
fields: [robots.assignedTaskId],
references: [tasks.id],
}),
maintenanceRecords: many(maintenanceRecords),
performanceMetrics: many(performanceMetrics),
}));
export const tasksRelations = relations(tasks, ({ one }) => ({
assignedRobot: one(robots, {
fields: [tasks.assignedRobotId],
references: [robots.id],
}),
}));
export const maintenanceRecordsRelations = relations(maintenanceRecords, ({ one }) => ({
robot: one(robots, {
fields: [maintenanceRecords.robotId],
references: [robots.id],
}),
technician: one(users, {
fields: [maintenanceRecords.technicianId],
references: [users.id],
}),
}));
export const performanceMetricsRelations = relations(performanceMetrics, ({ one }) => ({
robot: one(robots, {
fields: [performanceMetrics.robotId],
references: [robots.id],
}),
task: one(tasks, {
fields: [performanceMetrics.taskId],
references: [tasks.id],
}),
}));
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
export type Robot = typeof robots.$inferSelect;
export type NewRobot = typeof robots.$inferInsert;
export type Task = typeof tasks.$inferSelect;
export type NewTask = typeof tasks.$inferInsert;
export type MaintenanceRecord = typeof maintenanceRecords.$inferSelect;
export type NewMaintenanceRecord = typeof maintenanceRecords.$inferInsert;
export type PerformanceMetric = typeof performanceMetrics.$inferSelect;
export type NewPerformanceMetric = typeof performanceMetrics.$inferInsert;
```
**4. CORE FEATURES & USER FLOW:**
* **User Authentication:**
* **Flow:** Users access the login page. They can log in via Google OAuth or email/password. New users are prompted to sign up. Role-based access control is enforced (Admin, Manager, Technician, Viewer).
* **Details:** Use NextAuth.js. Implement middleware for route protection based on user role. Redirect unauthenticated users to login. Handle signup, login, password reset (optional for MVP), and logout.
* **Dashboard (Manager/Admin View):**
* **Flow:** Upon login, users see a dashboard summarizing key information.
* **Details:** Display total robots online/offline/maintenance, number of active tasks, upcoming maintenance alerts, and a quick overview of recent performance metrics. Utilize summary cards and possibly a small chart.
* **Robot Fleet Management:**
* **Flow:** Navigate to 'Robots' page. View a paginated, sortable, and searchable table of all robots. Add new robots, edit existing ones (model, type, location, status), and view robot details.
* **Details:** Implement CRUD operations for the `robots` table. Use `DataTable` component from shadcn/ui. Forms for adding/editing robots with validation (serial number must be unique, model is required). Status updates can be manual (via form) or automated (simulated via API endpoint for MVP).
* **Task Management:**
* **Flow:** Navigate to 'Tasks' page. View a table of tasks (pending, assigned, in progress, completed). Create new tasks, assign them to available robots (manual assignment for MVP), update task status, and view task details.
* **Details:** Implement CRUD for `tasks`. Forms for task creation (title, description, priority, schedule time). Filtering by status and priority. When a task is assigned, update the `assignedRobotId` in the `tasks` table and potentially the `assignedTaskId` in the `robots` table. Update task status through UI interactions (e.g., buttons on the task detail or table row).
* **Maintenance Scheduling:**
* **Flow:** Navigate to 'Maintenance' page. View a calendar or list of scheduled maintenance. Schedule new maintenance for a specific robot and date. Mark maintenance as complete.
* **Details:** CRUD operations for `maintenanceRecords`. Use a DatePicker component. Link maintenance to a robot. Allow marking as complete, potentially linking to the technician who performed it.
* **Performance Monitoring:**
* **Flow:** View performance metrics on a robot's detail page or a dedicated monitoring section. See historical data and trends.
* **Details:** (Simplified MVP) An API route `POST /api/robots/:id/metrics` to receive metric updates (e.g., battery level, operational status). A page to view these metrics, potentially with a simple chart showing battery level over time for a selected robot.
**5. API & DATA FETCHING:**
- Use Next.js API Routes (`app/api/...`) for backend logic.
- Employ Drizzle ORM for all database interactions within API routes or server actions.
- Fetch data in Server Components where possible for SEO and performance.
- Use Client Components for interactive elements, fetching data via API routes or Server Actions if necessary.
- **API Examples:**
- `POST /api/auth/...`: Handled by NextAuth.js
- `GET /api/robots`: Fetch list of robots (with filtering/pagination params)
- `POST /api/robots`: Create a new robot
- `GET /api/robots/:id`: Fetch single robot details (including relations like assigned task)
- `PUT /api/robots/:id`: Update robot details
- `DELETE /api/robots/:id`: Delete a robot
- `GET /api/tasks`: Fetch list of tasks
- `POST /api/tasks`: Create a new task
- `PUT /api/tasks/:id`: Update task status, assignment, etc.
- `POST /api/robots/:id/metrics`: (Internal/Simulated) Endpoint to receive performance data.
- **Data Fetching in Server Components:**
```typescript
// Example in app/dashboard/robots/page.tsx
import { db } from '@/lib/drizzle'; // Your Drizzle instance
import { robots } from '@/lib/schema'; // Your schema
import { eq } from 'drizzle-orm';
async function getRobots() {
return await db.query.robots.findMany({
with: { assignedTask: true }, // Example using relations
});
}
export default async function RobotsPage() {
const robots = await getRobots();
// ... render DataTable using robots data
}
```
**6. COMPONENT BREAKDOWN (Next.js App Router):**
* **`app/`**
* **`layout.tsx`**: Root layout (html, body, Tailwind init, ThemeProvider, global providers).
* **`page.tsx`**: Landing Page (public).
* **`auth/`**: Auth pages (login, signup).
* `layout.tsx`: Auth layout.
* `login/page.tsx`: Login form.
* **`dashboard/`**: Authenticated user area.
* `layout.tsx`: Main dashboard layout (sidebar, header, content area).
* `page.tsx`: Main dashboard overview (summary cards, alerts).
* **`robots/`**:
* `page.tsx`: Robot list page (includes `RobotDataTable` component).
* `components/RobotDataTable.tsx` (Client Component): Handles table interactions, search, pagination, buttons.
* `components/AddEditRobotForm.tsx` (Client Component): Modal form for adding/editing robots.
* `loading.tsx`: Loading UI for the robots page.
* **`tasks/`**:
* `page.tsx`: Task list page (includes `TaskDataTable`).
* `components/TaskDataTable.tsx` (Client Component): Table for tasks.
* `components/AddTaskForm.tsx` (Client Component): Modal form for adding tasks.
* `components/TaskDetailView.tsx` (Client Component): Displays task details and status updates.
* **`maintenance/`**:
* `page.tsx`: Maintenance schedule page (includes `MaintenanceCalendar` or `MaintenanceList`).
* `components/MaintenanceForm.tsx` (Client Component): Form for scheduling maintenance.
* `components/MaintenanceCalendar.tsx` (Client Component): Calendar view.
* **`robots/[id]/page.tsx`**: Individual Robot Detail Page (Server Component or Client Component fetching data).
* Displays robot info, status, assigned task, recent metrics, maintenance history.
* Includes `RobotStatusBadge`, `MetricChart`, `TaskInfoCard` components.
* **`api/`**: API Routes.
* `auth/[...nextauth]/route.ts`: NextAuth.js handler.
* `robots/route.ts`: Handles GET/POST for `/api/robots`.
* `robots/[id]/route.ts`: Handles GET/PUT/DELETE for `/api/robots/:id`.
* `tasks/route.ts`: Handles GET/POST for `/api/tasks`.
* `tasks/[id]/route.ts`: Handles PUT for `/api/tasks/:id`.
* `maintenance/route.ts`: CRUD for maintenance.
* `robots/[id]/metrics/route.ts`: POST for receiving metrics.
* **`components/`**: Shared UI components.
* `ui/`: Re-exports from shadcn/ui (`Button`, `Input`, `Card`, `Table`, `Dialog`, `DatePicker`, `Select`, `Toaster`, `Spinner`, `Form`, `FormField`, `Label`, `FormControl`, `FormMessage`, etc.).
* `AuthButton.tsx`: Button to handle login/logout states.
* `Sidebar.tsx`: Navigation sidebar.
* `Header.tsx`: Top navigation bar.
* `ChartComponent.tsx`: Wrapper for Recharts.
* `StatusBadge.tsx`: Displays status with color coding.
* **`lib/`**: Utility code.
* `db.ts`: Drizzle database connection setup.
* `schema.ts`: Database schema definition.
* `auth.ts`: NextAuth.js configuration.
* `utils.ts`: General utility functions.
* `validation.ts`: Zod schemas for form validation.
* **`hooks/`**: Custom React hooks (e.g., `useRobotStatus`, `useTaskProgress`).
* **`providers/`**: Context providers (e.g., `ThemeProvider`).
**7. UI/UX DESIGN & VISUAL IDENTITY:**
- **Style:** Modern, Clean, Professional with a touch of futuristic/tech aesthetic.
- **Color Palette:**
- Primary: `#007AFF` (Vibrant Blue - for actions, links)
- Secondary: `#5856D6` (Deep Purple - for accents, headers)
- Accent/Success: `#34C759` (Green - for online status, completion)
- Warning: `#FF9500` (Orange - for maintenance, pending)
- Danger: `#FF3B30` (Red - for error status, offline)
- Background: `#F5F5F7` (Light Gray - main background)
- Card/Surface: `#FFFFFF` (White - for content cards)
- Text (Dark): `#1D1D1F` (Near Black - primary text)
- Text (Light): `#8E8E93` (Gray - secondary text)
- **Typography:** System fonts (San Francisco for macOS/iOS, Roboto for Android, Arial/Helvetica as fallback). Use Tailwind's font size and weight utilities (e.g., `text-lg font-semibold`).
- **Layout:** Use a standard dashboard layout: Left-hand sidebar for navigation, top header, main content area. Utilize Tailwind's grid and flexbox for responsive layouts. Cards for summarizing information.
- **Responsiveness:** Mobile-first approach. Ensure usability on tablets and desktops. Sidebar might collapse into a hamburger menu on smaller screens.
- **Branding:** Subtle use of the primary/secondary colors. Clean logos.
**8. SAMPLE/MOCK DATA:**
* **Robots:**
1. `{ id: 1, serialNumber: 'RBT-JP-A001', model: 'Kawada HRP-4', type: 'warehouse', status: 'online', location: 'Warehouse A, Zone 3', lastMaintenance: '2024-01-15T10:00:00Z', assignedTaskId: null }`
2. `{ id: 2, serialNumber: 'RBT-JP-B005', model: 'Fanuc M-20iA', type: 'manufacturing', status: 'maintenance', location: 'Factory Floor 2', lastMaintenance: '2024-05-01T09:00:00Z', assignedTaskId: null }`
3. `{ id: 3, serialNumber: 'RBT-JP-C112', model: 'ABB YuMi', type: 'assembly', status: 'in_use', location: 'Assembly Line 1', lastMaintenance: '2024-03-20T14:30:00Z', assignedTaskId: 101 }`
4. `{ id: 4, serialNumber: 'RBT-JP-D007', model: 'Denso VP-80', type: 'inspection', status: 'online', location: 'Infrastructure Sector 7', lastMaintenance: '2023-11-10T11:00:00Z', assignedTaskId: null }`
5. `{ id: 5, serialNumber: 'RBT-JP-E020', model: 'Seiko Epson T6', type: 'logistics', status: 'offline', location: 'Loading Dock 5', lastMaintenance: '2024-04-25T16:00:00Z', assignedTaskId: null }`
* **Tasks:**
1. `{ id: 101, title: 'Package Item XYZ', description: 'Pick up Item XYZ from Shelf B-12 and place in outgoing bin.', priority: 'high', status: 'in_progress', assignedRobotId: 3, scheduledAt: '2024-05-10T10:00:00Z', completedAt: null }`
2. `{ id: 102, title: 'Routine Infrastructure Scan', description: 'Perform visual and thermal scan of Sector 7 Bridge supports.', priority: 'medium', status: 'pending', assignedRobotId: null, scheduledAt: '2024-05-11T08:00:00Z', completedAt: null }`
3. `{ id: 103, title: 'Re-stock Shelf C-5', description: 'Move 10 units of Product ABC from storage to Shelf C-5.', priority: 'low', status: 'pending', assignedRobotId: null, scheduledAt: '2024-05-10T14:00:00Z', completedAt: null }`
* **Maintenance Records:**
1. `{ id: 1, robotId: 2, technicianId: 1, scheduledDate: '2024-05-05T09:00:00Z', completionDate: '2024-05-05T11:30:00Z', notes: 'Replaced actuator on joint 3.', isCompleted: true }`
2. `{ id: 2, robotId: 1, technicianId: 1, scheduledDate: '2024-05-15T10:00:00Z', completionDate: null, notes: 'Scheduled for routine calibration.', isCompleted: false }`
**9. TURKISH TRANSLATIONS (Key UI Elements):**
- **App Title:** RoboFill
- **Login Page:**
- `title`: 'RoboFill'e Giriş Yapın'
- `login_button`: 'Giriş Yap'
- `signup_button`: 'Kayıt Ol'
- `oauth_google`: 'Google ile Giriş Yap'
- **Dashboard:**
- `title`: 'Genel Bakış'
- `total_robots`: 'Toplam Robot'
- `online_robots`: 'Çevrimiçi Robotlar'
- `maintenance_robots`: 'Bakımdaki Robotlar'
- `active_tasks`: 'Aktif Görevler'
- `upcoming_maintenance`: 'Yaklaşan Bakımlar'
- **Robots Page:**
- `page_title`: 'Robot Filosu'
- `add_robot_button`: 'Robot Ekle'
- `robot_table_header`: ['Seri No', 'Model', 'Tip', 'Durum', 'Konum', 'Son Bakım', 'İşlemler']
- `robot_status_online`: 'Çevrimiçi'
- `robot_status_offline`: 'Çevrimdışı'
- `robot_status_maintenance`: 'Bakımda'
- `robot_status_in_use`: 'Kullanımda'
- `robot_status_error`: 'Hata'
- `edit_robot`: 'Düzenle'
- `delete_robot`: 'Sil'
- `robot_form_serial`: 'Seri Numarası'
- `robot_form_model`: 'Model'
- `robot_form_type`: 'Tip'
- `robot_form_location`: 'Konum'
- `robot_form_status`: 'Durum'
- `robot_form_save`: 'Kaydet'
- **Tasks Page:**
- `page_title`: 'Görev Yönetimi'
- `add_task_button`: 'Görev Ekle'
- `task_table_header`: ['Başlık', 'Öncelik', 'Durum', 'Atanan Robot', 'Zamanlandı', 'Tamamlandı', 'İşlemler']
- `task_priority_low`: 'Düşük'
- `task_priority_medium`: 'Orta'
- `task_priority_high`: 'Yüksek'
- `task_priority_critical`: 'Kritik'
- `task_status_pending`: 'Bekliyor'
- `task_status_assigned`: 'Atandı'
- `task_status_in_progress`: 'Devam Ediyor'
- `task_status_completed`: 'Tamamlandı'
- `task_status_failed`: 'Başarısız'
- `task_status_cancelled`: 'İptal Edildi'
- `task_form_title`: 'Görev Başlığı'
- `task_form_description`: 'Açıklama'
- `task_form_priority`: 'Öncelik'
- `task_form_assign_robot`: 'Robot Ata'
- `task_form_schedule_time`: 'Zamanla'
- **Maintenance Page:**
- `page_title`: 'Bakım Takvimi'
- `schedule_maintenance_button`: 'Bakım Planla'
- `maintenance_robot`: 'Robot'
- `maintenance_date`: 'Tarih'
- `maintenance_technician`: 'Teknisyen'
- `maintenance_completed`: 'Tamamlandı'
- `maintenance_notes`: 'Notlar'
- `maintenance_form_robot`: 'Bakım Yapılacak Robot'
- `maintenance_form_date`: 'Planlanan Tarih'
- `maintenance_form_technician`: 'Teknisyen (Opsiyonel)'
**10. ANIMATIONS:**
- Use Tailwind CSS transitions for subtle hover effects on buttons and interactive elements (e.g., `transition-colors duration-200 ease-in-out`).
- Implement skeleton loaders or spinners (using shadcn/ui's `Skeleton` or `Spinner` components) for data fetching states on tables and cards.
- Animate status changes (e.g., a brief color flash when a robot status updates).
- Consider subtle parallax effects on the landing page if applicable.
**11. EDGE CASES:**
- **Empty States:** Design informative empty states for tables (e.g., 'Henüz robot eklenmedi. Robot eklemek için tıklayın.') and dashboard widgets.
- **Authentication:** Handle expired sessions, unauthorized access attempts (redirect to login or show a message).
- **Form Validation:** Implement robust client-side (Zod + React Hook Form) and server-side validation for all form inputs. Provide clear error messages.
- **API Errors:** Gracefully handle API errors (e.g., network issues, server errors). Display user-friendly messages using the `Toaster` component. Implement appropriate HTTP status codes.
- **Data Integrity:** Ensure relational integrity in the database (e.g., cannot delete a robot with active tasks if the logic doesn't allow it). Handle potential race conditions in concurrent updates if necessary (though less critical for MVP).
- **Robot Status Synchronization:** In a real-world scenario, robot status would be updated via a separate mechanism (e.g., MQTT, WebSockets). For MVP, simulate status updates via API calls or manual updates in the UI.