## AI Master Prompt for GoldGuard MVP Development
**1. PROJECT OVERVIEW:**
GoldGuard is a cutting-edge SaaS platform designed to enhance the security, transparency, and management of global financial institutions' cross-border assets, particularly gold reserves. It addresses the critical need for real-time tracking of asset location and status, enabling proactive identification and mitigation of geopolitical, operational, and compliance risks. The core value proposition is to provide financial institutions (central banks, large commercial banks, international financial organizations) with a single, reliable source of truth for their distributed asset holdings, ensuring peace of mind and operational efficiency.
The problem stems from the historical practice of holding significant assets in foreign jurisdictions (like France holding gold in the US Federal Reserve), creating complex logistical, security, and geopolitical challenges. Events like the repatriation of French gold highlight the need for robust oversight and control over these assets. GoldGuard aims to digitize and centralize this oversight, transforming a complex, often opaque process into a transparent, manageable digital workflow.
**2. TECH STACK:**
- **Frontend:** React (Next.js 14+ with App Router)
- **Styling:** Tailwind CSS 3+
- **State Management:** Zustand or React Context API for global state, component-level state as needed.
- **ORM:** Drizzle ORM with PostgreSQL (or a compatible SQL database like Supabase/Neon)
- **Authentication:** NextAuth.js (v5+) for robust authentication (OAuth, Credentials)
- **UI Components:** shadcn/ui for pre-built, accessible, and customizable components.
- **Data Fetching:** Server Actions and Route Handlers for API endpoints, React Query or SWR for client-side data fetching and caching (if not fully managed by Server Actions).
- **Form Handling:** React Hook Form with Zod for validation.
- **Charting:** Chart.js or Recharts for data visualization.
- **Deployment:** Vercel or a similar platform.
**3. DATABASE SCHEMA (PostgreSQL via Drizzle ORM):**
```sql
-- Users table for authentication and authorization
create table users (
id text primary key,
name text,
email text unique not null,
email_verified timestamp with time zone,
image text,
created_at timestamp with time zone default now(),
updated_at timestamp with time zone default now()
);
-- Accounts table for NextAuth.js integration
create table accounts (
id text primary key,
user_id text not null references users(id) on delete cascade,
type text not null, -- 'oauth' or 'credentials'
provider text not null,
provider_account_id text not null,
refresh_token text,
access_token text,
expires_at timestamp with time zone,
token_type text,
scope text,
id_token text,
session_state text,
unique (provider, provider_account_id)
);
-- Sessions table for NextAuth.js integration
create table sessions (
id text primary key,
user_id text not null references users(id) on delete cascade,
expires timestamp with time zone not null,
session_token text unique not null
);
-- Verification Tokens table for NextAuth.js integration
create table verification_tokens (
identifier text not null,
token text not null,
expires timestamp with time zone not null,
primary key (identifier, token)
);
-- User profile/settings (optional, can extend users table)
create table user_profiles (
user_id text primary key references users(id) on delete cascade,
institution_name text,
role text -- e.g., 'Admin', 'Auditor', 'Viewer'
);
-- Core Asset Entity
create table assets (
id uuid primary key default gen_random_uuid(),
user_id text not null references users(id) on delete cascade,
name text not null, -- e.g., 'French Gold Reserve', 'German Silver Hoard'
description text,
asset_type text not null, -- 'Gold', 'Silver', 'Platinum', 'Other'
quantity numeric(20, 4) not null,
unit text not null, -- 'kg', 'troy oz', 'tonnes'
created_at timestamp with time zone default now(),
updated_at timestamp with time zone default now()
);
-- Storage Locations for Assets
create table storage_locations (
id uuid primary key default gen_random_uuid(),
asset_id uuid not null references assets(id) on delete cascade,
country text not null, -- e.g., 'USA', 'France', 'Switzerland'
institution_name text not null, -- e.g., 'Federal Reserve Bank of New York', 'ECB Frankfurt Vault'
vault_identifier text, -- e.g., 'Vault A-12', 'Level 3, Section B'
address text,
is_custodian_fed_or_central_bank boolean default false,
created_at timestamp with time zone default now(),
updated_at timestamp with time zone default now()
);
-- Asset Status and Audit Trail
create table asset_status_history (
id uuid primary key default gen_random_uuid(),
storage_location_id uuid not null references storage_locations(id) on delete cascade,
recorded_at timestamp with time zone default now(),
quantity numeric(20, 4) not null,
unit text not null, -- Must match asset unit
is_standard_compliant boolean, -- True, False, or Null if unknown
notes text, -- e.g., 'Replaced older bars', 'Audit check passed', 'Potential contamination'
audited_by text, -- User ID or system identifier
created_at timestamp with time zone default now()
);
-- Geopolitical Risk Indicators (Simplified)
create table geopolitical_risks (
id uuid primary key default gen_random_uuid(),
country text not null unique,
risk_level text not null, -- 'Low', 'Medium', 'High', 'Critical'
description text,
last_updated timestamp with time zone default now(),
created_at timestamp with time zone default now()
);
-- Alerts configuration
create table alerts (
id uuid primary key default gen_random_uuid(),
user_id text not null references users(id) on delete cascade,
asset_id uuid references assets(id) on delete set null,
storage_location_id uuid references storage_locations(id) on delete set null,
risk_country text references geopolitical_risks(country) on delete set null,
alert_type text not null, -- 'Standard Compliance', 'Geopolitical', 'Location Change', 'Low Quantity'
threshold_value numeric(20, 4),
is_active boolean default true,
created_at timestamp with time zone default now(),
updated_at timestamp with time zone default now()
);
-- Notifications table
create table notifications (
id uuid primary key default gen_random_uuid(),
user_id text not null references users(id) on delete cascade,
alert_id uuid references alerts(id) on delete set null,
message text not null,
severity text not null, -- 'Info', 'Warning', 'Critical'
is_read boolean default false,
created_at timestamp with time zone default now()
);
```
**4. CORE FEATURES & USER FLOW:**
* **Authentication Flow:**
* User lands on the `/` (public) page. Option to "Sign In" or "Sign Up".
* Clicking "Sign Up" directs to `/auth/signup` page with fields for Name, Email, Password, Confirm Password. Includes Terms of Service and Privacy Policy checkboxes.
* Clicking "Sign In" directs to `/auth/signin` page with Email and Password fields. "Forgot Password?" link redirects to `/auth/forgot-password`.
* Upon successful signup/signin, user is redirected to the `/dashboard` page. NextAuth.js handles session management.
* **Edge Case:** Password mismatch during signup, invalid email format, existing email, incorrect credentials during signin, expired session.
* **Dashboard (Protected Route - `/dashboard`):**
* **User Flow:** User logs in -> redirected to Dashboard.
* **Functionality:** Displays a high-level overview of assets. Includes a summary widget showing Total Assets Value (if applicable/estimable), Total Quantity, and Number of Storage Locations. A prominent section shows recent notifications/alerts. Quick links to "Add Asset" and "View All Assets". Includes a map visualization (simple) showing asset distribution by country.
* **State:** Fetches user session data and aggregated asset data. Loads recent notifications.
* **Components:** `DashboardStatsGrid`, `RecentAlertsList`, `AssetDistributionMap`.
* **Add New Asset (Protected Route - `/assets/new`):**
* **User Flow:** User on Dashboard clicks "Add Asset" -> navigated to `/assets/new`.
* **Functionality:** A multi-step form (or single complex form) using `react-hook-form` and `zod` for validation.
1. **Asset Details:** Asset Name, Description, Type (dropdown: Gold, Silver, etc.), Quantity, Unit (dropdown: kg, tonnes, oz).
2. **Storage Location(s):** Add one or more storage locations. Fields: Country (dropdown/autocomplete), Institution Name, Vault Identifier, Address. Checkbox: "Is Custodian Fed/Central Bank?".
3. **Initial Status:** Record initial status for each location. Fields: Recorded At (defaults to now), Quantity (pre-filled), Unit (pre-filled), Is Standard Compliant (True/False/Unknown - radio buttons/dropdown), Notes (optional).
* **API Interaction:** Uses Server Actions to create `assets`, `storage_locations`, and `asset_status_history` records in a single transaction. Handles validation errors.
* **Edge Cases:** Incomplete form data, network errors during submission, invalid quantity/unit combinations.
* **View/Manage Assets (Protected Route - `/assets`):**
* **User Flow:** User on Dashboard clicks "View All Assets" or navigates via sidebar -> sees a table of all registered assets.
* **Functionality:** Displays assets in a paginated, sortable, and filterable table (`shadcn/ui DataTable`). Columns: Asset Name, Type, Total Quantity, Number of Locations, Last Updated. Each row has actions: "View Details", "Edit", "Delete".
* **Details View (Modal or New Page - `/assets/[id]`):** Clicking "View Details" opens a modal or navigates to a detail page. Shows all asset information, a list of its storage locations (each with its status history), and relevant geopolitical risk data for the location countries.
* **Edit Asset:** Allows modification of asset name, description, and adding/removing/editing storage locations and their status history.
* **Delete Asset:** Confirmation modal before deletion. Cascades deletes related `storage_locations` and `asset_status_history` entries.
* **API Interaction:** Fetch assets using Server Actions or Route Handlers. Server Actions handle edit/delete operations.
* **Alerts & Notifications (Protected Route - `/alerts`):**
* **User Flow:** System automatically generates alerts based on defined rules. User navigates to `/alerts` to view notifications.
* **Functionality:** Displays a list of generated notifications, filterable by status (read/unread), severity, and type. Each notification links to the relevant asset or location. A separate section (`/alerts/rules`) allows users to configure custom alerts (e.g., "Alert me if Gold in USA falls below X tonnes", "Alert me for any non-compliance in Swiss vaults").
* **Backend Logic:** A scheduled job (or triggered events) will periodically check `asset_status_history` and `geopolitical_risks` against active `alerts` rules to generate `notifications`.
* **API Interaction:** Fetch notifications, mark as read. Create/update/delete alert rules.
**5. API & DATA FETCHING:**
- **API Structure:** Utilize Next.js App Router's Route Handlers (`app/api/.../route.ts`) for RESTful endpoints and Server Actions (`'use server'`) for mutations and direct data fetching within components.
- **Authentication:** All relevant API routes and Server Actions will be protected, requiring user authentication via NextAuth.js middleware.
- **Data Fetching:** Server Actions will be the primary method for fetching data needed for server-rendered pages and components. Client components can use Route Handlers via `fetch` or libraries like `react-query` for interactive data needs (e.g., real-time updates, form state).
- **Example API (Route Handler for fetching assets):**
```typescript
// app/api/assets/route.ts
import { db } from '@/lib/drizzle'; // Your Drizzle connection
import { assets, users } from '@/lib/schema'; // Your Drizzle schema
import { auth } from '@/auth'; // NextAuth.js auth utility
import { eq } from 'drizzle-orm';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
try {
const userAssets = await db.query.assets.findMany({
where: eq(assets.user_id, session.user.id),
with: {
storageLocations: {
columns: { id: true, country: true, institution_name: true },
limit: 1 // Just show count or primary location
}
}
});
return NextResponse.json(userAssets);
} catch (error) {
console.error('Failed to fetch assets:', error);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}
}
```
- **Example Server Action (for creating an asset):**
```typescript
// app/actions.ts
'use server';
import { db } from '@/lib/drizzle';
import { assets, storage_locations, asset_status_history } from '@/lib/schema';
import { auth } from '@/auth';
import { createInsertSchema } from 'drizzle-zod';
import { z } from 'zod';
import { nanoid } from 'nanoid'; // For generating IDs if not using UUIDs directly in schema
import { pgTable, uuid, text, timestamp, numeric, boolean, pgEnum } from 'drizzle-orm/pg-core';
import { eq } from 'drizzle-orm';
import { Transaction, TransactionBegin } from '@neondatabase/serverless';
// Define Zod schemas for validation (simplified)
const assetSchema = createInsertSchema(assets);
const locationSchema = createInsertSchema(storage_locations);
const statusSchema = createInsertSchema(asset_status_history);
const NewAssetFormSchema = z.object({
asset: assetSchema.pick({ name: true, description: true, asset_type: true, quantity: true, unit: true }),
locations: z.array(locationSchema.pick({ country: true, institution_name: true, vault_identifier: true, address: true, is_custodian_fed_or_central_bank: true }))
});
export async function createAssetWithLocations(formData: FormData) {
const session = await auth();
if (!session?.user?.id) {
throw new Error('Unauthorized');
}
const rawData = Object.fromEntries(formData.entries());
// Need to parse locations correctly, likely requires custom parsing if sent as JSON string
const result = NewAssetFormSchema.safeParse(rawData); // Adjust parsing based on how form data is structured
if (!result.success) {
return { error: 'Validation failed', issues: result.error.flatten().fieldErrors };
}
const { asset, locations } = result.data;
const assetId = nanoid(); // Or use UUID if schema supports it directly
try {
// Use transaction to ensure atomicity
await db.transaction(async (tx: TransactionBegin) => {
await tx.insert(assets).values({ ...asset, id: assetId, user_id: session.user.id });
for (const loc of locations) {
const locationId = nanoid();
await tx.insert(storage_locations).values({ ...loc, id: locationId, asset_id: assetId });
// Create initial status entry for the location
await tx.insert(asset_status_history).values({
storage_location_id: locationId,
recorded_at: new Date(),
quantity: asset.quantity,
unit: asset.unit,
is_standard_compliant: null, // Default to unknown
notes: 'Initial registration',
audited_by: session.user.id
});
}
});
// Revalidate cache or redirect
// revalidatePath('/dashboard'); // Example
return { success: 'Asset created successfully' };
} catch (error) {
console.error('Failed to create asset:', error);
// Consider more specific error handling
return { error: 'Failed to create asset. Please try again.' };
}
}
```
**6. COMPONENT BREAKDOWN (Next.js App Router):**
- **`app/layout.tsx`**: Root layout with `<html>`, `<body>`, Tailwind CSS setup, theme provider, font loading.
- **`app/page.tsx`**: Landing Page. Includes hero section, feature highlights, call to action (Sign Up/Sign In).
- **`app/dashboard/layout.tsx`**: Protected layout with Sidebar Navigation. Wraps dashboard pages.
- **`app/dashboard/page.tsx`**: Main Dashboard. Displays overview widgets, recent alerts, map.
- **Components:** `DashboardStatsGrid`, `RecentAlertsList`, `AssetDistributionMap`, `Navbar`, `Sidebar`.
- **`app/(auth)/layout.tsx`**: Layout for Auth pages (Sign In, Sign Up, Forgot Password). Minimal design.
- **`app/(auth)/signin/page.tsx`**: Sign In form component.
- **`app/(auth)/signup/page.tsx`**: Sign Up form component.
- **`app/assets/page.tsx`**: Assets List page. Uses `DataTable` component.
- **Components:** `DataTable` (from shadcn/ui, configured for assets), `AssetTableActions` (Edit, Delete buttons).
- **`app/assets/new/page.tsx`**: Add New Asset form page.
- **Components:** `MultiStepAssetForm` or `SingleAssetForm` (using `react-hook-form`), `LocationInputGroup`.
- **`app/assets/[id]/page.tsx`**: Asset Details page. Shows asset info, locations, status history.
- **Components:** `AssetDetailCard`, `LocationList`, `StatusHistoryTable`.
- **`app/alerts/page.tsx`**: Notifications page. List view.
- **Components:** `NotificationList`, `NotificationItem`.
- **`app/alerts/rules/page.tsx`**: Alert Rules configuration page.
- **Components:** `AlertRuleForm`, `AlertRuleList`.
- **`app/settings/page.tsx`**: User Profile and Settings (e.g., change password, update institution).
- **Components:** `ProfileForm`, `SecuritySettings`.
- **`components/ui/`**: All shadcn/ui components, customized or used as-is.
- **`components/common/`**: Reusable components like `Navbar`, `Sidebar`, `Footer`, `Button`, `Card`, `AlertDialog`.
- **`lib/`**: Utility functions, API clients, Drizzle setup, schema definitions, auth configuration.
**7. UI/UX DESIGN & VISUAL IDENTITY:**
* **Design Style:** Modern, Clean, Professional, Trustworthy.
* **Color Palette:**
* Primary (Brand): Deep Blue (`#0A2540`)
* Secondary (Accents): Teal (`#30A0C0`)
* Background: Light Gray/Off-White (`#F8F9FA`)
* Card/Element Background: White (`#FFFFFF`)
* Text (Primary): Dark Gray (`#212529`)
* Text (Secondary): Medium Gray (`#6C757D`)
* Success/Positive: Green (`#198754`)
* Warning/Alert: Orange/Yellow (`#FD7E14`)
* Error/Critical: Red (`#DC3545`)
* **Typography:** Sans-serif. Use a modern font like Inter or Poppins. Clear hierarchy (H1, H2, H3, body, captions).
* **Layout:** Sidebar navigation on the left for authenticated users. Main content area occupies the rest of the screen. Generous spacing and padding. Clear visual separation between sections using cards and subtle borders.
* **Responsiveness:** Mobile-first approach. Sidebar collapses into a hamburger menu on smaller screens. Content reflows and scales appropriately. Ensure tables are usable on mobile (e.g., horizontal scroll or card-based display).
* **Visual Elements:** Subtle use of icons (e.g., Feather Icons, Lucide Icons). Data visualizations (charts, maps) should be clean and easy to understand.
**8. SAMPLE/MOCK DATA:**
* **User:**
* `id`: "clv3x1a6m0000xxxxxx"
* `name`: "François Villeroy"
* `email`: "francois.v@example-centralbank.fr"
* `role`: "Admin"
* `institution_name`: "Banque de France"
* **Asset 1 (Gold):**
* `id`: "uuid-gold-1234"
* `user_id`: "clv3x1a6m0000xxxxxx"
* `name`: "Banque de France - US Gold Repatriation"
* `asset_type`: "Gold"
* `quantity`: 129
* `unit`: "tonnes"
* **Storage Location 1 (for Gold):**
* `id`: "uuid-loc-usa-fed"
* `asset_id`: "uuid-gold-1234"
* `country`: "USA"
* `institution_name`: "Federal Reserve Bank of New York"
* `vault_identifier`: "Vault 7-B, Sub-level 3"
* `is_custodian_fed_or_central_bank`: true
* **Asset Status History 1 (for Gold in USA):**
* `id`: "uuid-status-1"
* `storage_location_id`: "uuid-loc-usa-fed"
* `recorded_at`: "2026-01-15T10:00:00Z"
* `quantity`: 129
* `unit`: "tonnes"
* `is_standard_compliant`: true
* `notes`: "Final batch of previously held gold, replaced with new bars meeting modern standards."
* `audited_by`: "system"
* **Geopolitical Risk:**
* `country`: "USA"
* `risk_level`: "Low"
* `description`: "Stable political climate, strong financial infrastructure."
* **Alert Rule:**
* `id`: "uuid-alert-rule-1"
* `user_id`: "clv3x1a6m0000xxxxxx"
* `asset_id`: "uuid-gold-1234"
* `alert_type`: "Standard Compliance"
* `is_active`: true
* **Notification:**
* `id`: "uuid-notif-1"
* `user_id`: "clv3x1a6m0000xxxxxx"
* `alert_id`: "uuid-alert-rule-1"
* `message`: "Alert: Gold held at Federal Reserve Bank of New York flagged as non-compliant."
* `severity`: "Critical"
* `is_read`: false
**9. TURKISH TRANSLATIONS (for key UI elements):**
* Sign In: `Giriş Yap`
* Sign Up: `Kayıt Ol`
* Password: `Şifre`
* Email: `E-posta`
* Name: `Ad`
* Dashboard: `Kontrol Paneli`
* Assets: `Varlıklar`
* Add Asset: `Varlık Ekle`
* New Asset: `Yeni Varlık`
* Asset Name: `Varlık Adı`
* Asset Type: `Varlık Türü`
* Quantity: `Miktar`
* Unit: `Birim`
* Storage Location: `Saklama Yeri`
* Country: `Ülke`
* Institution Name: `Kurum Adı`
* Vault Identifier: `Kasa Tanımlayıcı`
* Status History: `Durum Geçmişi`
* Recorded At: `Kaydedildiği Tarih`
* Is Standard Compliant: `Standartlara Uygun Mu?`
* Unknown: `Bilinmiyor`
* Alerts: `Uyarılar`
* Notifications: `Bildirimler`
* Alert Rules: `Uyarı Kuralları`
* Create Rule: `Kural Oluştur`
* Edit: `Düzenle`
* Delete: `Sil`
* Save: `Kaydet`
* Cancel: `İptal`
* Are you sure?: `Emin misiniz?`
* Last Updated: `Son Güncelleme`
* Total Assets: `Toplam Varlık`
* Active Locations: `Aktif Lokasyonlar`
* Recent Activity: `Son Aktiviteler`
* Settings: `Ayarlar`
* Profile: `Profil`
* Logout: `Çıkış Yap`
**10. ANIMATIONS:**
* **Page Transitions:** Subtle fade or slide transitions between pages using Next.js `useTransition` or a library like `Framer Motion`.
* **Button Hover Effects:** Slight scale-up or background color change on hover.
* **Loading States:** Use skeleton loaders or spinners (e.g., from `lucide-react`) for data fetching, especially in tables and dashboard widgets. Fade in data once loaded.
* **Hover Effects on Table Rows:** Subtle background highlight when hovering over a table row.
* **Form Feedback:** Animate success/error messages appearing and disappearing.
**11. EDGE CASES:**
* **Empty States:** All lists (Assets, Notifications, Locations) should display user-friendly empty state messages with a clear call to action (e.g., "No assets added yet. Click here to add your first asset.").
* **Authentication:** Implement robust session management with NextAuth.js. Handle token expiry, silent refresh, and redirects on unauthorized access.
* **Authorization:** Implement role-based access control (RBAC) based on the `role` field in `user_profiles`. Ensure users can only access and modify data according to their assigned role (e.g., Viewers cannot edit assets).
* **Error Handling:** Global error handler for uncatched exceptions. Specific error handling for API requests (displaying user-friendly messages). Use `try...catch` blocks extensively in Server Actions and Route Handlers.
* **Validation:** Implement server-side and client-side validation using Zod and React Hook Form for all user inputs. Provide clear feedback on validation errors.
* **Data Integrity:** Use database transactions for operations involving multiple tables (e.g., creating an asset and its initial locations).
* **Network Failures:** Gracefully handle network interruptions during data submission or fetching, providing feedback to the user and allowing retry mechanisms.