Communitygithub.com

コーディング規約・ベストプラクティス

命名、可読性、不変性、コード品質レビューに関するプロジェクト横断的なコーディング規約です。フレームワーク固有のパターンについては、フロントエンドまたはバックエンドの詳細スキルを使用してください。コードレビュー時や命名規則の確認時に、該当するフレームワーク固有のスキルがない場合に利用します。

コーディング規約・ベストプラクティス とは?

このスキルは、プロジェクト全体で一貫したコーディング品質を確保するための基本ルールを提供します。命名規則、可読性、KISS/DRY/YAGNI原則、不変性パターン、エラーハンドリング、TypeScript/JavaScriptの型安全性など、あらゆるコードベースに適用可能な普遍的なプラクティスをカバーしています。Reactのコンポーネント構造やカスタムフック、API設計、ファイル構成、テスト標準など、モダンなWeb開発に必要な具体的なコード例も含まれており、開発者がすぐに実践できるようになっています。コードレビューや新規プロジェクトの開始時、リファクタリング時など、様々な場面でアクティベートできます。ただし、Reactのコンポジションやフックパターン、バックエンドアーキテクチャなど、フレームワーク固有の詳細なガイダンスが必要な場合は、より特化したスキル(frontend-patterns、backend-patterns、api-designなど)を優先して使用すべきです。このスキルは、あくまで共通のベースラインとして機能し、特定のフレームワークやドメインに対応するスキルが存在する場合には、そちらを優先するよう設計されています。

対応~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/coding-standards

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

コーディング規約・ベストプラクティス は何をしますか?

プロジェクト横断的に適用可能なベースラインのコーディング規約です。

このスキルは共通の基盤であり、詳細なフレームワークのプレイブックではありません。

  • React、状態管理、フォーム、レンダリング、UIアーキテクチャには frontend-patterns を使用してください。
  • リポジトリ/サービス層、エンドポイント設計、バリデーション、サーバー固有の考慮事項には backend-patterns または api-design を使用してください。
  • フルスキルのウォークスルーではなく、最も短い再利用可能なルールが必要な場合は rules/common/coding-style.md を使用してください。

アクティベートすべきタイミング

  • 新しいプロジェクトやモジュールを開始するとき
  • コードの品質と保守性をレビューするとき
  • 既存のコードを規約に従ってリファクタリングするとき
  • 命名、フォーマット、構造の一貫性を強制するとき
  • リンター、フォーマッター、型チェックのルールを設定するとき
  • 新しいコントリビューターをコーディング規約にオンボーディングするとき

スコープの境界

このスキルは以下の場合にアクティベートします:

  • 説明的な命名
  • 不変性のデフォルト
  • 可読性、KISS、DRY、YAGNIの強制
  • エラーハンドリングの期待値とコードスメルレビュー

このスキルを主な情報源として使用すべきでない場合:

  • Reactのコンポジション、フック、レンダリングパターン
  • バックエンドアーキテクチャ、API設計、データベースレイヤリング
  • より狭い範囲のECCスキルがすでに存在する場合のドメイン固有フレームワークガイダンス

コード品質の原則

1. 可読性第一

  • コードは書かれるよりも読まれる
  • 明確な変数名と関数名
  • コメントよりも自己文書化コード
  • 一貫性のあるフォーマット

2. KISS(Keep It Simple, Stupid)

  • 動作する最もシンプルな解決策
  • 過剰エンジニアリングを避ける
  • 時期尚早な最適化はしない
  • 理解しやすさ > 巧妙なコード

3. DRY(Don't Repeat Yourself)

  • 共通ロジックを関数に抽出する
  • 再利用可能なコンポーネントを作成する
  • モジュール間でユーティリティを共有する
  • コピーペーストプログラミングを避ける

4. YAGNI(You Aren't Gonna Need It)

  • 必要になる前に機能を作らない
  • 投機的な汎用性を避ける
  • 必要な場合にのみ複雑さを追加する
  • シンプルに始め、必要に応じてリファクタリングする

TypeScript/JavaScript 標準

変数命名

// PASS: GOOD: 説明的な名前
const marketSearchQuery = 'election'
const isUserAuthenticated = true
const totalRevenue = 1000

// FAIL: BAD: 不明瞭な名前
const q = 'election'
const flag = true
const x = 1000

関数命名

// PASS: GOOD: 動詞-名詞パターン
async function fetchMarketData(marketId: string) { }
function calculateSimilarity(a: number[], b: number[]) { }
function isValidEmail(email: string): boolean { }

// FAIL: BAD: 不明瞭または名詞のみ
async function market(id: string) { }
function similarity(a, b) { }
function email(e) { }

不変性パターン(重要)

// PASS: ALWAYS use spread operator
const updatedUser = {
  ...user,
  name: 'New Name'
}

const updatedArray = [...items, newItem]

// FAIL: NEVER mutate directly
user.name = 'New Name'  // BAD
items.push(newItem)     // BAD

エラーハンドリング

// PASS: GOOD: 包括的なエラーハンドリング
async function fetchData(url: string) {
  try {
    const response = await fetch(url)

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }

    return await response.json()
  } catch (error) {
    console.error('Fetch failed:', error)
    throw new Error('Failed to fetch data')
  }
}

// FAIL: BAD: エラーハンドリングなし
async function fetchData(url) {
  const response = await fetch(url)
  return response.json()
}

Async/Await ベストプラクティス

// PASS: GOOD: 可能な限り並列実行
const [users, markets, stats] = await Promise.all([
  fetchUsers(),
  fetchMarkets(),
  fetchStats()
])

// FAIL: BAD: 不要な逐次実行
const users = await fetchUsers()
const markets = await fetchMarkets()
const stats = await fetchStats()

型安全性

// PASS: GOOD: 適切な型
interface Market {
  id: string
  name: string
  status: 'active' | 'resolved' | 'closed'
  created_at: Date
}

function getMarket(id: string): Promise<Market> {
  // Implementation
}

// FAIL: BAD: 'any' の使用
function getMarket(id: any): Promise<any> {
  // Implementation
}

React ベストプラクティス

コンポーネント構造

// PASS: GOOD: 型を持つ関数コンポーネント
interface ButtonProps {
  children: React.ReactNode
  onClick: () => void
  disabled?: boolean
  variant?: 'primary' | 'secondary'
}

export function Button({
  children,
  onClick,
  disabled = false,
  variant = 'primary'
}: ButtonProps) {
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={`btn btn-${variant}`}
    >
      {children}
    </button>
  )
}

// FAIL: BAD: 型なし、不明瞭な構造
export function Button(props) {
  return <button onClick={props.onClick}>{props.children}</button>
}

カスタムフック

// PASS: GOOD: 再利用可能なカスタムフック
export function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value)

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value)
    }, delay)

    return () => clearTimeout(handler)
  }, [value, delay])

  return debouncedValue
}

// Usage
const debouncedQuery = useDebounce(searchQuery, 500)

状態管理

// PASS: GOOD: 適切な状態更新
const [count, setCount] = useState(0)

// 前の状態に基づく関数型更新
setCount(prev => prev + 1)

// FAIL: BAD: 直接的な状態参照
setCount(count + 1)  // 非同期シナリオでは古くなる可能性がある

条件付きレンダリング

// PASS: GOOD: 明確な条件付きレンダリング
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
{data && <DataDisplay data={data} />}

// FAIL: BAD: 三項演算子の混乱
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}

API設計標準

REST API 規約

GET    /api/markets              # 全マーケットを取得
GET    /api/markets/:id          # 特定のマーケットを取得
POST   /api/markets              # 新しいマーケットを作成
PUT    /api/markets/:id          # マーケットを更新(全体)
PATCH  /api/markets/:id          # マーケットを更新(部分)
DELETE /api/markets/:id          # マーケットを削除

# フィルタリング用クエリパラメータ
GET /api/markets?status=active&limit=10&offset=0

レスポンス形式

// PASS: GOOD: 一貫性のあるレスポンス構造
interface ApiResponse<T> {
  success: boolean
  data?: T
  error?: string
  meta?: {
    total: number
    page: number
    limit: number
  }
}

// Success response
return NextResponse.json({
  success: true,
  data: markets,
  meta: { total: 100, page: 1, limit: 10 }
})

// Error response
return NextResponse.json({
  success: false,
  error: 'Invalid request'
}, { status: 400 })

入力バリデーション

import { z } from 'zod'

// PASS: GOOD: スキーマバリデーション
const CreateMarketSchema = z.object({
  name: z.string().min(1).max(200),
  description: z.string().min(1).max(2000),
  endDate: z.string().datetime(),
  categories: z.array(z.string()).min(1)
})

export async function POST(request: Request) {
  const body = await request.json()

  try {
    const validated = CreateMarketSchema.parse(body)
    // Proceed with validated data
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json({
        success: false,
        error: 'Validation failed',
        details: error.issues
      }, { status: 400 })
    }
  }
}

ファイル構成

プロジェクト構造

src/
├── app/                    # Next.js App Router
│   ├── api/               # API ルート
│   ├── markets/           # マーケットページ
│   └── (auth)/           # 認証ページ(ルートグループ)
├── components/            # React コンポーネント
│   ├── ui/               # 汎用UIコンポーネント
│   ├── forms/            # フォームコンポーネント
│   └── layouts/          # レイアウトコンポーネント
├── hooks/                # カスタム React フック
├── lib/                  # ユーティリティと設定
│   ├── api/             # API クライアント
│   ├── utils/           # ヘルパー関数
│   └── constants/       # 定数
├── types/                # TypeScript 型
└── styles/              # グローバルスタイル

ファイル命名

components/Button.tsx          # コンポーネントはパスカルケース
hooks/useAuth.ts              # 'use' プレフィックス付きキャメルケース
lib/formatDate.ts             # ユーティリティはキャメルケース
types/market.types.ts         # キャメルケース + .types サフィックス

コメントとドキュメント

コメントを書くべき時

// PASS: GOOD: 「何を」ではなく「なぜ」を説明する
// 障害発生時にAPIへの負荷を避けるため、指数バックオフを使用
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)

// 大規模配列でのパフォーマンスのために、意図的にミューテーションを使用
items.push(newItem)

// FAIL: BAD: 自明なことを述べている
// カウンターを1増やす
count++

// 名前をユーザー名に設定
name = user.name

公開APIのJSDoc

/**
 * セマンティック類似性を使用してマーケットを検索します。
 *
 * @param query - 自然言語による検索クエリ
 * @param limit - 結果の最大数(デフォルト: 10)
 * @returns 類似度スコアでソートされたマーケットの配列
 * @throws {Error} OpenAI API が失敗した場合、または Redis が利用不可の場合
 *
 * @example
 * ```typescript
 * const results = await searchMarkets('election', 5)
 * console.log(results[0].name) // "Trump vs Biden"
 * ```
 */
export async function searchMarkets(
  query: string,
  limit: number = 10
): Promise<Market[]> {
  // Implementation
}

パフォーマンスベストプラクティス

メモ化

import { useMemo, useCallback } from 'react'

// PASS: GOOD: 高コストな計算をメモ化
// ソート前にコピー - Array.prototype.sort は元の配列を変更する
const sortedMarkets = useMemo(() => {
  return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets])

// PASS: GOOD: コールバックをメモ化
const handleSearch = useCallback((query: string) => {
  setSearchQuery(query)
}, [])

レイジーローディング

import { lazy, Suspense } from 'react'

// PASS: GOOD: 重いコンポーネントをレイジーロード
const HeavyChart = lazy(() => import('./HeavyChart'))

export function Dashboard() {
  return (
    <Suspense fallback={<Spinner />}>
      <HeavyChart />
    </Suspense>
  )
}

データベースクエリ

// PASS: GOOD: 必要なカラムのみ選択
const { data } = await supabase
  .from('markets')
  .select('id, name, status')
  .limit(10)

// FAIL: BAD: すべてを選択
const { data } = await supabase
  .from('markets')
  .select('*')

テスト標準

テスト構造(AAAパターン)

test('類似度を正しく計算する', () => {
  // Arrange
  const vector1 = [1, 0, 0]
  const vector2 = [0, 1, 0]

  // Act
  const similarity = calculateCosineSimilarity(vector1, vector2)

  // Assert
  expect(similarity).toBe(0)
})

テスト命名

// PASS: GOOD: 説明的なテスト名
test('クエリに一致するマーケットがない場合、空の配列を返す', () => { })
test('OpenAI APIキーがない場合はエラーをスローする', () => { })
test('Redisが利用不可の場合、部分文字列検索にフォールバックする', () => { })

// FAIL: BAD: 曖昧なテスト名
test('動作する', () => { })
test('検索をテスト', () => { })

コードスメル検出

以下のアンチパターンに注意してください:

1. 長い関数

// FAIL: BAD: 50行を超える関数
function processMarketData() {
  // 100行のコード
}

// PASS: GOOD: 小さな関数に分割
function processMarketData() {
  const validated = validateData()
  const transformed = transformData(validated)
  return saveData(transformed)
}

2. 深いネスト

// FAIL: BAD: 5レベル以上のネスト
if (user) {
  if (user.isAdmin) {
    if (market) {
      if (market.isActive) {
        if (hasPermission) {
          // 何かを行う
        }
      }
    }
  }
}

// PASS: GOOD: 早期リターン
if (!user) return
if (!user.isAdmin) return
if (!market) return
if (!market.isActive) return
if (!hasPermission) return

// 何かを行う

3. マジックナンバー

// FAIL: BAD: 説明のない数値
if (retryCount > 3) { }
setTimeout(callback, 500)

// PASS: GOOD: 名前付き定数
const MAX_RETRIES = 3
const DEBOUNCE_DELAY_MS = 500

if (retryCount > MAX_RETRIES) { }
setTimeout(callback, DEBOUNCE_DELAY_MS)

注意: コード品質は交渉の余地がありません。明確で保守可能なコードは、迅速な開発と自信を持ったリファクタリングを可能にします。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

関連スキル