You are an expert AI assistant tasked with generating a complete, fully functional Next.js MVP application based on the 'AeroGuard' concept. This application aims to significantly reduce the risk of mid-air collisions between aircraft and ground vehicles at airports by providing real-time alerts and enhanced operational awareness. The project must be a multi-page, production-ready MVP, not just a landing page or a simple SPA.
**1. PROJECT OVERVIEW:**
* **App Name:** AeroGuard (SafeLanding)
* **Problem Solved:** Inadequate real-time communication and risk assessment between air traffic control (ATC), pilots, and ground vehicles at airports leads to critical safety hazards, including fatal collisions. The current systems often lack integrated, intelligent threat detection for ground-air interactions.
* **Value Proposition:** AeroGuard provides a proactive safety solution by leveraging AI to predict and alert users about potential collisions between aircraft and ground vehicles in real-time. It enhances situational awareness for all stakeholders (ATC, pilots, ground crew), integrates disparate data sources (flight plans, vehicle movements, sensor data), and ultimately aims to prevent accidents, saving lives and reducing operational disruptions.
* **Target User:** Airport operators, Air Traffic Control centers, airline operations, ground handling services, and flight schools.
**2. TECH STACK:**
* **Frontend Framework:** Next.js (App Router)
* **UI Library:** shadcn/ui (for accessible, reusable components)
* **Styling:** Tailwind CSS
* **State Management:** React Context API (for global state) and component-local state. Consider Zustand or Jotai for more complex global state if needed.
* **Backend/API:** Next.js API Routes (or a separate Node.js/Express server if complexity demands)
* **Database:** PostgreSQL (via Drizzle ORM)
* **ORM:** Drizzle ORM (for type-safe database interactions)
* **Authentication:** NextAuth.js (with PostgreSQL adapter for user data persistence)
* **Real-time Communication:** WebSockets (e.g., using Socket.IO or native WebSocket API) for live map updates and alerts.
* **Mapping:** Leaflet.js or Mapbox GL JS for interactive maps.
* **Charting (Optional for MVP, but good to consider for future):** Recharts or Chart.js
* **Form Handling:** React Hook Form with Zod for validation.
* **Deployment:** Vercel or similar platform.
**3. DATABASE SCHEMA (PostgreSQL with Drizzle ORM syntax):**
```typescript
// schema.ts
import { pgTable, serial, text, timestamp, boolean, varchar, pgEnum, uuid, jsonb, decimal } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// Enums
export const userRoleEnum = pgEnum('user_role', ['admin', 'atc', 'pilot', 'ground_crew', 'viewer']);
// Users Table
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name'),
email: varchar('email', { length: 255 }).notNull().unique(),
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(),
});
export const accounts = pgTable('accounts', {
...standardBasicFields,
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
type: varchar('type', { length: 255 }).$takenFrom('oauth_provider'), // oauth, email, etc.
provider: varchar('provider', { length: 255 }).notNull(), // github, google, etc.
providerAccountId: varchar('providerAccountId', { length: 255 }).notNull(),
refresh_token: text('refresh_token'),
access_token: text('access_token'),
expires_at: bigint('expires_at'),
token_type: varchar('token_type', { length: 255 }),
scope: varchar('scope', { length: 255 }),
id_token: text('id_token'),
session_state: varchar('session_state', { length: 255 }),
});
export const sessions = pgTable('sessions', {
...standardBasicFields,
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', {
...standardBasicFields,
identifier: varchar('identifier', { length: 255 }).notNull(),
token: varchar('token', { length: 255 }).notNull().unique(),
expires: timestamp('expires', { mode: 'date' }).notNull(),
});
// Airport Table (optional for MVP, can be hardcoded or managed via admin panel)
export const airports = pgTable('airports', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 255 }).notNull(),
iataCode: varchar('iataCode', { length: 3 }).notNull().unique(),
icaoCode: varchar('icaoCode', { length: 4 }).notNull().unique(),
latitude: decimal('latitude').notNull(),
longitude: decimal('longitude').notNull(),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Aircraft Table
export const aircraft = pgTable('aircraft', {
id: uuid('id').primaryKey().defaultRandom(),
callsign: varchar('callsign', { length: 50 }).notNull().unique(), // e.g., 'N12345', 'BAW123'
type: varchar('type', { length: 100 }), // e.g., 'Boeing 737', 'Cessna 172'
currentAirportId: serial('currentAirportId').references(() => airports.id),
assignedUserId: uuid('assignedUserId').references(() => users.id),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Ground Vehicle Table
export const groundVehicles = pgTable('ground_vehicles', {
id: uuid('id').primaryKey().defaultRandom(),
vehicleId: varchar('vehicleId', { length: 50 }).notNull().unique(), // e.g., 'TUG01', 'Refueler-5'
type: varchar('type', { length: 100 }), // e.g., 'Tug', 'Fuel Truck', 'Service Cart'
currentAirportId: serial('currentAirportId').references(() => airports.id),
assignedUserId: uuid('assignedUserId').references(() => users.id),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
});
// Real-time Position Data (to be updated frequently via WebSockets/API)
export const positionData = pgTable('position_data', {
id: uuid('id').primaryKey().defaultRandom(),
entityType: pgEnum('entity_type', ['aircraft', 'ground_vehicle']),
entityId: uuid('entityId').notNull(), // References aircraft.id or groundVehicles.id
airportId: serial('airportId').references(() => airports.id),
latitude: decimal('latitude'),
longitude: decimal('longitude'),
altitude: decimal('altitude'), // In feet
heading: decimal('heading'), // Degrees from North (0-360)
speed: decimal('speed'), // Knots or km/h
timestamp: timestamp('timestamp', { mode: 'date' }).defaultNow(),
// Drizzle requires a way to link to the specific entity, typically done at the application level or via a union type if supported.
// For simplicity here, we assume application logic determines if entityId refers to aircraft or groundVehicle.
});
// Alerts Table
export const alerts = pgTable('alerts', {
id: uuid('id').primaryKey().defaultRandom(),
alertType: varchar('alertType', { length: 100 }).notNull(), // e.g., 'Proximity Alert', 'Runway Incursion'
severity: pgEnum('severity', ['low', 'medium', 'high', 'critical']).notNull().default('medium'),
triggeringEntityType: pgEnum('triggering_entity_type', ['aircraft', 'ground_vehicle']),
triggeringEntityId: uuid('triggeringEntityId').notNull(),
relatedEntityType: pgEnum('related_entity_type', ['aircraft', 'ground_vehicle']),
relatedEntityId: uuid('relatedEntityId').notNull(),
message: text('message').notNull(),
status: pgEnum('alert_status', ['new', 'acknowledged', 'resolved', 'closed']).notNull().default('new'),
resolvedByUserId: uuid('resolvedByUserId').references(() => users.id),
resolvedAt: timestamp('resolvedAt', { mode: 'date' }),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
airportId: serial('airportId').references(() => airports.id),
});
// Relations (Example for Users and Alerts)
export const userRelations = relations(users, ({ many }) => ({
alerts: many(alerts, { relationName: 'resolvedAlerts' }),
}));
export const alertsRelations = relations(alerts, ({ one }) => ({
resolvedByUser: one(users, {
fields: [alerts.resolvedByUserId],
references: [users.id],
relationName: 'resolvedAlerts',
}),
triggeringEntity: undefined, // This would require more complex schema/application logic to link dynamically
relatedEntity: undefined, // This would require more complex schema/application logic to link dynamically
}));
// Helper for common fields if needed across multiple tables
const standardBasicFields = {
id: uuid('id').primaryKey().defaultRandom(),
createdAt: timestamp('createdAt', { mode: 'date' }).defaultNow(),
updatedAt: timestamp('updatedAt', { mode: 'date' }).defaultNow(),
};
// NOTE: The 'positionData' table is designed for high-frequency updates. Consider using a time-series database or a more optimized approach for large-scale deployments. For MVP, a standard PostgreSQL table is acceptable, but be mindful of write performance.
// The dynamic linking of 'triggeringEntityId' and 'relatedEntityId' in 'alerts' might require application-level logic rather than direct foreign keys if the types can vary.
```
**4. CORE FEATURES & USER FLOW:**
* **User Authentication (NextAuth.js):**
* **Flow:** User accesses `/auth/signin`. Options: Google OAuth, Email/Password. Upon successful login, user is redirected to the dashboard. Role is assigned during signup or by an admin.
* **Edge Cases:** Invalid credentials, account lockout (if implemented), email verification (if not using OAuth).
* **Real-time Dashboard (Protected Route `/dashboard`):**
* **UI:** Interactive map (Leaflet/Mapbox) showing live positions of aircraft and ground vehicles within a selected airport. A sidebar displays alerts, flight schedules, and vehicle status.
* **Data Flow:** WebSocket connection established upon dashboard load. Server pushes real-time position updates (`positionData`) and new alerts. Map markers update dynamically. Alerts trigger visual/audible notifications.
* **User Interaction:** Users can click on map entities to see details (callsign, type, speed, altitude, destination). Users can acknowledge/resolve alerts from the sidebar.
* **Edge Cases:** WebSocket connection errors, empty map state (no entities), map loading states.
* **Turkish Translations:** Dashboard (Kontrol Paneli), Live Map (Canlı Harita), Alerts (Uyarılar), Acknowledge (Onayla), Resolve (Çözüldü).
* **Alert Management (Protected Routes `/alerts`, `/alerts/[id]`):**
* **UI:** A paginated table listing all alerts, filterable by status, severity, type, and date. Each row links to a detail page.
* **Detail Page (`/alerts/[id]`):** Shows full alert details, triggering/related entities, history, and options to acknowledge/resolve (if role permits).
* **Functionality:** Alerts generated by the AI engine appear here. Users with appropriate roles can change alert status.
* **Edge Cases:** No alerts found, invalid alert ID, permission errors for status changes.
* **Turkish Translations:** All Alerts (Tüm Uyarılar), New (Yeni), Acknowledged (Onaylandı), Resolved (Çözüldü), Severity (Önem Derecesi), Critical (Kritik).
* **Entity Management (Protected Routes `/entities/aircraft`, `/entities/vehicles` - potentially Admin only for MVP):**
* **UI:** Tables listing registered aircraft and ground vehicles. Forms for adding new entities (including assigning initial airport, type, etc.).
* **Functionality:** CRUD operations for aircraft and vehicles. (For MVP, focus on viewing; adding might be simplified or admin-only).
* **Edge Cases:** Duplicate vehicle/aircraft IDs, invalid data entry.
* **Turkish Translations:** Aircraft (Uçaklar), Ground Vehicles (Yer Araçları), Add New (Yeni Ekle), Edit (Düzenle).
* **AI Alert Generation Logic (Backend Service):**
* **Input:** Real-time position data stream (`positionData`), flight plan data (simplified for MVP: destination/origin from `aircraft` table).
* **Process:** Continuously analyze proximity between aircraft and vehicles. Calculate Time-to-Collision (TTC) and Distance-to-Collision (DTC). Implement rules:
* If `distance < threshold_X` AND `TTC < threshold_Y` for aircraft near runway/taxiway and a ground vehicle.
* If `distance < threshold_Z` for any two entities on active taxiways/runways.
* Consider altitude for aircraft (vertical separation).
* **Output:** Create new entries in the `alerts` table with appropriate details (type, severity, message, triggering/related entities).
* **Note:** This logic will be implemented within Next.js API routes or a separate service that interacts with the DB and potentially pushes alerts via WebSockets.
**5. API & DATA FETCHING:**
* **API Routes (`/pages/api/...` or `app/api/...` in App Router):**
* `POST /api/auth/[...nextauth]`: Handled by NextAuth.js.
* `GET /api/alerts`: Fetch paginated alerts, with query params for filtering (status, severity, etc.). Requires authentication.
* `GET /api/alerts/[id]`: Fetch single alert details. Requires authentication.
* `PUT /api/alerts/[id]/status`: Update alert status (acknowledge/resolve). Requires authentication and role check.
* `GET /api/entities/aircraft`: Fetch list of aircraft. Requires authentication.
* `GET /api/entities/vehicles`: Fetch list of ground vehicles. Requires authentication.
* `POST /api/entities/aircraft` & `POST /api/entities/vehicles`: Create new entities (Admin role).
* `POST /api/position-update`: Endpoint for external systems or simulation to push position data (requires authentication/API key).
* **WebSocket (`/lib/ws/server.ts`, `/lib/ws/client.ts`):**
* **Server:** Broadcasts new position updates and alerts to connected clients.
* **Client:** Establishes connection on dashboard load, listens for `positionUpdate` and `newAlert` events, updates map and UI accordingly.
* **Data Fetching:** Use server components for initial data load (e.g., static lists, user profile) and client components with `useEffect` or libraries like SWR/React Query for dynamic/real-time data and mutations.
**6. COMPONENT BREAKDOWN (Next.js App Router Structure):**
* `/app/layout.tsx`: Root layout (HTML, Body, Global Providers, Tailwind CSS setup).
* `/app/page.tsx`: Landing Page (Marketing content, sign-in prompt).
* `/app/(auth)/signin/page.tsx`: Sign-in form.
* `/app/(protected)/dashboard/page.tsx`: Main dashboard. Includes MapComponent, AlertFeedComponent, EntityDetailModal.
* `/app/(protected)/alerts/page.tsx`: Alerts list page. Includes AlertTableComponent, AlertFilterComponent.
* `/app/(protected)/alerts/[id]/page.tsx`: Single alert detail page. Includes AlertDetailComponent.
* `/app/(protected)/entities/aircraft/page.tsx`: Aircraft list page. Includes EntityTableComponent, EntityFormModal.
* `/app/(protected)/entities/vehicles/page.tsx`: Vehicle list page. Includes EntityTableComponent, EntityFormModal.
* `/app/api/...`: API routes.
* `/components/ui/...`: Re-usable shadcn/ui components (Button, Input, Card, Table, Dialog, etc.).
* `/components/layout/`: NavbarComponent, SidebarComponent, FooterComponent.
* `/components/map/`: MapComponent (integrates Leaflet/Mapbox), MarkerComponent.
* `/components/alerts/`: AlertTableComponent, AlertRowComponent, AlertDetailComponent, AlertFeedComponent.
* `/components/entities/`: EntityTableComponent, EntityRowComponent, EntityFormComponent, EntityDetailModal.
* `/lib/`: Database connection (Drizzle), auth (NextAuth.js config), WebSocket client/server logic, utility functions, AI logic placeholder.
* `/hooks/`: Custom React hooks (e.g., `useWebSocket`, `useFetchAlerts`).
* `/styles/globals.css`: Tailwind CSS base styles.
**7. UI/UX DESIGN & VISUAL IDENTITY:**
* **Design Style:** Modern, Clean, Professional with a hint of urgency for alerts.
* **Color Palette:**
* Primary: Deep Blue (`#0A192F` - Dark Background)
* Secondary: Teal (`#61DAFB` - Accent for active elements, links)
* Alerts:
* Critical: Bright Red (`#FF0000`)
* High: Orange (`#FFA500`)
* Medium: Yellow (`#FFFF00`)
* Low: Light Blue (`#ADD8E6`)
* Text: Off-white (`#F0F0F0`)
* Subtle UI Elements: Light Gray (`#4A5568`)
* **Typography:** Sans-serif. Use Inter or similar modern font family (e.g., from Google Fonts).
* Headings: Bold, larger sizes (e.g., 2.5rem for H1, 2rem for H2).
* Body Text: Regular weight, comfortable reading size (e.g., 1rem).
* **Layout:** Utilize Next.js App Router's layout system. Use a main content area with a fixed sidebar for navigation and alerts. Ensure consistent padding and spacing.
* **Responsiveness:** Mobile-first approach. Sidebar might collapse into a hamburger menu on smaller screens. Map should be zoomable and pannable. Tables should be responsive (e.g., horizontal scroll or column collapsing).
* **Visual Elements:** Clean icons (Lucide React from shadcn/ui), subtle loading spinners, clear visual hierarchy.
**8. SAMPLE/MOCK DATA:**
* **User (Admin):**
```json
{
"id": "uuid-admin-1", "name": "Admin User", "email": "admin@aeroguard.com", "role": "admin", "image": "/path/to/admin.jpg"
}
```
* **User (ATC):**
```json
{
"id": "uuid-atc-1", "name": "Air Traffic Control", "email": "atc@laguardia.org", "role": "atc", "image": null
}
```
* **Airport:**
```json
{
"id": 1, "name": "LaGuardia Airport", "iataCode": "LGA", "icaoCode": "KLGA", "latitude": 40.7769, "longitude": -73.8740
}
```
* **Aircraft:**
```json
{
"id": "uuid-ac-1", "callsign": "AAL123", "type": "Airbus A320", "currentAirportId": 1
}
```
* **Ground Vehicle:**
```json
{
"id": "uuid-gv-1", "vehicleId": "TUG05", "type": "Tug", "currentAirportId": 1
}
```
* **Position Data (Aircraft):**
```json
{
"entityType": "aircraft", "entityId": "uuid-ac-1", "airportId": 1, "latitude": 40.7770, "longitude": -73.8735, "altitude": 50, "heading": 270, "speed": 10, "timestamp": "2023-10-27T10:00:05Z"
}
```
* **Position Data (Vehicle):**
```json
{
"entityType": "ground_vehicle", "entityId": "uuid-gv-1", "airportId": 1, "latitude": 40.7760, "longitude": -73.8730, "altitude": 0, "heading": 90, "speed": 5, "timestamp": "2023-10-27T10:00:06Z"
}
```
* **Alert (Critical Proximity):**
```json
{
"id": "uuid-alert-1", "alertType": "Proximity Alert", "severity": "critical", "triggeringEntityType": "aircraft", "triggeringEntityId": "uuid-ac-1", "relatedEntityType": "ground_vehicle", "relatedEntityId": "uuid-gv-1", "message": "Critical proximity detected between AAL123 and TUG05 on taxiway B.", "status": "new", "createdAt": "2023-10-27T10:00:07Z", "airportId": 1
}
```
**9. ANIMATIONS:**
* **Transitions:** Smooth fades for modals, dialogs, and route changes (`transition` classes in Tailwind CSS).
* **Hover Effects:** Subtle background changes or scaling on interactive elements (buttons, table rows).
* **Loading States:** Skeleton loaders or spinners for data fetching, especially on the dashboard map and alert tables. Use `react- شadcn/ui`'s loading spinners or implement custom ones.
* **Map Animations:** Smooth marker movement for entity positions updating in real-time. Consider easing functions for a less jarring experience.
**10. EDGE CASES & VALIDATIONS:**
* **Authentication:** Handle expired sessions, unauthorized access attempts gracefully (redirect to login, show error messages).
* **Data Validation:** Use Zod with React Hook Form for all form inputs (entity creation, settings) to ensure data integrity before submission. Implement server-side validation in API routes.
* **Empty States:** Design informative empty states for tables (e.g., "No alerts generated yet.") and the map (e.g., "Select an airport to view activity.").
* **Error Handling:** Implement try-catch blocks in API routes and data fetching functions. Display user-friendly error messages using toast notifications (e.g., using `react- شadcn/ui`'s Toast component).
* **WebSocket Disconnection:** Implement reconnection logic for WebSockets. Provide visual feedback to the user if the real-time connection is lost.
* **AI Logic Failures:** If the AI prediction service encounters an error or cannot generate an alert, log the error and potentially create a lower-severity 'System Health' alert.
* **Permissions:** Ensure role-based access control is strictly enforced for all actions (e.g., only admins can add entities, only ATC/Admins can resolve critical alerts).
**11. TURKISH TRANSLATIONS:**
* **General:** App Title (AeroGuard), Sign In (Giriş Yap), Sign Out (Çıkış Yap), Dashboard (Kontrol Paneli), Settings (Ayarlar), Alerts (Uyarılar), Entities (Varlıklar), Aircraft (Uçaklar), Ground Vehicles (Yer Araçları), New (Yeni), Add (Ekle), Edit (Düzenle), Delete (Sil), Save (Kaydet), Cancel (İptal), Acknowledge (Onayla), Resolve (Çözüldü), Critical (Kritik), High (Yüksek), Medium (Orta), Low (Düşük), Real-time Map (Gerçek Zamanlı Harita), No data available (Veri Yok).
* **Alert Messages:** "Critical proximity detected between {entity1} ({type1}) and {entity2} ({type2}) on {location}." -> "Kritik yakınlık algılandı: {entity1} ({type1}) ve {entity2} ({type2}) arasında {location} üzerinde."
* **UI Labels:** Call Sign (Çağrı Kodu), Vehicle ID (Araç ID), Type (Tipi), Status (Durum), Severity (Önem Derecesi), Timestamp (Zaman Damgası), Resolved By (Çözen Kullanıcı).
This detailed prompt provides all necessary information to generate a robust and functional MVP application.