Files
gh-warrenzhu050413-warren-c…/skills/rapid-fullstack/SKILL.md
2025-11-30 09:05:19 +08:00

10 KiB

Rapid Full-Stack Prototyping

Build working full-stack web apps quickly (1-4 hours). Design first, code second, test third.

When to Use

  • User says "WEBAPP", "PROTOTYPE", "full-stack app", or "build a web application"
  • Need both backend API + frontend UI
  • Want speed + quality

What You'll Build

  • Stack: React + Vite + RESTful API (FastAPI/Express) + SQLite
  • Timeline: 1-4 hours from idea to working app
  • Output: Polished, functional prototype with keyboard shortcuts and clean UI

The 3-Step Process

Step 1: Design (5-10 min)

Create a text-based design showing:

UI LAYOUT:
[Header with Logo, Nav, Actions]
[Main Content - Left Sidebar | Center Panel | Right Info]
[Footer with Status]

USER INTERACTIONS:
1. Click "New" → Opens editor
2. Type text → Updates state
3. Press ⌘S → Saves via API
4. Click "History" → Opens panel

DATA MODELS:
- Item: {id, content, created_at}
- Revision: {id, item_id, content, timestamp}

API ENDPOINTS:
GET  /api/items          → List all
POST /api/items          → Create new
GET  /api/items/:id      → Get one
PUT  /api/items/:id      → Update
GET  /api/history/:id    → Get revisions

Step 2: Get Approval (30 sec)

Show the design → User says "looks good" → Start coding

Step 3: Build (1-3 hours)

Use this stack (don't ask, just use):

  • Frontend: React + Vite
  • Backend: FastAPI (Python) or Express (Node)
  • Database: SQLite
  • State: useState + useEffect

Build in order:

  1. Backend skeleton (30 min)
  2. Core features (1-2 hours)
  3. Polish + keyboard shortcuts (30 min)
  4. Test with WEBTEST

Rules for Claude

DO:

  • Design mock UI before any code
  • Use React + RESTful API (default)
  • Start coding immediately after approval
  • Add keyboard shortcuts (⌘S, ⌘/, etc.)

DON'T:

  • Ask user to choose frameworks
  • Skip the design phase
  • Spend 30+ min researching simple features
  • Build custom solutions for standard problems

Core Principles

  1. Design Before Code - Mock UI + interactions first, then build
  2. Use What You Know - Familiar tools > "perfect" tools you don't know
  3. Single Source of Truth - One state for each piece of data, sync explicitly
  4. Right Tool for Job - Fighting a component's design? Wrong component
  5. Test Early - Automated tests + real user feedback before launch

Default Stack (Use This)

Frontend:  React + Vite
Backend:   FastAPI (Python) or Express (Node)
Database:  SQLite
State:     useState + useEffect
Styling:   Vanilla CSS

Why? Fast setup, familiar patterns, good docs, zero config database.

When to deviate:

  • User explicitly requests different stack → use their choice
  • User needs SEO/SSR → use Next.js instead of Vite
  • User says "no code" → suggest Bubble/Retool (explain trade-offs)

Choosing Libraries

When to add a library:

  • Would take > 1 hour to build from scratch
  • Well-maintained (updated in last 6 months)
  • You need > 30% of its features

When to build it yourself:

  • Can be done in < 30 lines of code
  • Only need 10% of library features
  • Fighting the library's design

Quick research (spend max 15 min):

# 1. Search
WebSearch: "best [feature] library react 2025"

# 2. Check npm
npm info [package-name]
# Look at: downloads/week, last publish, dependencies count

# 3. Test
# Try basic example - works in 15 min? Keep it. Doesn't? Try next option.

Examples:

// ❌ Don't need library for:
fetch()              // axios is overkill
<textarea />         // don't force WYSIWYG when plain text works
Intl.DateTimeFormat  // moment.js is heavy

// ✅ Use library for:
<MarkdownEditor />   // complex parsing + preview
<DiffViewer />       // diff algorithm is non-trivial
<CodeEditor />       // syntax highlighting + LSP

Project Structure

project/
├── backend/
│   ├── server.py          # FastAPI app
│   └── requirements.txt   # Python deps
├── frontend/
│   ├── src/
│   │   ├── App.jsx       # Main component
│   │   ├── App.css       # Styles
│   │   └── main.jsx      # Entry point
│   ├── package.json
│   └── vite.config.js    # Vite config with proxy
├── launcher-script        # CLI to start both servers
├── install.sh            # Setup script
└── README.md             # Documentation

Build Workflow

Phase 0: Design (15-30 min)

See "The 3-Step Process" above - create text-based design with UI layout, interactions, data models, and API endpoints. Show to user → get approval → start coding.

Phase 1: Backend + Frontend Skeleton (30 min)

Backend:

# Define models → Create CRUD endpoints → Test with curl
# FastAPI example:
@app.get("/api/items")
async def list_items(): ...

@app.post("/api/items")
async def create_item(item: Item): ...

Frontend:

npm create vite@latest my-app -- --template react
cd my-app && npm install
# Configure vite.config.js proxy to backend
# Test connection with /api/health endpoint

Phase 2: Core Features (1-2 hours)

  • Build one feature at a time
  • useState for local state, useEffect for side effects
  • Single source of truth (one canonical state, sync others from it)
  • Test each feature before moving to next

Phase 3: Polish (30 min)

// Add keyboard shortcuts
useEffect(() => {
  const handleKeyDown = (e) => {
    if (e.metaKey) {
      if (e.key === 's') { e.preventDefault(); save(); }
      if (e.key === '/') { e.preventDefault(); showHelp(); }
    }
  };
  window.addEventListener('keydown', handleKeyDown);
  return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
  • Add help modal (⌘/)
  • Add button active states
  • Add status feedback ("✓ Saved")
  • Add tooltips with keyboard shortcuts

Phase 4: Test (Use WEBTEST)

# Run automated tests
WEBTEST  # Triggers testing-webapps skill

# Manual checks:
# - All buttons work
# - Data persists after save
# - No console errors
# - Keyboard shortcuts work

Common Mistakes

1. Multiple Sources of Truth

// ❌ Bad: Three states for same data
const [editorContent, setEditorContent] = useState('');
const [diffContent, setDiffContent] = useState('');
const [previewContent, setPreviewContent] = useState('');

// ✅ Good: One source, sync to views
const [content, setContent] = useState('');
useEffect(() => {
  editorRef.current?.setContent(content);
}, [viewMode, content]);

2. Fighting Component Design

// ❌ Bad: Complex CSS to hide UI elements
.editor .toolbar { display: none !important; }
.editor .tabs { visibility: hidden !important; }

// ✅ Good: Use simpler component
<textarea value={content} onChange={e => setContent(e.target.value)} />

3. Hardcoded Config

// ❌ Bad
target: 'http://127.0.0.1:8765'

// ✅ Good
const port = process.env.VITE_BACKEND_PORT || '8765';
target: `http://127.0.0.1:${port}`

4. CORS Issues

# ✅ FastAPI CORS setup
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],
    allow_methods=["*"],
    allow_headers=["*"],
)

Code Patterns

Button States

.btn { background: #007bff; transition: 0.2s; }
.btn:hover { background: #0056b3; }
.btn.active { background: #28a745; box-shadow: 0 2px 4px rgba(0,0,0,0.2); }

Status Feedback

const save = async () => {
  try {
    await saveToBackend();
    setStatus('✓ Saved');
    setTimeout(() => setStatus(''), 2000);
  } catch (error) {
    setStatus('❌ Error');
  }
};

Help Modal

{helpOpen && (
  <div className="modal" onClick={() => setHelpOpen(false)}>
    <div className="content" onClick={e => e.stopPropagation()}>
      <h3>⌨️ Shortcuts</h3>
      <kbd> S</kbd> Save
      <kbd> /</kbd> Help
    </div>
  </div>
)}

Launcher Script

Create a simple script to start both servers:

#!/usr/bin/env python3
import subprocess, webbrowser, time

# Start backend
backend = subprocess.Popen(
    ["uvicorn", "server:app", "--port", "8000"],
    cwd="./backend"
)

# Start frontend
frontend = subprocess.Popen(
    ["npm", "run", "dev"],
    cwd="./frontend"
)

time.sleep(2)
webbrowser.open("http://localhost:5173")

try:
    backend.wait()
except KeyboardInterrupt:
    backend.terminate()
    frontend.terminate()

Make executable: chmod +x launcher

Quick Reference

Testing Checklist

# Automated
WEBTEST  # Use testing-webapps skill

# Manual
- [ ] All buttons work
- [ ] Keyboard shortcuts (⌘S, ⌘/)
- [ ] Data persists
- [ ] No console errors

When to Add a Feature

  1. Solves real problem? ✓
  2. Can be done simply? ✓
  3. Fits core purpose? ✓

If any = no → defer it

When to Refactor

  • Code duplicated 3+ times
  • Fighting component design
  • Adding features getting harder

View Modes Pattern

const [viewMode, setViewMode] = useState('edit');
const [content, setContent] = useState('');

{viewMode === 'edit' && <Editor value={content} onChange={setContent} />}
{viewMode === 'diff' && <DiffView content={content} previous={prev} />}
{viewMode === 'preview' && <Preview content={content} />}

Debugging

  1. Console errors (browser + terminal)
  2. Network tab (API responses)
  3. React DevTools (state flow)
  4. Use right component for the job?

Success Criteria

  • Core features work end-to-end
  • Keyboard shortcuts (⌘S, ⌘/)
  • No console errors
  • Data persists
  • Clean UI, no glitches

Real Example: mdedit (3 hours total)

Stack: React + Vite + FastAPI + SQLite Features: 4 view modes, version history, visual diff, keyboard shortcuts

Key Decisions (38 min research):

  • FastAPI > Flask (type hints, async)
  • SQLite > Postgres (zero config)
  • Toast UI Editor for rich editing, but textarea for diff mode (fighting component = wrong tool)
  • react-diff-viewer (GitHub-style, simple)
  • marked for preview (lightweight)

Lesson: Don't fight components with CSS. Use simpler alternatives when needed.


Key Reminders

Design → Code → Test

  • Mock UI + interactions first
  • Use defaults (React + RESTful)
  • WEBTEST when done

Red Flags:

  • Complex CSS hiding → wrong component
  • Multiple states for same data → refactor
  • Fighting a library → use different one
  • 30 min on one bug → rethink approach

Best Prototypes Are:

  1. Fast (1-4 hours)
  2. Simple (easy to change)
  3. Polished (shortcuts + help)
  4. Tested (no errors)