Add v0 prompt for frontend generation
This commit is contained in:
parent
f9b873d331
commit
ab52debf8b
1 changed files with 322 additions and 0 deletions
322
v0-prompt.md
Normal file
322
v0-prompt.md
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
# BloxServer Frontend — v0 Prompt
|
||||
|
||||
Build a Next.js 14+ frontend for BloxServer, a visual AI agent workflow builder. The UI paradigm is like **Excel meets n8n** — toolbar at top, tabs at bottom, flow canvas in the middle.
|
||||
|
||||
## Tech Stack
|
||||
- **Framework:** Next.js 14 (App Router)
|
||||
- **Components:** shadcn/ui + Tailwind CSS
|
||||
- **Flow Canvas:** React Flow (@xyflow/react)
|
||||
- **Code Editor:** Monaco Editor (for YAML and WASM/AssemblyScript)
|
||||
- **State:** Zustand
|
||||
- **Auth:** Clerk
|
||||
- **API:** REST (see types below)
|
||||
|
||||
## Pages
|
||||
|
||||
| Route | Purpose |
|
||||
|-------|---------|
|
||||
| `/` | Landing page (marketing) |
|
||||
| `/dashboard` | Flow list, usage stats, quick actions |
|
||||
| `/flow/[id]` | Main flow editor (canvas + YAML tabs) |
|
||||
| `/flow/[id]/runs` | Execution history for a flow |
|
||||
| `/marketplace` | Browse/install tools and flow templates |
|
||||
| `/settings` | Account, billing, API keys |
|
||||
|
||||
## Flow Editor Layout
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ TOOLBAR: [Save] [Run ▶] [Stop ■] [Canvas|YAML|Split] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────┐ │
|
||||
│ │ PALETTE │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ │ │ Webhook │ ───▶ │ LLM │ ───▶ │ Output │ │
|
||||
│ │[Triggers] │ Trigger │ │ Agent │ │ │ │
|
||||
│ │[LLM] │ └─────────┘ └─────────┘ └─────────┘ │
|
||||
│ │[HTTP] │ │
|
||||
│ │[Code] │ Drag nodes from palette onto canvas. │
|
||||
│ │[Branch] │ Connect outputs to inputs. │
|
||||
│ │[Output] │ Canvas auto-saves. │
|
||||
│ │ │ │
|
||||
│ │[Market] │ YAML tab shows generated config. │
|
||||
│ │ ↳ search│ Edits in YAML reflect back on canvas. │
|
||||
│ └─────────┘ │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ STATUS BAR: Nodes: 3 │ Status: Saved │ Last run: 2m ago │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Node Types
|
||||
|
||||
| Type | Icon | Purpose |
|
||||
|------|------|---------|
|
||||
| `trigger` | 🎯 | Entry point (webhook, schedule, manual) |
|
||||
| `llmCall` | 🤖 | LLM agent (Claude, GPT, Grok) |
|
||||
| `httpRequest` | 🌐 | External API call |
|
||||
| `codeBlock` | 📝 | Custom WASM code (Pro) |
|
||||
| `conditional` | 🔀 | Branch based on condition |
|
||||
| `output` | 📤 | Terminal node / response |
|
||||
|
||||
## Dashboard Features
|
||||
- List of user's flows (cards or table)
|
||||
- Flow status indicator (stopped/running/error)
|
||||
- Quick actions: New Flow, Import, Run
|
||||
- Usage stats (executions this month, limit)
|
||||
|
||||
## Key UX Patterns
|
||||
1. **Bidirectional sync:** Canvas changes update YAML, YAML changes update canvas
|
||||
2. **Auto-save:** Changes saved automatically (debounced)
|
||||
3. **Run/Stop:** Single click to deploy/undeploy a flow
|
||||
4. **Execution history:** Click a run to see logs, input/output payloads
|
||||
5. **Node inspector:** Click a node to edit its config in a side panel
|
||||
|
||||
## API Base URL
|
||||
`https://api.openblox.ai/v1` (placeholder — backend on Render)
|
||||
|
||||
---
|
||||
|
||||
## TypeScript API Types
|
||||
|
||||
```typescript
|
||||
// Common
|
||||
export type UUID = string;
|
||||
export type ISODateTime = string;
|
||||
|
||||
// User (synced from Clerk)
|
||||
export interface User {
|
||||
id: UUID;
|
||||
clerkId: string;
|
||||
email: string;
|
||||
name: string | null;
|
||||
avatarUrl: string | null;
|
||||
tier: 'free' | 'paid' | 'pro' | 'enterprise';
|
||||
createdAt: ISODateTime;
|
||||
}
|
||||
|
||||
// Flow
|
||||
export type FlowStatus = 'stopped' | 'starting' | 'running' | 'stopping' | 'error';
|
||||
|
||||
export interface Flow {
|
||||
id: UUID;
|
||||
userId: UUID;
|
||||
name: string;
|
||||
description: string | null;
|
||||
organismYaml: string;
|
||||
canvasState: CanvasState | null;
|
||||
status: FlowStatus;
|
||||
containerId: string | null;
|
||||
errorMessage: string | null;
|
||||
createdAt: ISODateTime;
|
||||
updatedAt: ISODateTime;
|
||||
}
|
||||
|
||||
export interface FlowSummary {
|
||||
id: UUID;
|
||||
name: string;
|
||||
description: string | null;
|
||||
status: FlowStatus;
|
||||
updatedAt: ISODateTime;
|
||||
}
|
||||
|
||||
export interface CreateFlowRequest {
|
||||
name: string;
|
||||
description?: string;
|
||||
organismYaml?: string;
|
||||
}
|
||||
|
||||
export interface UpdateFlowRequest {
|
||||
name?: string;
|
||||
description?: string;
|
||||
organismYaml?: string;
|
||||
canvasState?: CanvasState;
|
||||
}
|
||||
|
||||
// Canvas State (React Flow)
|
||||
export interface CanvasState {
|
||||
nodes: CanvasNode[];
|
||||
edges: CanvasEdge[];
|
||||
viewport: { x: number; y: number; zoom: number };
|
||||
}
|
||||
|
||||
export interface CanvasNode {
|
||||
id: string;
|
||||
type: NodeType;
|
||||
position: { x: number; y: number };
|
||||
data: NodeData;
|
||||
}
|
||||
|
||||
export type NodeType =
|
||||
| 'trigger'
|
||||
| 'llmCall'
|
||||
| 'httpRequest'
|
||||
| 'codeBlock'
|
||||
| 'conditional'
|
||||
| 'output'
|
||||
| 'custom';
|
||||
|
||||
export interface NodeData {
|
||||
name: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
handler?: string;
|
||||
payloadClass?: string;
|
||||
isAgent?: boolean;
|
||||
config?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface CanvasEdge {
|
||||
id: string;
|
||||
source: string;
|
||||
target: string;
|
||||
sourceHandle?: string;
|
||||
targetHandle?: string;
|
||||
}
|
||||
|
||||
// Triggers
|
||||
export type TriggerType = 'webhook' | 'schedule' | 'manual';
|
||||
|
||||
export interface Trigger {
|
||||
id: UUID;
|
||||
flowId: UUID;
|
||||
type: TriggerType;
|
||||
name: string;
|
||||
config: TriggerConfig;
|
||||
webhookToken?: string;
|
||||
webhookUrl?: string;
|
||||
createdAt: ISODateTime;
|
||||
}
|
||||
|
||||
export type TriggerConfig =
|
||||
| { type: 'webhook' }
|
||||
| { type: 'schedule'; cron: string; timezone?: string }
|
||||
| { type: 'manual' };
|
||||
|
||||
export interface CreateTriggerRequest {
|
||||
type: TriggerType;
|
||||
name: string;
|
||||
config: TriggerConfig;
|
||||
}
|
||||
|
||||
// Executions (Run History)
|
||||
export type ExecutionStatus = 'running' | 'success' | 'error' | 'timeout';
|
||||
|
||||
export interface Execution {
|
||||
id: UUID;
|
||||
flowId: UUID;
|
||||
triggerId: UUID | null;
|
||||
triggerType: TriggerType;
|
||||
status: ExecutionStatus;
|
||||
startedAt: ISODateTime;
|
||||
completedAt: ISODateTime | null;
|
||||
durationMs: number | null;
|
||||
errorMessage: string | null;
|
||||
inputPayload: string | null;
|
||||
outputPayload: string | null;
|
||||
}
|
||||
|
||||
export interface ExecutionSummary {
|
||||
id: UUID;
|
||||
status: ExecutionStatus;
|
||||
triggerType: TriggerType;
|
||||
startedAt: ISODateTime;
|
||||
durationMs: number | null;
|
||||
}
|
||||
|
||||
// Marketplace
|
||||
export type MarketplaceListingType = 'tool' | 'flow';
|
||||
|
||||
export interface MarketplaceListingSummary {
|
||||
id: UUID;
|
||||
authorName: string;
|
||||
type: MarketplaceListingType;
|
||||
name: string;
|
||||
description: string;
|
||||
category: string;
|
||||
downloads: number;
|
||||
rating: number | null;
|
||||
}
|
||||
|
||||
// API Responses
|
||||
export interface PaginatedResponse<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
hasMore: boolean;
|
||||
}
|
||||
|
||||
export interface ApiError {
|
||||
code: string;
|
||||
message: string;
|
||||
details?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
// Stats
|
||||
export interface FlowStats {
|
||||
flowId: UUID;
|
||||
executionsTotal: number;
|
||||
executionsSuccess: number;
|
||||
executionsError: number;
|
||||
avgDurationMs: number;
|
||||
lastExecutedAt: ISODateTime | null;
|
||||
}
|
||||
|
||||
export interface UsageStats {
|
||||
userId: UUID;
|
||||
period: 'day' | 'month';
|
||||
flowCount: number;
|
||||
executionCount: number;
|
||||
executionLimit: number;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Flows
|
||||
- `GET /flows` — List user's flows (returns `FlowSummary[]`)
|
||||
- `POST /flows` — Create flow
|
||||
- `GET /flows/:id` — Get full flow
|
||||
- `PATCH /flows/:id` — Update flow
|
||||
- `DELETE /flows/:id` — Delete flow
|
||||
- `POST /flows/:id/start` — Start flow (deploy container)
|
||||
- `POST /flows/:id/stop` — Stop flow
|
||||
|
||||
### Triggers
|
||||
- `GET /flows/:id/triggers` — List triggers
|
||||
- `POST /flows/:id/triggers` — Create trigger
|
||||
- `DELETE /triggers/:id` — Delete trigger
|
||||
|
||||
### Executions
|
||||
- `GET /flows/:id/executions` — List runs (paginated)
|
||||
- `GET /executions/:id` — Get run details
|
||||
- `GET /executions/:id/logs` — Stream logs (WebSocket)
|
||||
|
||||
### Marketplace
|
||||
- `GET /marketplace` — Browse listings
|
||||
- `GET /marketplace/:id` — Get listing details
|
||||
- `POST /marketplace/:id/install` — Install to user's library
|
||||
|
||||
### User
|
||||
- `GET /me` — Current user info + usage stats
|
||||
|
||||
---
|
||||
|
||||
## Design Notes
|
||||
|
||||
1. **Dark mode default** — Developer audience prefers dark
|
||||
2. **Keyboard shortcuts** — Cmd+S save, Cmd+Enter run, etc.
|
||||
3. **Toast notifications** — For save/run/error feedback
|
||||
4. **Loading states** — Skeleton loaders, not spinners
|
||||
5. **Mobile:** Dashboard is responsive, flow editor is desktop-only (show message on mobile)
|
||||
|
||||
---
|
||||
|
||||
## Start With
|
||||
1. Dashboard page with flow list
|
||||
2. Flow editor with React Flow canvas
|
||||
3. Basic YAML tab (Monaco, read-only first)
|
||||
4. Run/Stop buttons that call API
|
||||
|
||||
Then iterate: node inspector panel, execution history, marketplace.
|
||||
Loading…
Reference in a new issue