# System Architecture: Vibery Kits Website

## High-Level Architecture

```
┌─────────────────────────────────────────────────────────┐
│ User Browser                                            │
│ ┌───────────────────────────────────────────────────┐   │
│ │ HTML (Static)                                     │   │
│ │ ├─ Header, Hero, TemplatesGrid (static content)  │   │
│ │ └─ Vue Islands (hydrated on demand)              │   │
│ │    ├─ SearchBar (client:load)                    │   │
│ │    ├─ FilterBar (client:load)                    │   │
│ │    ├─ CartSidebar (client:load)                  │   │
│ │    └─ TemplateModal (client:load)                │   │
│ │                                                  │   │
│ │ Shared State (Composables)                       │   │
│ │ ├─ useCart (localStorage sync)                   │   │
│ │ ├─ useModal (modal state)                        │   │
│ │ ├─ useSearch (filter logic)                      │   │
│ │ ├─ useNotifications (toast queue)                │   │
│ │ └─ useUsageStats (analytics)                     │   │
│ └───────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
                      ↓ (fetch HTML + JS)
┌─────────────────────────────────────────────────────────┐
│ Cloudflare CDN (Edge)                                   │
│ ├─ Static HTML pages (dist/*.html)                      │
│ ├─ CSS (auto-prefixed, minified)                        │
│ ├─ JS bundles (Vue + composables, minified)             │
│ ├─ Images (optimized, cached)                           │
│ └─ Security headers (CSP, X-Frame-Options, etc.)        │
└─────────────────────────────────────────────────────────┘
                      ↓ (origin fallback)
┌─────────────────────────────────────────────────────────┐
│ Build Process (GitHub → Cloudflare Pages)              │
│ ├─ Astro build (astro build)                            │
│ │  ├─ Parse .astro + .vue files                        │
│ │  ├─ Build routes (SSG)                               │
│ │  ├─ Minify CSS (Tailwind)                            │
│ │  └─ Generate dist/                                   │
│ ├─ Deploy to Cloudflare Pages                          │
│ └─ Cache invalidation + CDN refresh                    │
└─────────────────────────────────────────────────────────┘
```

## Data Flow Architecture

### 1. Build Time (Static Generation)

```
src/data/
├─ templates.json (600+ items)
├─ stacks.json (12 curated)
├─ outcomes.json (8 flows)
└─ claudekit.json (premium)
      ↓ (import during build)
src/pages/
├─ index.astro (home, featured)
├─ agents.astro → filtered templates
├─ stacks.astro → all stacks
├─ stacks/[id].astro → dynamic SSG
└─ claudekit.astro → premium page
      ↓ (pre-render to HTML)
dist/
├─ index.html
├─ agents/index.html
├─ stacks/index.html
├─ stacks/nextjs-production/index.html (SSG)
└─ ... (all routes pre-rendered)
```

### 2. Runtime (Client-Side Hydration)

```
Browser loads dist/index.html
      ↓
Parse HTML (static)
      ↓
Mount Vue components (islands)
├─ SearchBar.vue (client:load)
│  └─ Loaded templates.json via prop or import
│     └─ useSearch() composable
│        └─ Filter templates in real-time
├─ CartSidebar.vue
│  └─ useCart() composable
│     └─ Subscribe to cart state
│        └─ Read/write localStorage
├─ TemplateModal.vue
│  └─ useModal() composable
│     └─ Handle modal visibility
│        └─ Display selected template
└─ NotificationToast.vue
   └─ useNotifications() composable
      └─ Queue and display toasts
```

### 3. State Management Flow

```
Vue Island (e.g., SearchBar)
      ↓
Composable (useSearch)
      │
      ├─ Read: templates.json
      ├─ Write: query.value
      └─ Compute: filteredResults
           ↓
      Another Island (TemplateCard) receives data via prop
      ├─ Display: template info
      └─ Event: @click add-to-cart
           ↓
      CartSidebar Island
      └─ useCart().addItem()
           ├─ Update: items.value
           └─ Sync: localStorage
```

## Component Architecture

### Astro Components (Static HTML)

**Purpose:** Pre-rendered HTML, no client-side logic

```
Header.astro (navigation)
├─ Logo + nav links
├─ Cart button (shows count from useCart)
└─ Mobile menu toggle

Hero.astro (home)
├─ Search prompt
├─ Featured stacks
└─ CTA button

TemplateCard.astro (reusable)
├─ Icon + name
├─ Description
├─ Tags
├─ Type badge
└─ Add button (event handler in Vue)

TemplatesGrid.astro (container)
├─ Map templates to TemplateCard
└─ Pagination (if needed)

StacksGrid.astro (smart stacks)
├─ Grid of stacks
├─ Metadata (description, count, tags)
└─ Install button

Footer.astro (static)
├─ Links
└─ Copyright
```

### Vue Components (Reactive Islands)

**Purpose:** Interactive features with state management

```
AppWrapper.vue (root orchestrator)
├─ Loads data (templates.json)
├─ Provides composables
└─ Renders children

SearchBar.vue
├─ Input field (v-model query)
├─ useSearch() composable
├─ Real-time filtering
└─ Results dropdown (or modal trigger)

FilterBar.vue
├─ Type filter pills
├─ Sort dropdown
├─ useSearch() composable
└─ Trigger re-render

CartSidebar.vue
├─ Item list (useCart)
├─ Count badge
├─ Generate install command
├─ Copy to clipboard
└─ Persist to localStorage

TemplateModal.vue
├─ useModal() composable
├─ Full template details
├─ Add to cart action
├─ External links
├─ Keyboard navigation (Esc)
└─ Close button

NotificationToast.vue
├─ useNotifications() composable
├─ Toast queue (FIFO)
├─ Auto-dismiss (5s)
└─ Animation transitions
```

## Composable Architecture

### State Management Composables

```
useCart.ts
├─ State: items (ref<CartItem[]>)
├─ Persistence: localStorage (vibery-cart)
├─ Functions:
│  ├─ addItem(item)
│  ├─ removeItem(name)
│  ├─ hasItem(name)
│  ├─ generateCommand()
│  └─ clear()
└─ Watchers: items → sync to localStorage

useModal.ts
├─ State: isOpen, currentTemplate
├─ Functions:
│  ├─ open(template)
│  ├─ close()
│  └─ next() / prev()
└─ Watchers: route change → close modal

useSearch.ts
├─ State: query, filters, results
├─ Functions:
│  ├─ search(query)
│  ├─ filter(type, tags)
│  └─ sort(by)
└─ Computed: filtered & sorted templates

useNotifications.ts
├─ State: queue (ref<Toast[]>)
├─ Functions:
│  ├─ add(message, type, duration)
│  └─ remove(id)
└─ Watchers: queue → auto-dismiss

useUsageStats.ts
├─ State: analytics data
├─ Functions:
│  ├─ trackView(page)
│  ├─ trackClick(templateId)
│  └─ trackInstall(templateId)
└─ Persistence: localStorage
```

## Data Schema

### Template Object

```typescript
interface Template {
  id: string; // unique-id
  name: string; // "Prompt Engineer"
  type: "agent" | "command" | "mcp" | "setting" | "hook" | "skill";
  description: string; // Short description
  icon: string; // "ph-book" (Phosphor)
  category: string; // "productivity", "security"
  tags: string[]; // ["prompting", "ai"]
  installs: number; // Download count
  updated: string; // "2024-12-21" (ISO date)
  source?: string; // GitHub/docs URL
  author?: string; // Creator name
}
```

### Stack Object

```typescript
interface Stack {
  id: string; // "nextjs-production"
  name: string; // "Next.js Production Stack"
  description: string; // Detailed description
  icon: string; // "ph-lightning"
  category: string; // "frontend", "backend"
  templates: StackTemplate[]; // Array of templates in stack
  tags: string[]; // ["nextjs", "react", "production"]
  credits?: string; // Attribution/source
}

interface StackTemplate {
  type: TemplateType;
  name: string; // Template name to search
}
```

### Outcome Object

```typescript
interface Outcome {
  id: string; // "build-saas"
  question: string; // "Building a SaaS application?"
  description: string; // Explanation
  followUp: OutcomeStep; // Next step
}

interface OutcomeStep {
  question: string; // "What's your primary stack?"
  options: OutcomeOption[]; // Multiple answers
}

interface OutcomeOption {
  id: string; // "nextjs"
  label: string; // "Next.js"
  templates: string[]; // ["nextjs-architecture-expert"]
  nextStep?: OutcomeStep; // Further branching
}
```

## Build Pipeline

### Build Steps

```
1. npm run build
   ├─ Parse astro.config.mjs
   ├─ Discover routes (src/pages/)
   └─ Create build queue

2. For each route:
   ├─ Render Astro component
   ├─ Import JSON data
   ├─ Generate HTML
   └─ Extract Vue islands (mark client:load)

3. CSS Processing:
   ├─ Tailwind CSS scan
   ├─ Identify used classes
   ├─ Generate optimized CSS
   └─ Minify + prefix

4. JS Processing:
   ├─ Bundle Vue components
   ├─ Bundle composables
   ├─ Tree-shake unused code
   └─ Minify

5. Output:
   ├─ dist/index.html
   ├─ dist/assets/style-HASH.css
   ├─ dist/assets/index-HASH.js
   └─ dist/_astro/*.html (SSG routes)

6. Deploy to Cloudflare Pages:
   ├─ Upload dist/
   ├─ Set cache headers
   └─ Enable security features
```

### Build Times

| Step                | Duration   | Notes                   |
| ------------------- | ---------- | ----------------------- |
| Parse config        | <100ms     | Once per build          |
| Render routes       | ~1-2s      | 12 routes, parallelized |
| Process CSS         | ~500ms     | Tailwind scan + minify  |
| Process JS          | ~1-2s      | Vue + composables       |
| Generate SSG stacks | ~200ms     | 12 SSG pages            |
| Upload to CDN       | ~2-5s      | Cloudflare Pages        |
| **Total**           | **~5-10s** | Fast cold builds        |

## Deployment Architecture

### Cloudflare Pages Setup

```
GitHub Repository
├─ Push to main branch
      ↓
Cloudflare Pages Build
├─ Install dependencies (npm ci)
├─ Build (npm run build)
│  └─ Generates dist/
├─ Deploy dist/ to edge
└─ Assign to vibery.app

Cloudflare Edge Network
├─ Caches dist/ files globally
├─ CDN: 200+ edge locations
├─ Zero cold-start (pre-cached)
├─ Automatic HTTPS + TLS
└─ DDoS protection included
```

### Cache Strategy

| Asset      | Cache Duration | Strategy                    |
| ---------- | -------------- | --------------------------- |
| HTML pages | 1 hour         | Cache-control: max-age=3600 |
| CSS files  | 30 days        | Immutable (content hash)    |
| JS files   | 30 days        | Immutable (content hash)    |
| JSON data  | 1 hour         | Cache-control: max-age=3600 |
| Images     | 30 days        | Immutable                   |

## Known Architectural Issues

### Issue 1: Legacy ClientScripts.astro

**Problem:** 451-line file with old JavaScript logic

**Current State:**

- Contains CartManager logic (duplicates useCart)
- Event listeners for add-to-cart (redundant)
- Old neon-\* class references

**Solution:** Delete and migrate logic to Vue composables

**Status:** Pending (Phase 2)

### Issue 2: Dual Component Implementations

**Problem:** Components exist in both Astro + Vue versions

**Examples:**

- Modal.astro (deprecated) + TemplateModal.vue (active)
- Cart.astro (deprecated) + CartSidebar.vue (active)
- FilterBar.astro (deprecated) + FilterBar.vue (active)

**Solution:** Complete Vue Islands migration, delete Astro versions

**Status:** Pending (Phase 2)

### Issue 3: Neon Class References

**Problem:** Some components still reference old `neon-*` Tailwind classes

**Locations:**

- TemplatesGrid.astro (minor refs)
- ClientScripts.astro (in JS strings)

**Solution:** Replace with `warm-*` classes from design system

**Status:** Pending (Phase 2)

## Performance Considerations

### Metrics & Targets

| Metric                         | Target | Method                  |
| ------------------------------ | ------ | ----------------------- |
| FCP (First Contentful Paint)   | <1s    | Static HTML (no JS)     |
| LCP (Largest Contentful Paint) | <1.5s  | CDN + Tailwind CSS      |
| CLS (Cumulative Layout Shift)  | <0.1   | Fixed layouts, no jumps |
| TTI (Time to Interactive)      | <3s    | Vue island hydration    |
| Lighthouse                     | >90    | Astro + optimization    |

### Optimization Strategies

1. **Static Generation** - Pre-render all pages at build time
2. **Vue Islands** - Only hydrate interactive parts
3. **CSS-in-JS** - Tailwind purges unused classes
4. **Image Optimization** - SVG icons (Phosphor), no large images
5. **Code Splitting** - Lazy-load modals on demand
6. **Caching** - CDN + browser cache headers

## Security Architecture

### Content Security Policy (CSP)

```
default-src 'self'
script-src 'self' cdn.jsdelivr.net
style-src 'self' 'unsafe-inline' fonts.googleapis.com
font-src 'self' fonts.gstatic.com
img-src 'self' data:
connect-src 'self' https:
frame-ancestors 'none'
base-uri 'self'
form-action 'self'
```

### Security Headers

```
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
```

### Input Validation

- Vue templates auto-escape
- No `dangerouslySetInnerHTML`
- Search input sanitized
- localStorage validated

## Monitoring & Analytics

### Client-Side Analytics

**Composable:** `useUsageStats()`

```typescript
trackView(page); // Page view
trackClick(templateId); // Template click
trackInstall(templateId); // Install command
```

**Storage:** localStorage (vibery-analytics)

**Future:** Integrate with Cloudflare Analytics / Sentry

## Future Architecture Improvements

### Phase 2: Vue Islands Complete

- Remove ClientScripts.astro
- Delete Astro duplicates
- Fix neon-\* class refs

### Phase 3: Server-Side Features

- Cloudflare Workers for dynamic routes
- User authentication (Clerk)
- Premium feature unlocking

### Phase 4: Database Integration

- Supabase for user stacks
- Template ratings/reviews
- Analytics pipeline

### Phase 5: Advanced Features

- Real-time collab (WebSocket)
- AI-powered recommendations
- Integration with Claude Code directly
