본문으로 건너뛰기
cccskills
무료GitHub에 공개

frontend-api-integration

Integrate with the FastAPI backend through the typed wrapper in frontend/lib/api.ts, attach Supabase JWTs for admin calls, and handle errors via ApiError. Use when adding/modifying API calls or wiring auth.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구Supabase
설치 방법 보기

포함된 파일(1)

  • SKILL.md6.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

API Integration Skill

Version: 1.0 | Working Directory: frontend/

API integration patterns for $ARGUMENTS in the Next.js frontend.

Overview

Single API surface, single auth flow:

  • frontend/lib/api.ts — typed fetch wrapper, ApiError class, helpers per endpoint
  • process.env.NEXT_PUBLIC_API_URL — base URL (no other URLs hardcoded anywhere)
  • Supabase Auth — admin JWT obtained from the Supabase session and passed as token to admin* helpers
  • @supabase/ssr — createSupabaseServerClient() for RSC/route handlers, createSupabaseBrowserClient() for Client Components

Constitution (Non-Negotiable Rules)

#RuleWhy
1Every backend call is a typed helper in lib/api.ts — never fetch against NEXT_PUBLIC_API_URL from a component or pageOne typed surface, one place to add headers/cache
2Admin calls require token — get it from supabase.auth.getSession() and pass to the helperBackend's require_admin checks the JWT
3Never hardcode the API URL — always via NEXT_PUBLIC_API_URLEnvironment-portable
4Throw ApiError — non-2xx responses already throw; let it propagate or catch with instanceof ApiError for detailConsistent error surface
5Strict types for request and response — define them in lib/types.ts, import where usedNo any
6No service-role secret on the frontend — never reference SUPABASE_SERVICE_ROLE_KEY from frontend/; that key is backend-onlyService-role bypasses RLS
7Cache choice is deliberate — admin/checkout helpers use cache: "no-store" (already set); use next: { revalidate: N } for ISR-eligible readsAvoid stale dashboards and accidental caching of mutations
8Multipart goes through a dedicated helper — adminUploadImage builds FormData and skips Content-Type so the browser sets the boundaryMultipart needs no manual Content-Type

When to Use

  • Adding a new FastAPI endpoint to consume from the UI
  • Modifying error handling for a call
  • Wiring admin auth into a new admin page
  • Adding a multipart upload

Quick Start

1. Add a typed helper

// frontend/lib/api.ts
export function adminBulkUpdateProducts(token: string, ids: string[], patch: Partial<Product>) {
  return api<Product[]>(`/api/admin/products/bulk`, {
    method: "POST",
    token,
    body: JSON.stringify({ ids, patch }),
  });
}

(If new shapes are involved, define them in frontend/lib/types.ts first.)

2. Use it from a Server Component (admin)

import { createSupabaseServerClient } from "@/lib/supabase/server";
import { adminListOrders } from "@/lib/api";

export default async function OrdersPage() {
  const supabase = await createSupabaseServerClient();
  const { data: { session } } = await supabase.auth.getSession();
  if (!session) redirect("/admin/login");
  const { items } = await adminListOrders(session.access_token, { limit: 50 });
  return <OrdersTable items={items} />;
}

3. Use it from a Client Component (admin mutation)

"use client";
import { useRouter } from "next/navigation";
import { createSupabaseBrowserClient } from "@/lib/supabase/client";
import { adminSetOrderStatus, ApiError } from "@/lib/api";

export function StatusDropdown({ orderId, current }: { orderId: string; current: string }) {
  const router = useRouter();
  async function onChange(next: string) {
    const supabase = createSupabaseBrowserClient();
    const { data: { session } } = await supabase.auth.getSession();
    if (!session) return;
    try {
      await adminSetOrderStatus(session.access_token, orderId, next);
      router.refresh();
    } catch (err) {
      alert(err instanceof ApiError ? String(err.detail) : "Update failed");
    }
  }
  return <select defaultValue={current} onChange={(e) => onChange(e.target.value)}>{/* ... */}</select>;
}

4. Public/storefront call from a Server Component

import { listProducts } from "@/lib/api";
const { items } = await listProducts({ q, limit: 24 });

Auth & Token Lifecycle

  • Sign-in / sign-out — frontend/app/admin/login/page.tsx uses createSupabaseBrowserClient() to call signInWithPassword / signOut
  • Session refresh — frontend/middleware.ts runs updateSession() for /admin/:path*, which keeps cookies fresh on every request
  • Reading the session — server: createSupabaseServerClient().auth.getSession(); client: createSupabaseBrowserClient().auth.getSession()
  • Role check — user.app_metadata?.role === "admin"; non-admins get a redirect/403 server-side
  • Never copy the access token into localStorage or attach it to non-admin requests

Cache Strategy

CallCache
Admin list/detailcache: "no-store" (already set) — admins want fresh data
Mutations (POST/PATCH)cache: "no-store"
Public product list/detailcache: "no-store" for now; switch to next: { revalidate: 60 } if traffic warrants
After a mutationrouter.refresh() from the Client Component to re-render server data

Errors

api() throws ApiError(status, detail) for non-2xx. detail is the parsed JSON body when the server returned JSON (FastAPI usually returns { "detail": "..." }), otherwise the raw text.

try { await checkout(payload); }
catch (e) {
  if (e instanceof ApiError) {
    const msg = typeof e.detail === "object" && e.detail && "detail" in e.detail
      ? String((e.detail as { detail: unknown }).detail)
      : String(e.detail);
    setError(msg);
  } else {
    setError("Network error");
  }
}

In Server Components: let it bubble to the closest error.tsx, or catch and notFound() for 404s (see exemplar app/(store)/products/[slug]/page.tsx).

Multipart Uploads

adminUploadImage is the template:

  • Build FormData, append the file
  • Bypass the JSON api() wrapper (it sets Content-Type: application/json)
  • Set Authorization manually; let the browser set the multipart boundary
  • Throw ApiError on non-2xx for parity

Don't add a generic multipart helper unless a second upload endpoint shows up.

Exemplar Files

  • frontend/lib/api.ts — every helper, ApiError, the api<T>() core
  • frontend/lib/supabase/server.ts — RSC/route-handler client
  • frontend/lib/supabase/client.ts — browser client
  • frontend/lib/supabase/middleware.ts — session refresh used by frontend/middleware.ts
  • frontend/lib/types.ts — request/response types

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Supabase Postgres + Storage + Auth operations from FastAPI — service-role client, RLS-aware queries, additive SQL migrations under backend/db/migrations, the create_order RPC, and the product-images bucket. Use when adding tables/columns, writing queries, calling RPCs, or working with Storage.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

shanraisshan/learning-x-claude22026년 5월 7일 업데이트

Build FastAPI endpoints in the layered router → service → Supabase pattern, with Pydantic v2 schemas, JWT/admin gating, and consistent HTTPException-based domain errors. Use when adding/modifying any endpoint under backend/.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

shanraisshan/learning-x-claude22026년 5월 7일 업데이트

pytest + httpx + TestClient patterns for the FastAPI backend. Dependency overrides for auth, FakeSupabase mocking, HTTPException assertions. Use when writing or reviewing backend/tests/test_*.py.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

shanraisshan/learning-x-claude22026년 5월 7일 업데이트

Drive Chrome via the claude-in-chrome MCP to exercise plan.md::Verify steps for a shipped feature. Loads deferred MCP tool schemas, asserts console/network cleanliness, records a GIF for the PR. Used by the browser-verifier agent.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

shanraisshan/learning-x-claude22026년 5월 7일 업데이트

Pre-PR code review checklist for this repo. Plan alignment, security gates, layering, dead code, API-surface completeness. Used by the code-reviewer agent.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

shanraisshan/learning-x-claude22026년 5월 7일 업데이트

Build pages and components in the Next.js 15 App Router (RSC by default, "use client" only when needed), Tailwind for styling, typed props, and the existing CartProvider for cart state. Use when creating or modifying pages, layouts, components, or forms in frontend/.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

shanraisshan/learning-x-claude22026년 5월 7일 업데이트

shanraisshan의 스킬 모두 보기

이 스킬의 문제 신고