Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计通过

fullstack-workflow全栈工作流程

Agent Skill

fullstack-workflow 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

499

周安装

21

GitHub Stars

10,499

下载量

175
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:fullstack-workflow(全栈工作流程)
来源仓库:https://github.com/elie222/inbox-zero
仓库路径:skills/fullstack-workflow
安装命令:
npx skills add https://github.com/elie222/inbox-zero --skill fullstack-workflow
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/elie222/inbox-zero --skill fullstack-workflow

简介

fullstack-workflow 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中快速定位候选结果。

  • 适用于需要根据关键词或任务场景进行信息筛选的场景。
  • 通过安装命令从指定仓库添加技能,可结合原始 README 核验用法。
  • 安装前建议确认权限范围和维护状态,避免触发不必要的数据访问。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Fullstack Workflow

Complete guide for building features from API to UI, combining GET API routes, data fetching, form handling, and server actions.

Overview

When building a new feature, follow this pattern:

  1. GET API Route - For fetching data
  2. Server Action - For mutations (create/update/delete)
  3. Data Fetching - Using SWR on the client
  4. Form Handling - Using React Hook Form with Zod validation

1. GET API Route

For fetching data. Always wrap with withAuth or withEmailAccount:

// apps/web/app/api/user/example/route.ts
import { NextResponse } from "next/server";
import prisma from "@/utils/prisma";
import { withEmailAccount } from "@/utils/middleware";

// Auto-generate response type for client use
export type GetExampleResponse = Awaited<ReturnType<typeof getData>>;

export const GET = withEmailAccount(async (request) => {
  const { emailAccountId } = request.auth;

  const result = await getData({ emailAccountId });
  return NextResponse.json(result);
});

// We make this its own function so we can infer the return type for a type-safe response on the client
async function getData({ emailAccountId }: { emailAccountId: string }) {
  const items = await prisma.example.findMany({
    where: { emailAccountId },
  });

  return { items };
}

2. Server Action

For mutations. Use next-safe-action with proper validation.

Action clients (defined in apps/web/utils/actions/safe-action.ts):

ClientContextUse when
actionClientUserctx.userIdOnly need authenticated user
actionClientctx.emailAccountId, ctx.userIdNeed user + email account (most mutations)
adminActionClientctx.loggerAdmin-only actions (no userId in ctx)

Always use .metadata({name: "actionName"}) for Sentry instrumentation. Use SafeError for expected errors.

Validation Schema (apps/web/utils/actions/example.validation.ts):

import { z } from "zod";

export const createExampleBody = z.object({
  name: z.string().min(1, "Name is required"),
  email: z.string().email("Invalid email"),
  description: z.string().optional(),
});
export type CreateExampleBody = z.infer<typeof createExampleBody>;

export const updateExampleBody = z.object({
  id: z.string(),
  name: z.string().optional(),
  email: z.string().email().optional(),
  description: z.string().optional(),
});
export type UpdateExampleBody = z.infer<typeof updateExampleBody>;

Server Action (apps/web/utils/actions/example.ts):

"use server";

import { actionClient } from "@/utils/actions/safe-action";
import { createExampleBody, updateExampleBody } from "@/utils/actions/example.validation";
import prisma from "@/utils/prisma";

export const createExampleAction = actionClient
  .metadata({ name: "createExample" })
  .inputSchema(createExampleBody)
  .action(async ({
    ctx: { emailAccountId },
    parsedInput: { name, email, description }
  }) => {
    const example = await prisma.example.create({
      data: {
        name,
        email,
        description,
        emailAccountId,
      },
    });

    return example;
  });

export const updateExampleAction = actionClient
  .metadata({ name: "updateExample" })
  .inputSchema(updateExampleBody)
  .action(async ({
    ctx: { emailAccountId },
    parsedInput: { id, name, email, description }
  }) => {
    const example = await prisma.example.update({
      where: { id, emailAccountId },
      data: { name, email, description },
    });

    return example;
  });

3. Data Fetching

Use SWR for client-side data fetching:

import useSWR from "swr";
import { GetExampleResponse } from "@/app/api/user/example/route";

export function useExamples() {
  return useSWR<GetExampleResponse>("/api/user/example");
}

4. Form Handling

Use React Hook Form with useAction from next-safe-action/hooks:

import { useCallback } from "react";
import { useForm, type SubmitHandler } from "react-hook-form";
import { useAction } from "next-safe-action/hooks";
import { zodResolver } from "@hookform/resolvers/zod";
import { Input } from "@/components/Input";
import { Button } from "@/components/ui/button";
import { toastSuccess, toastError } from "@/components/Toast";
import { getActionErrorMessage } from "@/utils/error";
import { createExampleAction } from "@/utils/actions/example";
import { createExampleBody, type CreateExampleBody } from "@/utils/actions/example.validation";

export function ExampleForm({ onSuccess }: { onSuccess?: () => void }) {
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm<CreateExampleBody>({
    resolver: zodResolver(createExampleBody),
  });

  const { execute, isExecuting } = useAction(createExampleAction, {
    onSuccess: () => {
      toastSuccess({ description: "Example created!" });
      reset();
      onSuccess?.();
    },
    onError: (error) => {
      toastError({
        description: getActionErrorMessage(error.error),
      });
    },
  });

  return (
    <form className="space-y-4" onSubmit={handleSubmit(execute)}>
      <Input
        type="text"
        name="name"
        label="Name"
        registerProps={register("name")}
        error={errors.name}
      />
      <Input
        type="email"
        name="email"
        label="Email"
        registerProps={register("email")}
        error={errors.email}
      />
      <Input
        type="text"
        name="description"
        label="Description"
        registerProps={register("description")}
        error={errors.description}
      />
      <Button type="submit" loading={isExecuting}>
        Create Example
      </Button>
    </form>
  );
}

5. Complete Data Fetching Component

'use client';

import { useExamples } from "@/hooks/useExamples";
import { Button } from "@/components/ui/button";
import { LoadingContent } from "@/components/LoadingContent";

export function Examples() {
  const { data, isLoading, error } = useExamples();

  return (
    <LoadingContent loading={isLoading} error={error}>
      <div className="grid gap-4">
        {data?.examples.map((example) => (
          <div key={example.id} className="border p-4 rounded">
            <h3 className="font-semibold">{example.name}</h3>
            <p className="text-gray-600">{example.email}</p>
            {example.description && (
              <p className="text-sm text-gray-500">{example.description}</p>
            )}
          </div>
        ))}
      </div>
    </LoadingContent>
  );
}

Key Guidelines

Authentication & Authorization

  • Use withAuth for user-level operations
  • Use withEmailAccount for email-account-level operations
  • Server actions automatically get the right context

Mutations

  • Use server actions for all mutations (create/update/delete operations)
  • Do NOT use POST API routes for mutations - use server actions instead

Error Handling

  • Use useAction hook with onSuccess and onError callbacks
  • Use getActionErrorMessage(error.error) from @/utils/error to extract user-friendly messages
  • For prefix + error pattern: getActionErrorMessage(error.error, {prefix: "Failed to save"})
  • next-safe-action provides centralized error handling with flattened validation errors
  • No need for try/catch in GET routes when using middleware

Type Safety

  • Export response types from GET routes
  • Use Zod schemas for validation on both client and server
  • Leverage TypeScript inference for better DX

Loading and Error States

  • Use LoadingContent component to handle loading and error states consistently
  • Pass loading, error, and children props to LoadingContent
  • This provides a standardized way to show loading spinners and error messages

Performance

  • Use SWR for efficient data fetching and caching
  • Call mutate() after successful mutations to refresh data

File Organization

apps/web/
├── app/api/user/example/route.ts          # GET API route
├── utils/actions/example.validation.ts    # Zod schemas
├── utils/actions/example.ts               # Server actions
├── hooks/useExamples.ts                   # SWR hook
└── components/ExampleForm.tsx              # Form component

Related Rules

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.76%
按下载量换算59

Claude

27.6%
按下载量换算48

Cursor

19.71%
按下载量换算34

Gemini CLI

9.34%
按下载量换算16

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills