Receber por email
← Voltar para o catálogo

api-organization

Explains the standardized API organization pattern for this codebase. Use when creating new API endpoints, API clients, or modifying existing API structure. Covers the 5-file system (endpoint-types, endpoints, api-client, admin-api-client, protected-endpoints), role-based access patterns (admin vs regular users), and TypeScript type safety across the API layer. All API code lives in src/lib/api/ f

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/api-organization/svg)](https://www.skillteca.com.br/skills/api-organization)

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

API Organization Pattern

This skill defines the standardized API organization pattern used throughout this codebase. All external API integrations follow the same 5-file structure for consistency, type safety, and maintainability.

When to Use This Skill

Use this skill when:

  • Creating new API endpoints or integrations
  • Adding new API categories or domains
  • Implementing role-based API access (admin vs regular users)
  • Modifying existing API structure
  • Setting up authentication for API calls
  • Creating type-safe API wrappers

Core Principles

  1. Single Source of Truth - All API URLs defined once in endpoints.ts
  2. Type Safety - Full TypeScript coverage from params to responses
  3. Role-Based Access - Separate clients for regular vs admin endpoints
  4. Centralized Auth - Authentication handled automatically by clients
  5. DRY Code - Reusable client functions, no duplicate endpoint definitions

The 5-File System

All API code lives in src/lib/api/ with exactly these files:

src/lib/api/
├── endpoint-types.ts       # TypeScript types for all endpoints
├── endpoints.ts            # URL definitions organized by domain
├── api-client.ts           # Generic authenticated API client
├── admin-api-client.ts     # Admin-only API client with role checks
└── protected-endpoints.ts  # Type-safe wrapper functions

File Purposes

1. endpoint-types.ts

  • Define all TypeScript interfaces for API data
  • Organize types by domain (e.g., audiences, instances, membership)
  • Include param types, response types, and request body DTOs
  • Provide utility types for extracting types

See references/endpoint-types-pattern.md for detailed structure.

2. endpoints.ts

  • Define all API endpoint URLs in one place
  • Organize by feature/domain matching types
  • Use functions that accept parameters and return URLs
  • Support environment variable base URLs

See references/endpoints-pattern.md for detailed structure.

3. api-client.ts

  • Generic API client with automatic authentication
  • Error parsing and handling
  • Support for GET, POST, PUT, DELETE methods
  • Server-side only ('use server')

See references/api-client-pattern.md for implementation.

4. admin-api-client.ts

  • Admin-specific API client
  • Role validation (Admin/SuperAdmin groups)
  • Permission checking functions
  • Throws AdminAuthError if unauthorized

See references/admin-api-client-pattern.md for implementation.

5. protected-endpoints.ts

  • Type-safe wrapper functions combining URLs + types + clients
  • Organized to match endpoint-types structure
  • Provides clean import: import { api } from '@/lib/api/protected-endpoints'
  • No 'use server' directive (exports objects)

See references/protected-endpoints-pattern.md for detailed structure.

Authentication System

This application uses Supabase Auth for authentication. All API requests require authentication via Supabase access tokens.

Supabase Client Structure

src/lib/supabase/
├── client.ts      # Browser-side Supabase client
├── server.ts      # Server-side Supabase client (RSC, Server Actions)
└── middleware.ts  # Middleware helper for auth cookie refresh

Auth Flow

  1. User authenticates via Supabase (email/password, OAuth, etc.)
  2. Supabase stores session in httpOnly cookies
  3. Middleware refreshes session on every request
  4. Server components/actions use createClient() from server.ts
  5. API client extracts access token from session automatically

See references/supabase-auth-integration.md for detailed implementation.

Role-Based Access Pattern

Regular User Endpoints

Use api-client.ts functions with automatic Supabase auth:

import { apiGet, apiPost } from '@/lib/api/api-client';

// Access token extracted from Supabase session automatically
const data = await apiGet<ResponseType>(url);

Admin-Only Endpoints

Use admin-api-client.ts functions with role validation:

import { adminApiRequest, checkAdminPermission } from '@/lib/api/admin-api-client';

// Validate admin access first (checks user role from database)
await checkAdminPermission(); // Throws if not admin

// Make admin API request
const data = await adminApiRequest<ResponseType>(url, options);

Admin Roles

Admin roles are stored in the users table:

  • users.role = 'admin' - Standard admin access
  • users.role = 'member' - Regular user access

First user in a family is automatically assigned admin role.

Adding New API Endpoints

Follow this exact order when integrating a new API into the application:

Step 1: Define Types in endpoint-types.ts

// 1. Define response type(s)
export interface ResourceItem {
  id: string;
  name: string;
  // ... other fields from your API response
}

// 2. Define request DTO(s) for mutations
export interface CreateResourceDto {
  name: string;
  // ... fields required to create
}

// 3. Add parameter types to EndpointParams interface
export interface EndpointParams {
  // ... existing domains

  resources: {
    list: void;              // No params needed
    get: { id: string };     // Requires ID
    create: void;            // Body in request, not params
    update: { id: string };
    delete: { id: string };
  };
}

// 4. Add response types to EndpointResponses interface
export interface EndpointResponses {
  // ... existing domains

  resources: {
    list: ResourceItem[];
    get: ResourceItem;
    create: ResourceItem;
    update: ResourceItem;
    delete: void;
  };
}

// 5. Add request body types to EndpointBodies interface (if needed)
export interface EndpointBodies {
  // ... existing domains

  resources: {
    create: CreateResourceDto;
    update: CreateResourceDto;
  };
}

Step 2: Define URLs in endpoints.ts

export const API_ENDPOINTS = {
  // ... existing categories

  resources: {
    list: () => `${API_BASE}/api/resources`,
    get: (id: string) => `${API_BASE}/api/resources/${id}`,
    create: () => `${API_BASE}/api/resources`,
    update: (id: string) => `${API_BASE}/api/resources/${id}`,
    delete: (id: string) => `${API_BASE}/api/resources/${id}`,
  },
};

Step 3: Add Wrapper in protected-endpoints.ts

export const api = {
  // ... existing domains

  resources: {
    async list(): Promise<ResourceItem[]> {
      return apiGet<ResourceItem[]>(
        API_ENDPOINTS.resources.list()
      );
    },

    async get(id: string): Promise<ResourceItem> {
      return apiGet<ResourceItem>(
        API_ENDPOINTS.resources.get(id)
      );
    },

    async create(data: CreateResourceDto): Promise<ResourceItem> {
      return apiPost<ResourceItem, CreateResourceDto>(
        API_ENDPOINTS.resources.create(),
        data
      );
    },

    async update(id: string, data: CreateResourceDto): Promise<ResourceItem> {
      return apiPut<ResourceItem, CreateResourceDto>(
        API_ENDPOINTS.resources.update(id),
        data
      );
    },

    async delete(id: string): Promise<void> {
      return apiDelete<void>(
        API_ENDPOINTS.resources.delete(id)
      );
    },
  },
};

Step 4: Use in Application Code

'use server';

import { api } from '@/lib/api/protected-endpoints';

// In a server component or server action
const resources = await api.resources.list();
const resource = await api.resources.get(id);
const newResource = await api.resources.create({
  name: 'New Resource'
});

Naming Conventions

Endpoint Operations

  • list / listAll - GET multiple items
  • get - GET single item
  • create - POST new item
  • update - PUT/PATCH existing item
  • delete - DELETE item

Type Naming

  • Response types: PascalCase describing entity (e.g., AudienceListItem)
  • DTOs: PascalCase with suffix (e.g., CreateUserDto, UpdateSettingsDto)
  • Interfaces match plural for collections, singular for items

Error Handling

All API clients handle errors automatically:

try {
  const data = aw
Compartilhar X LinkedIn