スキル一覧に戻る
levanminhduc

cloudflare

by levanminhduc

0🍴 0📅 2025年12月25日
GitHubで見るManusで実行

SKILL.md


name: cloudflare description: Guide for building applications on Cloudflare's edge platform. Use when implementing serverless functions (Workers), edge databases (D1), storage (R2, KV), real-time apps (Durable Objects), AI features (Workers AI, AI Gateway), static sites (Pages), or any edge computing solutions. license: MIT version: 1.0.0

Cloudflare Developer Platform Skill

Cloudflare Developer Platform is a comprehensive edge computing ecosystem for building full-stack applications on Cloudflare's global network. It includes serverless functions, databases, storage, AI/ML capabilities, and static site hosting.

When to Use This Skill

Use this skill when:

  • Building serverless applications on the edge
  • Implementing edge databases (D1 SQLite)
  • Working with object storage (R2) or key-value stores (KV)
  • Creating real-time applications with WebSockets (Durable Objects)
  • Integrating AI/ML capabilities (Workers AI, AI Gateway, Agents)
  • Deploying static sites with serverless functions (Pages)
  • Building full-stack applications with frameworks (Next.js, Remix, Astro, etc.)
  • Implementing message queues and background jobs (Queues)
  • Optimizing for global performance and low latency

Core Concepts

Edge Computing Platform

Cloudflare's Edge Network: Code runs on servers globally distributed across 300+ cities, executing requests from the nearest location for ultra-low latency.

Key Components:

  • Workers: Serverless functions on the edge
  • D1: SQLite database with global read replication
  • KV: Distributed key-value store with eventual consistency
  • R2: Object storage with zero egress fees
  • Durable Objects: Stateful compute with WebSocket support
  • Queues: Message queue system for async processing
  • Pages: Static site hosting with serverless functions
  • Workers AI: Run AI models on the edge
  • AI Gateway: Unified interface for AI providers

Execution Model

V8 Isolates: Lightweight execution environments (faster than containers) with:

  • Millisecond cold starts
  • Zero infrastructure management
  • Automatic scaling
  • Pay-per-request pricing

Handler Types:

  • fetch: HTTP requests
  • scheduled: Cron jobs
  • queue: Message processing
  • tail: Log aggregation
  • email: Email handling
  • alarm: Durable Object timers

Getting Started with Workers

Installation

# Install Wrangler CLI
npm install -g wrangler

# Login to Cloudflare
wrangler login

# Create new project
wrangler init my-worker
cd my-worker

# Start local development
wrangler dev

# Deploy to production
wrangler deploy

Basic Worker

// src/index.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    return new Response("Hello from Cloudflare Workers!");
  },
};

Configuration (wrangler.toml)

name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"

# Environment variables
[vars]
ENVIRONMENT = "production"

# Bindings (added per product below)

Language Support

  • JavaScript/TypeScript: Primary language (full Node.js compatibility)
  • Python: Beta support via Workers Python
  • Rust: Compile to WebAssembly

Storage Products

D1 (SQLite Database)

Use Cases: Relational data, complex queries, ACID transactions

Setup:

# Create database
wrangler d1 create my-database

# Add to wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "YOUR_DATABASE_ID"

# Generate and apply schema
wrangler d1 execute my-database --file=./schema.sql

Usage:

export default {
  async fetch(request: Request, env: Env) {
    // Query
    const result = await env.DB.prepare("SELECT * FROM users WHERE id = ?")
      .bind(userId)
      .first();

    // Insert
    await env.DB.prepare("INSERT INTO users (name, email) VALUES (?, ?)")
      .bind("Alice", "alice@example.com")
      .run();

    // Batch (atomic)
    await env.DB.batch([
      env.DB.prepare(
        "UPDATE accounts SET balance = balance - 100 WHERE id = ?",
      ).bind(user1),
      env.DB.prepare(
        "UPDATE accounts SET balance = balance + 100 WHERE id = ?",
      ).bind(user2),
    ]);

    return new Response(JSON.stringify(result));
  },
};

Key Features:

  • Global read replication (low-latency reads)
  • Single-writer consistency
  • Standard SQLite syntax
  • 25GB database size limit

KV (Key-Value Store)

Use Cases: Cache, sessions, feature flags, rate limiting

Setup:

# Create namespace
wrangler kv:namespace create MY_KV

# Add to wrangler.toml
[[kv_namespaces]]
binding = "KV"
id = "YOUR_NAMESPACE_ID"

Usage:

export default {
  async fetch(request: Request, env: Env) {
    // Put with TTL
    await env.KV.put("session:token", JSON.stringify(data), {
      expirationTtl: 3600, // 1 hour
    });

    // Get
    const data = await env.KV.get("session:token", "json");

    // Delete
    await env.KV.delete("session:token");

    // List with prefix
    const list = await env.KV.list({ prefix: "user:123:" });

    return new Response(JSON.stringify(data));
  },
};

Key Features:

  • Sub-millisecond reads (edge-cached)
  • Eventual consistency (~60 seconds globally)
  • 25MB value size limit
  • Automatic expiration (TTL)

R2 (Object Storage)

Use Cases: File storage, media hosting, backups, static assets

Setup:

# Create bucket
wrangler r2 bucket create my-bucket

# Add to wrangler.toml
[[r2_buckets]]
binding = "R2_BUCKET"
bucket_name = "my-bucket"

Usage:

export default {
  async fetch(request: Request, env: Env) {
    // Put object
    await env.R2_BUCKET.put("path/to/file.jpg", fileBuffer, {
      httpMetadata: {
        contentType: "image/jpeg",
      },
    });

    // Get object
    const object = await env.R2_BUCKET.get("path/to/file.jpg");
    if (!object) {
      return new Response("Not found", { status: 404 });
    }

    // Stream response
    return new Response(object.body, {
      headers: {
        "Content-Type":
          object.httpMetadata?.contentType || "application/octet-stream",
      },
    });

    // Delete
    await env.R2_BUCKET.delete("path/to/file.jpg");

    // List
    const list = await env.R2_BUCKET.list({ prefix: "uploads/" });
  },
};

Key Features:

  • S3-compatible API
  • Zero egress fees (huge cost advantage)
  • Unlimited storage
  • 5TB object size limit
  • Multipart upload support

Durable Objects

Use Cases: Real-time apps, WebSockets, coordination, stateful logic

Setup:

# wrangler.toml
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"
script_name = "my-worker"

Usage:

// Define Durable Object class
export class Counter {
  state: DurableObjectState;

  constructor(state: DurableObjectState, env: Env) {
    this.state = state;
  }

  async fetch(request: Request) {
    // Get current count
    let count = (await this.state.storage.get<number>("count")) || 0;

    // Increment
    count++;
    await this.state.storage.put("count", count);

    return new Response(JSON.stringify({ count }));
  }
}

// Use in Worker
export default {
  async fetch(request: Request, env: Env) {
    // Get Durable Object instance
    const id = env.COUNTER.idFromName("global-counter");
    const counter = env.COUNTER.get(id);

    // Forward request
    return counter.fetch(request);
  },
};

WebSocket Example:

export class ChatRoom {
  state: DurableObjectState;
  sessions: Set<WebSocket>;

  constructor(state: DurableObjectState) {
    this.state = state;
    this.sessions = new Set();
  }

  async fetch(request: Request) {
    const pair = new WebSocketPair();
    const [client, server] = Object.values(pair);

    this.state.acceptWebSocket(server);
    this.sessions.add(server);

    return new Response(null, { status: 101, webSocket: client });
  }

  async webSocketMessage(ws: WebSocket, message: string) {
    // Broadcast to all connected clients
    for (const session of this.sessions) {
      session.send(message);
    }
  }

  async webSocketClose(ws: WebSocket) {
    this.sessions.delete(ws);
  }
}

Key Features:

  • Single-instance coordination (strong consistency)
  • Persistent storage (1GB limit on paid plans)
  • WebSocket support
  • Automatic hibernation for inactive objects

Queues

Use Cases: Background jobs, email sending, async processing

Setup:

# wrangler.toml
[[queues.producers]]
binding = "MY_QUEUE"
queue = "my-queue"

[[queues.consumers]]
queue = "my-queue"
max_batch_size = 10
max_batch_timeout = 30

Usage:

// Producer: Send messages
export default {
  async fetch(request: Request, env: Env) {
    await env.MY_QUEUE.send({
      type: "email",
      to: "user@example.com",
      subject: "Welcome!",
    });

    return new Response("Message queued");
  },
};

// Consumer: Process messages
export default {
  async queue(batch: MessageBatch<any>, env: Env) {
    for (const message of batch.messages) {
      try {
        await processMessage(message.body);
        message.ack(); // Acknowledge success
      } catch (error) {
        message.retry(); // Retry on failure
      }
    }
  },
};

Key Features:

  • At-least-once delivery
  • Automatic retries (exponential backoff)
  • Dead-letter queue support
  • Batch processing

AI Products

Workers AI

Use Cases: Run AI models directly on the edge

Setup:

# wrangler.toml
[ai]
binding = "AI"

Usage:

export default {
  async fetch(request: Request, env: Env) {
    // Text generation
    const response = await env.AI.run("@cf/meta/llama-3-8b-instruct", {
      messages: [{ role: "user", content: "What is edge computing?" }],
    });

    // Image classification
    const imageResponse = await env.AI.run("@cf/microsoft/resnet-50", {
      image: imageBuffer,
    });

    // Text embeddings
    const embeddings = await env.AI.run("@cf/baai/bge-base-en-v1.5", {
      text: "Hello world",
    });

    return new Response(JSON.stringify(response));
  },
};

Available Models:

  • LLMs: Llama 3, Mistral, Gemma, Qwen
  • Image: Stable Diffusion, DALL-E, ResNet
  • Embeddings: BGE, GTE
  • Translation, summarization, sentiment analysis

AI Gateway

Use Cases: Unified interface for AI providers with caching, rate limiting, analytics

Setup:

// OpenAI via AI Gateway
const response = await fetch(
  "https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${env.OPENAI_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "gpt-4",
      messages: [{ role: "user", content: "Hello!" }],
    }),
  },
);

Features:

  • Request caching (reduce costs)
  • Rate limiting
  • Analytics and logging
  • Supports OpenAI, Anthropic, HuggingFace, etc.

Agents

Use Cases: Build AI agents with tools and workflows

import { Agent } from "@cloudflare/agents";

export default {
  async fetch(request: Request, env: Env) {
    const agent = new Agent({
      model: "@cf/meta/llama-3-8b-instruct",
      tools: [
        {
          name: "get_weather",
          description: "Get current weather",
          parameters: {
            type: "object",
            properties: {
              location: { type: "string" },
            },
          },
          handler: async ({ location }) => {
            // Fetch weather data
            return { temperature: 72, conditions: "sunny" };
          },
        },
      ],
    });

    const result = await agent.run("What is the weather in San Francisco?");
    return new Response(JSON.stringify(result));
  },
};

AI Search (RAG)

Use Cases: Build retrieval-augmented generation applications

import { VectorizeIndex } from "@cloudflare/workers-types";

export default {
  async fetch(request: Request, env: Env) {
    // Generate embeddings
    const embeddings = await env.AI.run("@cf/baai/bge-base-en-v1.5", {
      text: query,
    });

    // Search vector database
    const results = await env.VECTORIZE_INDEX.query(embeddings.data[0], {
      topK: 5,
    });

    // Generate response with context
    const response = await env.AI.run("@cf/meta/llama-3-8b-instruct", {
      messages: [
        {
          role: "system",
          content: `Context: ${results.matches.map((m) => m.metadata.text).join("\n")}`,
        },
        { role: "user", content: query },
      ],
    });

    return new Response(JSON.stringify(response));
  },
};

Cloudflare Pages

Static Sites + Serverless Functions

Deployment:

# Deploy via Git (recommended)
# Connect GitHub repo in Cloudflare dashboard

# Or deploy via CLI
wrangler pages deploy ./dist

Pages Functions

Directory-based routing in functions/:

functions/
├── api/
│   ├── users/
│   │   └── [id].ts       # /api/users/:id
│   └── posts.ts          # /api/posts
└── _middleware.ts        # Global middleware

Example Function:

// functions/api/users/[id].ts
export async function onRequestGet(context) {
  const { params, env } = context;
  const user = await env.DB.prepare("SELECT * FROM users WHERE id = ?")
    .bind(params.id)
    .first();

  return new Response(JSON.stringify(user), {
    headers: { "Content-Type": "application/json" },
  });
}

Middleware:

// functions/_middleware.ts
export async function onRequest(context) {
  const start = Date.now();
  const response = await context.next();
  const duration = Date.now() - start;

  console.log(
    `${context.request.method} ${context.request.url} - ${duration}ms`,
  );
  return response;
}

Framework Support

Next.js:

npx create-next-app@latest my-app
cd my-app
npm install -D @cloudflare/next-on-pages
npx @cloudflare/next-on-pages
wrangler pages deploy .vercel/output/static

Remix:

npx create-remix@latest --template cloudflare/remix

Astro:

npm create astro@latest
# Select "Cloudflare" adapter during setup

SvelteKit:

npm create svelte@latest
npm install -D @sveltejs/adapter-cloudflare

Wrangler CLI Essentials

Core Commands

# Development
wrangler dev                    # Local development server
wrangler dev --remote          # Dev on real Cloudflare infrastructure

# Deployment
wrangler deploy                # Deploy to production
wrangler deploy --dry-run     # Preview changes without deploying

# Logs
wrangler tail                  # Real-time logs
wrangler tail --format pretty # Formatted logs

# Versions
wrangler deployments list      # List deployments
wrangler rollback [version]   # Rollback to previous version

# Secrets
wrangler secret put SECRET_NAME    # Add secret
wrangler secret list               # List secrets
wrangler secret delete SECRET_NAME # Delete secret

Project Management

# Create projects
wrangler init my-worker        # Create Worker
wrangler pages project create  # Create Pages project

# Database
wrangler d1 create my-db           # Create D1 database
wrangler d1 execute my-db --file=schema.sql
wrangler d1 execute my-db --command="SELECT * FROM users"

# KV
wrangler kv:namespace create MY_KV
wrangler kv:key put --binding=MY_KV "key" "value"
wrangler kv:key get --binding=MY_KV "key"

# R2
wrangler r2 bucket create my-bucket
wrangler r2 object put my-bucket/file.txt --file=./file.txt

Integration Patterns

Full-Stack Application Architecture

┌─────────────────────────────────────────┐
│         Cloudflare Pages (Frontend)      │
│    Next.js / Remix / Astro / SvelteKit  │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│      Workers (API Layer / BFF)          │
│    - Routing                             │
│    - Authentication                      │
│    - Business logic                      │
└─┬──────┬──────┬──────┬──────┬───────────┘
  │      │      │      │      │
  ▼      ▼      ▼      ▼      ▼
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────────────┐
│ D1 │ │ KV │ │ R2 │ │ DO │ │ Workers AI │
└────┘ └────┘ └────┘ └────┘ └────────────┘

Polyglot Storage Pattern

export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    // KV: Fast cache
    const cached = await env.KV.get(url.pathname);
    if (cached) return new Response(cached);

    // D1: Structured data
    const user = await env.DB.prepare("SELECT * FROM users WHERE id = ?")
      .bind(userId)
      .first();

    // R2: Media files
    const avatar = await env.R2_BUCKET.get(`avatars/${user.id}.jpg`);

    // Durable Objects: Real-time coordination
    const chat = env.CHAT_ROOM.get(env.CHAT_ROOM.idFromName(roomId));

    // Queue: Async processing
    await env.EMAIL_QUEUE.send({ to: user.email, template: "welcome" });

    return new Response(JSON.stringify({ user, avatar }));
  },
};

Authentication Pattern

import { verifyJWT, createJWT } from "./jwt";

export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    // Login
    if (url.pathname === "/api/login") {
      const { email, password } = await request.json();

      const user = await env.DB.prepare("SELECT * FROM users WHERE email = ?")
        .bind(email)
        .first();

      if (!user || !(await verifyPassword(password, user.password_hash))) {
        return new Response("Invalid credentials", { status: 401 });
      }

      const token = await createJWT({ userId: user.id }, env.JWT_SECRET);

      return new Response(JSON.stringify({ token }), {
        headers: { "Content-Type": "application/json" },
      });
    }

    // Protected route
    const authHeader = request.headers.get("Authorization");
    if (!authHeader) {
      return new Response("Unauthorized", { status: 401 });
    }

    const token = authHeader.replace("Bearer ", "");
    const payload = await verifyJWT(token, env.JWT_SECRET);

    // Store session in KV
    await env.KV.put(`session:${payload.userId}`, JSON.stringify(payload), {
      expirationTtl: 86400, // 24 hours
    });

    return new Response("Authenticated");
  },
};

Cache Strategy

export default {
  async fetch(request: Request, env: Env) {
    const cache = caches.default;
    const cacheKey = new Request(request.url);

    // Check cache
    let response = await cache.match(cacheKey);
    if (response) return response;

    // Check KV (distributed cache)
    const kvCached = await env.KV.get(request.url);
    if (kvCached) {
      response = new Response(kvCached);
      await cache.put(cacheKey, response.clone());
      return response;
    }

    // Fetch from origin (D1, R2, etc.)
    const data = await fetchFromOrigin(request, env);
    response = new Response(data);

    // Store in both caches
    await cache.put(cacheKey, response.clone());
    await env.KV.put(request.url, data, { expirationTtl: 3600 });

    return response;
  },
};

Best Practices

Performance

  1. Minimize Cold Starts: Keep Workers lightweight (<1MB bundled)
  2. Use Bindings Over Fetch: Direct bindings are faster than HTTP calls
  3. Edge Caching: Leverage KV and Cache API for frequently accessed data
  4. Batch Operations: Use D1 batch for multiple queries
  5. Stream Large Responses: Use Response.body streams for large files

Security

  1. Secrets Management: Use wrangler secret for API keys
  2. Environment Isolation: Separate production/staging/development
  3. Input Validation: Sanitize user input
  4. Rate Limiting: Use KV or Durable Objects for rate limiting
  5. CORS: Configure proper CORS headers

Cost Optimization

  1. R2 for Large Files: Zero egress fees vs S3
  2. KV for Caching: Reduce D1/R2 requests
  3. Request Deduplication: Cache identical requests
  4. Efficient Queries: Index D1 tables properly
  5. Monitor Usage: Use Cloudflare Analytics

Development Workflow

  1. Local Development: Use wrangler dev for testing
  2. Type Safety: Use TypeScript with @cloudflare/workers-types
  3. Testing: Use Vitest with unstable_dev()
  4. CI/CD: GitHub Actions with cloudflare/wrangler-action
  5. Gradual Deployments: Use percentage-based rollouts

Common Patterns

API Gateway

import { Hono } from "hono";

const app = new Hono();

app.get("/api/users/:id", async (c) => {
  const user = await c.env.DB.prepare("SELECT * FROM users WHERE id = ?")
    .bind(c.req.param("id"))
    .first();

  return c.json(user);
});

app.post("/api/users", async (c) => {
  const { name, email } = await c.req.json();

  await c.env.DB.prepare("INSERT INTO users (name, email) VALUES (?, ?)")
    .bind(name, email)
    .run();

  return c.json({ success: true }, 201);
});

export default app;

Image Transformation

export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);
    const imageKey = url.pathname.replace("/images/", "");

    // Get from R2
    const object = await env.R2_BUCKET.get(imageKey);
    if (!object) {
      return new Response("Not found", { status: 404 });
    }

    // Transform with Cloudflare Images
    return new Response(object.body, {
      headers: {
        "Content-Type": object.httpMetadata?.contentType || "image/jpeg",
        "Cache-Control": "public, max-age=86400",
        "cf-image-resize": JSON.stringify({
          width: 800,
          height: 600,
          fit: "cover",
        }),
      },
    });
  },
};

Rate Limiting (KV)

async function rateLimit(ip: string, env: Env): Promise<boolean> {
  const key = `ratelimit:${ip}`;
  const limit = 100; // requests per minute
  const window = 60; // seconds

  const current = await env.KV.get(key);
  const count = current ? parseInt(current) : 0;

  if (count >= limit) {
    return false; // Rate limit exceeded
  }

  await env.KV.put(key, (count + 1).toString(), {
    expirationTtl: window,
  });

  return true;
}

export default {
  async fetch(request: Request, env: Env) {
    const ip = request.headers.get("CF-Connecting-IP") || "unknown";

    if (!(await rateLimit(ip, env))) {
      return new Response("Rate limit exceeded", { status: 429 });
    }

    return new Response("OK");
  },
};

Scheduled Jobs

# wrangler.toml
[triggers]
crons = ["0 0 * * *"] # Daily at midnight
export default {
  async scheduled(event: ScheduledEvent, env: Env) {
    // Cleanup old sessions
    const sessions = await env.KV.list({ prefix: "session:" });
    for (const key of sessions.keys) {
      const session = await env.KV.get(key.name, "json");
      if (session.expiresAt < Date.now()) {
        await env.KV.delete(key.name);
      }
    }
  },
};

Troubleshooting

Common Issues

"Module not found" errors

  • Ensure dependencies are in package.json
  • Run npm install before deploying
  • Check compatibility_date in wrangler.toml

Database connection errors (D1)

  • Verify database_id in wrangler.toml
  • Check database exists: wrangler d1 list
  • Run migrations: wrangler d1 execute DB --file=schema.sql

KV not found errors

  • Create namespace: wrangler kv:namespace create MY_KV
  • Add binding to wrangler.toml
  • Deploy after configuration changes

Cold start timeout

  • Reduce bundle size (<1MB ideal)
  • Remove unnecessary dependencies
  • Use dynamic imports for large libraries

CORS errors

  • Add CORS headers to responses:
    return new Response(data, {
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
        "Access-Control-Allow-Headers": "Content-Type",
      },
    });
    

Deployment fails

  • Check wrangler version: wrangler --version
  • Verify authentication: wrangler whoami
  • Review build errors in console output

Debugging

# Real-time logs
wrangler tail

# Local debugging with breakpoints
wrangler dev --local

# Remote debugging
wrangler dev --remote

# Check deployment status
wrangler deployments list

Decision Matrix

NeedChoose
Sub-millisecond readsKV
SQL queriesD1
Large files (>25MB)R2
Real-time WebSocketsDurable Objects
Async background jobsQueues
ACID transactionsD1
Strong consistencyDurable Objects
Zero egress costsR2
AI inferenceWorkers AI
Static site hostingPages
Serverless functionsWorkers
Multi-provider AIAI Gateway

Framework-Specific Guides

Next.js

  • Use @cloudflare/next-on-pages adapter
  • Configure next.config.js for edge runtime
  • Deploy via wrangler pages deploy

Remix

  • Use official Cloudflare template
  • Configure server.ts for Workers
  • Access bindings via context.cloudflare.env

Astro

  • Use @astrojs/cloudflare adapter
  • Enable SSR in astro.config.mjs
  • Access env via Astro.locals.runtime.env

SvelteKit

  • Use @sveltejs/adapter-cloudflare
  • Configure in svelte.config.js
  • Access platform via event.platform.env

Resources

Implementation Checklist

Workers Setup

  • Install Wrangler CLI (npm install -g wrangler)
  • Login to Cloudflare (wrangler login)
  • Create project (wrangler init)
  • Configure wrangler.toml
  • Add environment variables/secrets
  • Test locally (wrangler dev)
  • Deploy (wrangler deploy)

Storage Setup (as needed)

  • Create D1 database and apply schema
  • Create KV namespace
  • Create R2 bucket
  • Configure Durable Objects
  • Set up Queues
  • Add bindings to wrangler.toml

Pages Setup

  • Connect Git repository or use CLI
  • Configure build settings
  • Set environment variables
  • Add Pages Functions (if needed)
  • Deploy and test

Production Checklist

  • Set up custom domain
  • Configure DNS records
  • Enable SSL/TLS
  • Set up monitoring/analytics
  • Configure rate limiting
  • Implement error handling
  • Set up CI/CD pipeline
  • Test gradual deployments
  • Document rollback procedure
  • Configure logging/observability

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です