frontend-connect

📁 chloezhu010/vibe-ship 📅 7 days ago
2
总安装量
2
周安装量
#64264
全站排名
安装命令
npx skills add https://github.com/chloezhu010/vibe-ship --skill frontend-connect

Agent 安装分布

amp 2
gemini-cli 2
github-copilot 2
codex 2
kimi-cli 2
cursor 2

Skill 文档

Frontend Connect

Wire the AI-generated frontend to the live Supabase backend — replacing mock data and localStorage with real queries.

This skill is called by the vibe-ship orchestrator. FRAMEWORK = nextjs or vite.

1. Apply framework best practices

If FRAMEWORK = nextjs: Invoke next-best-practices If FRAMEWORK = vite: Invoke vercel-react-best-practices

2. Audit the codebase for mock data patterns

Scan for:

  • Hardcoded arrays of objects (e.g. const users = [{ id: 1, name: '...' }])
  • localStorage.getItem / localStorage.setItem calls
  • useState initialised with static data that should be dynamic
  • TODO: fetch from API comments

List every instance found with its file path and line number before making any changes.

3. Replace mock data with Supabase queries

For each instance found:

If FRAMEWORK = nextjs (Server Component pattern):

// Before
const items = [{ id: 1, title: 'Example' }]

// After
import { supabase } from '@/lib/supabase'

const { data: items } = await supabase.from('items').select('*')

If FRAMEWORK = vite (client-side hook pattern):

// Before
const [items, setItems] = useState([{ id: 1, title: 'Example' }])

// After
import { useEffect, useState } from 'react'
import { supabase } from '@/lib/supabase'

const [items, setItems] = useState([])
useEffect(() => {
  supabase.from('items').select('*').then(({ data }) => setItems(data ?? []))
}, [])

Replace localStorage writes with Supabase inserts:

// Before
localStorage.setItem('items', JSON.stringify(newItem))

// After
await supabase.from('items').insert(newItem)

4. Create a DB mapping layer

Supabase returns snake_case column names; TypeScript interfaces typically use camelCase. Create a single file to handle all translation.

If FRAMEWORK = nextjs → create lib/db.ts If FRAMEWORK = vite → create src/lib/db.ts

Import paths: Examples below use @/lib/supabase. Check vite.config.ts or tsconfig.json for the @ alias — if it’s not configured or points to the project root rather than src/, use relative paths instead (e.g. '../lib/supabase').

For each entity, write a mapX function and an insert helper:

// Example for a "session" entity
export function mapSession(row: Record<string, unknown>) {
  return {
    id: row.id as string,
    userId: row.user_id as string,
    createdAt: row.created_at as string,
    // map all columns here
  }
}

export function toSessionRow(session: Partial<Session>) {
  return {
    user_id: session.userId,
    // reverse map for inserts/updates
  }
}

All Supabase query results pass through mapX before use. All inserts/updates pass through the inverse helper. Never scatter column name mapping across components.

Derived vs stored data: Before adding a column to the database, ask: can this value be computed from data already fetched? Counts, streaks, and progress percentages derived from a list of records should be computed client-side, not stored separately — stored copies go stale. Only persist user-set preferences (goals, settings) and source data (individual records).

5. Scope queries to the logged-in user

For any data that belongs to a specific user, first obtain the session, then add .eq('user_id', session.user.id) to the query.

If FRAMEWORK = nextjs (Server Component):

import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'

const supabase = createServerComponentClient({ cookies })
const { data: { session } } = await supabase.auth.getSession()

const { data: items } = await supabase
  .from('items')
  .select('*')
  .eq('user_id', session?.user.id)

If FRAMEWORK = vite:

import { useAuth } from '@/contexts/AuthContext'

const { session } = useAuth()

useEffect(() => {
  if (!session) return
  supabase.from('items').select('*')
    .eq('user_id', session.user.id)
    .then(({ data }) => setItems(data ?? []))
}, [session])

Check supabase/migrations/ for RLS policies. If none exist, prompt: “Your data is not yet scoped to individual users. Go to Supabase → Authentication → Policies to add row-level security rules.”

6. Validate

Ask the user to:

  1. Run npm run dev
  2. Confirm data loads from Supabase (check Supabase → Table Editor to verify rows exist)
  3. Create or update an item and confirm the change appears in Supabase

Report: “✓ Frontend connected to Supabase. Mock data replaced with live queries.”