## AI Master Prompt: Sovereign Host MVP - Next.js, Tailwind CSS, Drizzle ORM
### 1. PROJECT OVERVIEW
**App Title:** Sovereign Host
**Value Proposition:** Sovereign Host provides a decentralized, performant, and privacy-focused Content Delivery Network (CDN) and static site hosting platform. It aims to liberate users from the vendor lock-in and potential censorship risks associated with large, centralized cloud providers like Cloudflare. By offering a competitive, EU-based alternative, Sovereign Host empowers individuals and businesses to regain control over their digital infrastructure, ensuring data sovereignty and global accessibility.
**Problem Solved:** Addresses the growing concern over internet centralization, single points of failure, potential censorship, and data privacy issues stemming from reliance on dominant cloud infrastructure providers. Offers a transparent, performant, and user-controlled alternative for CDN and static hosting needs.
**Core Goal:** To build a fully functional, multi-page, production-ready MVP of Sovereign Host using the Next.js App Router, Tailwind CSS for styling, and Drizzle ORM for database interactions. The application must include robust user authentication, core CDN/hosting features, and a comprehensive management dashboard.
### 2. TECH STACK
* **Framework:** Next.js (App Router)
* **Styling:** Tailwind CSS v3+
* **Database ORM:** Drizzle ORM
* **Database:** PostgreSQL (recommended for Drizzle)
* **Authentication:** NextAuth.js (or Lucia Auth for more flexibility if needed, but NextAuth.js is simpler for MVP)
* **UI Components:** shadcn/ui (built on Radix UI & Tailwind CSS)
* **State Management:** React Context API & Server Components (for data fetching)
* **Form Handling:** React Hook Form + Zod (for validation)
* **API Layer:** Next.js API Routes (Server Actions for mutations)
* **Deployment:** Vercel (recommended for Next.js)
* **Other Packages:** `zod`, `bcrypt` (if not using NextAuth.js built-in), `uuid`, date-fns, charting library (e.g., Chart.js or Recharts)
### 3. DATABASE SCHEMA (PostgreSQL with Drizzle ORM)
```typescript
import { pgTable, text, timestamp, boolean, integer, uuid, primaryKey, varchar } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// Users Table (for authentication)
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name'),
email: text('email').unique().notNull(),
emailVerified: timestamp('emailVerified', { mode: 'date' }),
image: text('image'),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
export const accounts = pgTable(
'accounts',
{
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
type: varchar('type', {
length: 255,
}).$type<any>(),
provider: varchar('provider', {
length: 255,
}).notNull(),
providerAccountId: varchar('providerAccountId', {
length: 255,
}).notNull(),
refresh_token: text('refresh_token'),
access_token: text('access_token'),
expires_at: integer('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,
}),
},
(account) => ({
compoundKey: primaryKey(account.provider, account.providerAccountId),
}),
);
export const sessions = pgTable('sessions', {
sessionToken: varchar('sessionToken', {
length: 255,
}).primaryKey(),
userId: uuid('userId').notNull().references(() => users.id, {
onDelete: 'cascade',
}),
expires: timestamp('expires', {
mode: 'date',
}).notNull(),
});
export const verificationTokens = pgTable(
'verificationTokens',
{
identifier: text('identifier').notNull(),
token: text('token').notNull(),
expires: timestamp('expires', {
mode: 'date',
}).notNull(),
},
(vt) => ({
compoundKey: primaryKey(vt.identifier, vt.token),
}),
);
// CDN/Hosting Resources Table
export const sites = pgTable('sites', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('userId').notNull().references(() => users.id, { onDelete: 'cascade' }),
domainName: varchar('domainName', { length: 255 }).unique().notNull(), // e.g., 'myblog.com'
subdomain: varchar('subdomain', { length: 255 }).unique(), // e.g., 'www' or custom subdomain for platform hosting
originUrl: varchar('originUrl', { length: 255 }).notNull(), // URL of the user's origin server/storage
cdnEnabled: boolean('cdnEnabled').default(false),
hostingEnabled: boolean('hostingEnabled').default(false),
createdAt: timestamp('createdAt').defaultNow(),
updatedAt: timestamp('updatedAt').defaultNow(),
});
// CDN Performance Metrics (Example - can be expanded)
export const cdnMetrics = pgTable('cdnMetrics', {
id: uuid('id').primaryKey().defaultRandom(),
siteId: uuid('siteId').notNull().references(() => sites.id, { onDelete: 'cascade' }),
timestamp: timestamp('timestamp').defaultNow(),
bandwidthUsed: integer('bandwidthUsed').default(0), // in MB
requests: integer('requests').default(0),
// Add more metrics like cache hit ratio, latency per region etc.
});
// Relations (using Drizzle Relations)
export const userRelations = relations(users, ({ many }) => ({
sites: many(sites),
}));
export const siteRelations = relations(sites, ({ one, many }) => ({
user: one(users, {
fields: [sites.userId],
references: [users.id],
}),
metrics: many(cdnMetrics),
}));
export const cdnMetricRelations = relations(cdnMetrics, ({ one }) => ({
site: one(sites, {
fields: [cdnMetrics.siteId],
references: [sites.id],
}),
}));
// Attach relations to main tables for easier access
users.on(userRelations);
sites.on(siteRelations);
cdnMetrics.on(cdnMetricRelations);
```
### 4. CORE FEATURES & USER FLOWS
* **Authentication (NextAuth.js):**
* **Flow:** User lands on the login page -> Clicks 'Sign In' -> Presented with options (e.g., Google, GitHub, Email/Password) -> Selects provider -> Redirected to provider's auth page -> Grants permission -> Redirected back to Sovereign Host dashboard -> User session created.
* **Features:** OAuth (Google, GitHub), Email/Password with verification, Password Reset (optional for MVP).
* **Edge Case:** Invalid credentials, session expiry, provider errors.
* **Site Management (CRUD):**
* **Flow:** Authenticated user navigates to 'Sites' dashboard -> Clicks 'Add New Site' -> Enters `domainName` (e.g., `example.com`), `originUrl` (e.g., `http://your-server.com/path` or S3 bucket URL), configures `cdnEnabled` and `hostingEnabled` toggles -> Clicks 'Save' -> New site entry created in the `sites` table.
* **Update Flow:** User selects an existing site -> Edits domain, origin, or toggles features -> Clicks 'Update' -> Site record updated.
* **Delete Flow:** User selects site -> Clicks 'Delete' -> Confirms deletion -> Site record removed.
* **Edge Cases:** Duplicate domain name, invalid `originUrl` format, missing required fields.
* **DNS Configuration (Simplified):**
* **Flow:** After creating a site, the user is presented with DNS records (e.g., A record pointing to a platform IP, CNAME for origin if applicable) they need to add to their domain registrar.
* **UI:** A dedicated section within the Site Details page displaying the required DNS records and instructions.
* **Backend:** No direct DNS manipulation; provides instructions. Future versions could integrate with registrar APIs.
* **Edge Cases:** User incorrectly configures DNS, propagation delays.
* **CDN Service Activation:**
* **Flow:** User enables `cdnEnabled` toggle for a site -> Backend triggers provisioning of CDN rules (associating the `domainName` with the `originUrl` in the CDN infrastructure - simulated for MVP if actual integration is complex).
* **UI:** A toggle switch on the Site Details page. Status indicator (e.g., 'Provisioning', 'Active', 'Error').
* **Edge Cases:** Origin server unreachable, SSL certificate issues (handled by platform), CDN configuration failure.
* **Static Site Hosting:**
* **Flow:** User enables `hostingEnabled` toggle -> User uploads site files (via FTP, rsync, or a dedicated upload interface - for MVP, assume files are accessible via `originUrl` or a placeholder).
* **UI:** Upload interface or clear instructions on how to point `originUrl` to a static file source.
* **Edge Cases:** Large file uploads, incorrect file structure, build process errors (if applicable in future).
* **Dashboard & Analytics:**
* **Flow:** User logs in -> Sees an overview dashboard with key metrics (total sites, traffic summary, bandwidth usage) -> Navigates to a specific Site's details -> Views detailed analytics (requests, bandwidth, latency, cache hit ratio - mock data initially) visualized with charts.
* **UI:** Main dashboard page, Site Details page with analytics tab/section.
* **Backend:** API routes to fetch aggregated metrics from `cdnMetrics` table.
* **Edge Cases:** No data available (empty state), metric calculation errors.
### 5. API & DATA FETCHING
* **Authentication:** Handled by NextAuth.js middleware and routes (`/api/auth/[...nextauth]`).
* **Server Actions (App Router):** Use for all data mutations (CRUD operations on `sites`, `cdnMetrics`).
* `POST /api/sites`: Create new site (Server Action).
* `PUT /api/sites/[id]`: Update existing site (Server Action).
* `DELETE /api/sites/[id]`: Delete site (Server Action).
* **Route Handlers (App Router):** For data fetching (GET requests).
* `GET /api/sites`: Fetch list of user's sites.
* `GET /api/sites/[id]`: Fetch details for a specific site.
* `GET /api/sites/[id]/metrics`: Fetch performance metrics for a specific site.
* **Data Fetching in Components:** Use `fetch` within Server Components or use Server Actions directly in form submissions. For client-side fetching (e.g., in dashboard charts), use `useEffect` or a library like SWR/React Query to call the API routes.
* **Request/Response Examples:**
* **POST /api/sites:**
* Request Body: `{ "domainName": "test.com", "originUrl": "http://origin.server", "cdnEnabled": true, "hostingEnabled": false }`
* Response (Success): `201 Created`, `{ "id": "uuid", "message": "Site added successfully" }`
* Response (Error): `400 Bad Request`, `{ "error": "Invalid input" }`
* **GET /api/sites/[id]/metrics:**
* Response (Success): `200 OK`, `[{ "timestamp": "...", "bandwidthUsed": 100, "requests": 500 }, ...]`
* Response (No Data): `200 OK`, `[]`
### 6. COMPONENT BREAKDOWN (Next.js App Router)
* **`app/layout.tsx`**: Root layout (includes `<html>`, `<body>`, global styles, AuthProvider).
* **`app/page.tsx`**: Landing Page (Public).
* **`app/auth/signin/page.tsx`**: Sign In page (using NextAuth.js components).
* **`app/(app)/layout.tsx`**: Protected Layout for authenticated users (includes Navbar, Sidebar).
* **`app/(app)/dashboard/page.tsx`**: Main Dashboard. Overview metrics, recent activity. Fetches user data and site list summary.
* **`app/(app)/sites/page.tsx`**: List of all user's sites. Table view with basic info, links to details.
* **`app/(app)/sites/[id]/page.tsx`**: Site Details Page.
* Displays site configuration (domain, origin, toggles).
* Contains forms for editing site details (using Server Actions).
* Shows DNS configuration instructions.
* Includes a sub-section/tab for Analytics.
* **`app/(app)/sites/[id]/analytics.tsx`**: Analytics View for a specific site. Displays charts for bandwidth, requests, etc. (mock data initially).
* **`app/components/ui/`**: Re-usable UI components from shadcn/ui (Button, Input, Card, Table, Tabs, Alert, etc.).
* **`app/components/`**: Custom components.
* `Navbar.tsx`: Top navigation bar with user profile/logout.
* `Sidebar.tsx`: Left-hand navigation for different app sections.
* `SiteForm.tsx`: Form for adding/editing site details.
* `AnalyticsChart.tsx`: Re-usable chart component.
* `DnsInstructions.tsx`: Component displaying DNS setup steps.
* `LoadingSpinner.tsx`: Global or component-specific loading indicator.
* `EmptyState.tsx`: Component for displaying when no data is available.
### 7. UI/UX DESIGN & VISUAL IDENTITY
* **Design Style:** Modern, Clean, Professional, Trustworthy.
* **Color Palette:**
* Primary: `#4A90E2` (Trustworthy Blue)
* Secondary: `#50E3C2` (Vibrant Teal/Green for accents)
* Background: `#F7F9FC` (Light Gray)
* Dark Mode Background: `#1A202C` (Dark Gray/Near Black)
* Text: `#2D3748` (Dark Gray), `#A0AEC0` (Light Gray for secondary text)
* Accent/Alerts: `#F56565` (Red), `#ECC94B` (Yellow)
* **Typography:**
* Headings: Inter, Bold (e.g., `font-family: 'Inter', sans-serif; font-weight: 700;`)
* Body Text: Inter, Regular/Medium (e.g., `font-family: 'Inter', sans-serif; font-weight: 400;`)
* **Layout:**
* Dashboard/App Area: Sidebar on the left, main content area on the right.
* Use of `Card` components for distinct sections.
* Generous whitespace.
* Responsive design targeting mobile, tablet, and desktop breakpoints using Tailwind's `sm:`, `md:`, `lg:`, `xl:` prefixes.
* **Visual Elements:** Subtle gradients on buttons or headers, clean icons (e.g., Lucide React), clear data visualizations.
### 8. SAMPLE/MOCK DATA
* **User:**
* `id`: `uuid-user-1`
* `name`: "Alice Johnson"
* `email`: "alice.j@example.com"
* `image`: "/path/to/alice_avatar.jpg"
* **Site 1:**
* `id`: `uuid-site-1`
* `userId`: `uuid-user-1`
* `domainName`: "alicej-blog.com"
* `originUrl`: "http://my-personal-vps.com/blog"
* `cdnEnabled`: `true`
* `hostingEnabled`: `false`
* `createdAt`: "2023-10-26T10:00:00Z"
* **Site 2:**
* `id`: `uuid-site-2`
* `userId`: `uuid-user-1`
* `domainName`: "business-site.co"
* `originUrl`: "http://s3-bucket-name.s3.amazonaws.com/business-site"
* `cdnEnabled`: `true`
* `hostingEnabled`: `true`
* `createdAt`: "2023-10-27T11:30:00Z"
* **CDN Metric 1 (for Site 1):**
* `id`: `uuid-metric-1`
* `siteId`: `uuid-site-1`
* `timestamp`: "2023-10-27T12:00:00Z"
* `bandwidthUsed`: `150` (MB)
* `requests`: `750`
* **CDN Metric 2 (for Site 1):
* `id`: `uuid-metric-2`
* `siteId`: `uuid-site-1`
* `timestamp`: "2023-10-27T13:00:00Z"
* `bandwidthUsed`: `165` (MB)
* `requests`: `810`
### 9. TURKISH TRANSLATIONS
* **Sovereign Host:** Egemen Sunucu
* **Dashboard:** Kontrol Paneli
* **Sites:** Sitelerim
* **Add New Site:** Yeni Site Ekle
* **Site Name:** Site Adı
* **Origin URL:** Kaynak URL
* **CDN:** CDN
* **Hosting:** Hosting
* **Enabled:** Etkin
* **Disabled:** Devre Dışı
* **Actions:** İşlemler
* **Edit:** Düzenle
* **Delete:** Sil
* **Save Changes:** Değişiklikleri Kaydet
* **DNS Settings:** DNS Ayarları
* **Analytics:** Analitik
* **Bandwidth Usage:** Bant Genişliği Kullanımı
* **Total Requests:** Toplam İstek
* **Settings:** Ayarlar
* **Profile:** Profil
* **Logout:** Çıkış Yap
* **Sign In:** Giriş Yap
* **Email Address:** E-posta Adresi
* **Password:** Şifre
* **Remember Me:** Beni Hatırla
* **Forgot Password?:** Şifremi Unuttum?
* **This domain is already registered:** Bu alan adı zaten kayıtlı.
* **Please enter a valid URL:** Lütfen geçerli bir URL girin.
* **No sites found:** Hiç site bulunamadı.
* **Add your first site to get started:** Başlamak için ilk sitenizi ekleyin.
* **Loading...:** Yükleniyor...
* **An error occurred:** Bir hata oluştu.
### 10. ANIMATIONS
* **Page Transitions:** Subtle fade-in/fade-out transitions between pages using Next.js `app` directory features or a library like `Framer Motion` if needed.
* **Button Hovers:** Slight scale-up or background color change on button hover states (`transition-transform`, `transition-colors` with Tailwind CSS).
* **Loading States:** Use `LoadingSpinner.tsx` component with CSS animations (spin) for data fetching operations. Skeleton loaders for table rows or cards where applicable.
* **Toggle Switches:** Smooth transition animation for `cdnEnabled` and `hostingEnabled` toggles.
* **Chart Interactions:** Tooltips and hover effects on chart data points.
### 11. EDGE CASES & VALIDATION
* **Authentication:** Handle expired sessions, unauthorized access attempts gracefully (redirect to login, show alert).
* **Empty States:** Design specific UI states for when lists are empty (e.g., no sites created, no analytics data available) with clear calls to action.
* **Form Validation:** Implement real-time validation using Zod and React Hook Form for all user inputs (domain names, URLs, etc.) on both client and server sides.
* **Error Handling:** Catch API errors, display user-friendly messages using `Alert` components. Log errors to a monitoring service.
* **Data Fetching:** Handle network errors, server errors, and scenarios where data might be temporarily unavailable. Implement retry mechanisms where appropriate (e.g., using SWR).
* **Configuration Errors:** Provide clear feedback if a site's configuration is invalid or if DNS settings are incorrect/not propagated.
* **Resource Limits:** (Future consideration) Implement checks for bandwidth/storage limits based on subscription tiers.