You are tasked with developing a full-stack MVP for a 'Liveable Cities' platform using Next.js 14 App Router, React, TypeScript, Tailwind CSS, and Drizzle ORM (configured for PostgreSQL or SQLite for local development). The application should have a multi-page structure and implement full CRUD functionality for key features. Focus on functionality over elaborate design, ensuring all core features are operational.
**Project Setup:**
1. Initialize a new Next.js project with TypeScript and Tailwind CSS.
2. Set up Drizzle ORM with a schema file (drizzle/schema.ts) and a Drizzle config (drizzle.config.ts). Use environment variables for database connection.
**Database Schema (drizzle/schema.ts):**
Define the following tables with appropriate fields and relationships:
1. **Users:**
* `id` (uuid, primary key)
* `email` (string, unique)
* `password_hash` (string, for basic auth or integrate a simple auth solution like next-auth for MVP if preferred)
* `username` (string, unique)
* `created_at` (timestamp, default now)
* `updated_at` (timestamp, default now, on update current_timestamp)
2. **Cities:**
* `id` (uuid, primary key)
* `name` (string, unique)
* `country` (string)
* `description` (text)
* `population` (integer)
* `avg_cost_of_living` (numeric)
* `transit_quality_score` (integer, 1-5)
* `food_convenience_score` (integer, 1-5)
* `safety_score` (integer, 1-5)
* `internet_speed_score` (integer, 1-5)
* `green_spaces_score` (integer, 1-5)
* `image_url` (string, optional)
* `created_at` (timestamp, default now)
* `updated_at` (timestamp, default now, on update current_timestamp)
3. **Reviews:**
* `id` (uuid, primary key)
* `city_id` (uuid, foreign key to Cities.id)
* `user_id` (uuid, foreign key to Users.id)
* `rating` (integer, 1-5)
* `comment` (text)
* `created_at` (timestamp, default now)
4. **UserPreferences:**
* `id` (uuid, primary key)
* `user_id` (uuid, unique, foreign key to Users.id)
* `preferred_transit_quality` (integer, 1-5, default 3)
* `preferred_food_convenience` (integer, 1-5, default 3)
* `preferred_safety` (integer, 1-5, default 3)
* `preferred_internet_speed` (integer, 1-5, default 3)
* `preferred_green_spaces` (integer, 1-5, default 3)
* `max_cost_of_living` (numeric, optional)
* `updated_at` (timestamp, default now, on update current_timestamp)
**API Routes (app/api/...):**
Implement the following API routes using Next.js Route Handlers:
1. `/api/auth/register` (POST): Register new user.
2. `/api/auth/login` (POST): Authenticate user and return a simple session token (for MVP, could be JWT).
3. `/api/cities` (GET, POST):
* GET: Fetch all cities with pagination/filtering options.
* POST: Create a new city (admin only, for MVP, assume no specific admin role, just a user creating it).
4. `/api/cities/[id]` (GET, PUT, DELETE):
* GET: Fetch a single city by ID, including its reviews.
* PUT: Update city details (admin only).
* DELETE: Delete a city (admin only).
5. `/api/reviews` (POST): Submit a new review for a city (requires user authentication).
6. `/api/users/[id]/preferences` (GET, PUT):
* GET: Fetch user preferences.
* PUT: Update user preferences (requires user authentication).
**Frontend Pages (app/...):**
Develop the following pages, leveraging server components where appropriate for data fetching and client components for interactivity.
1. **Homepage (`app/page.tsx`):**
* An introductory section.
* A search bar to find cities by name or country.
* Links to explore cities or compare.
2. **City List Page (`app/cities/page.tsx`):**
* Displays a list of all cities.
* Each city item should link to its detailed view.
* Basic filtering/sorting options (e.g., by country, score).
3. **City Detail Page (`app/cities/[id]/page.tsx`):**
* Shows all details for a specific city.
* Lists all reviews for that city.
* A form for authenticated users to submit a new review.
4. **User Profile & Preferences Page (`app/profile/page.tsx`):**
* Displays user information.
* A form to view and update user preferences (e.g., preferred transit quality, max cost of living).
* Requires user authentication.
5. **City Comparison Page (`app/compare/page.tsx`):**
* Allows users to select 2-3 cities to compare side-by-side.
* Displays key metrics for each selected city (e.g., scores for transit, food, safety, avg_cost_of_living).
* Highlight differences based on user's defined preferences (if available).
6. **Authentication Pages (`app/(auth)/login/page.tsx`, `app/(auth)/register/page.tsx`):**
* Simple forms for user login and registration.
**Key Requirements:**
* Implement full CRUD operations for cities and reviews via the defined API routes and Drizzle ORM.
* Ensure proper data validation for forms.
* Use Tailwind CSS for basic styling across all pages.
* Handle authentication state minimally (e.g., store a token in localStorage for MVP, or use NextAuth if it simplifies session management without overcomplicating the core task).
* Structure the App Router with logical groups (e.g., `(auth)` for login/register).
* Provide placeholder data or a seeding script for initial database population for testing.
**Deliverables:**
* `drizzle/schema.ts` with all table definitions.
* Example `drizzle.config.ts`.
* Example API route handlers (e.g., for `cities` and `reviews`).
* Example page components for `app/cities/[id]/page.tsx` and `app/compare/page.tsx`, demonstrating data fetching and interaction.
* A brief explanation of how to run migrations and seed the database.