mcpField
B
backend-dev-guidelines

backend-dev-guidelines

github.com/ovachiever開発5654 回インストール49 週間前に更新
リポジトリ

backend-dev-guidelines について

Langfuseのweb、worker、sharedパッケージ向けに、バックエンド開発の指針をまとめたスキルです。ルーティング、サービス層、データアクセス、検証、可観測性、テストの実装パターンを扱います。

主な機能

  1. 01tRPCとREST APIの規約
  2. 02BullMQワーカーのパターン
  3. 03サービス層とリポジトリの分離
  4. 04Zodによる入力検証
  5. 05データベースの分離とアクセス
  6. 06可観測性とテストの指針

活用シーン

  1. 01tRPC機能や公開エンドポイントの追加
  2. 02BullMQキュープロセッサーの実装
  3. 03データベースやサービスロジックの変更
  4. 04バックエンド機能や修正のテスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ovachiever/droid-tings --skill backend-dev-guidelines

インストール後、Claude Code で/backend-dev-guidelinesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

resources/
architecture-overview.md
configuration.md
database-patterns.md
middleware-guide.md
routing-and-controllers.md
services-and-repositories.md
testing-guide.md

詳細

バックエンド開発ガイドライン

目的

Next.js 14、tRPC、BullMQ、TypeScript のパターンを使用する Langfuse のバックエンドパッケージ(web、worker、packages/shared)全体で、一貫性とベストプラクティスを確立します。

このスキルを使用するタイミング

以下の作業時に自動的に有効になります。

  • tRPC ルーターとプロシージャの作成または変更
  • パブリック API エンドポイント(REST)の作成または変更
  • BullMQ キューのコンシューマーとプロデューサーの作成または変更
  • ビジネスロジックを含むサービスの構築
  • API リクエストの認証
  • エンタイトルメントに基づくリソースへのアクセス
  • ミドルウェア(tRPC、NextAuth、パブリック API)の実装
  • Prisma(PostgreSQL)または ClickHouse を使用したデータベース操作
  • OpenTelemetry、DataDog、logger、traceException を使用したオブザーバビリティ
  • Zod v4 による入力検証
  • 環境変数による環境設定
  • バックエンドのテストとリファクタリング

クイックスタート

UI:新しい tRPC 機能のチェックリスト(Web)
  • ルーター:features/[feature]/server/*Router.ts に定義します
  • プロシージャ:適切なプロシージャタイプ(protected、public)を使用します
  • 認証:ミドルウェアを介して JWT 認可を使用します。
  • エンタイトルメントの確認:リソースとロールに基づいてリソースにアクセスします
  • 検証:入力用の Zod v4 スキーマ
  • サービス:サービスファイルにビジネスロジックを記述します
  • エラー処理:traceException ラッパーを使用します
  • テスト:__tests__/ に単体テストと統合テストを作成します
  • 設定:env.mjs 経由でアクセスします
SDK:新しいパブリック API エンドポイントのチェックリスト(Web)
  • ルートファイル:pages/api/public/ に作成します
  • ラッパー:withMiddlewares と createAuthedProjectAPIRoute を使用します
  • 型:features/public-api/types/ に定義します
  • 認証:Basic 認証による認可
  • 検証:クエリ/ボディ/レスポンス用の Zod スキーマ
  • バージョン管理:API パスと、クエリ/ボディ/レスポンス用の Zod スキーマでバージョンを管理します
  • テスト:__tests__/async/ にエンドツーエンドテストを追加します
新しいキュープロセッサーのチェックリスト(Worker)
  • プロセッサー:worker/src/queues/ に作成します
  • キューの型:packages/shared/src/server/queues にキューの型を作成します
  • サービス:features/ または worker/src/features/ にビジネスロジックを記述します
  • エラー処理:キュー処理を失敗させるエラーと、成功イベントにつながるエラーを区別します。
  • キューの登録:app.ts の WorkerManager に追加します
  • テスト:worker に vitest テストを追加します

アーキテクチャの概要

階層型アーキテクチャ
# Web Package (Next.js 14)

┌─ tRPC API ──────────────────┐   ┌── Public REST API ──────────┐
│                             │   │                             │
│  HTTP Request               │   │  HTTP Request               │
│      ↓                      │   │      ↓                      │
│  tRPC Procedure             │   │  withMiddlewares +          │
│  (protectedProjectProcedure)│   │  createAuthedProjectAPIRoute│
│      ↓                      │   │      ↓                      │
│  Service (business logic)   │   │  Service (business logic)   │
│      ↓                      │   │      ↓                      │
│  Prisma / ClickHouse        │   │  Prisma / ClickHouse        │
│                             │   │                             │
└─────────────────────────────┘   └─────────────────────────────┘
                 ↓
            [optional]: Publish to Redis BullMQ queue
                 ↓
┌─ Worker Package (Express) ──────────────────────────────────┐
│                                                             │
│  BullMQ Queue Job                                           │
│      ↓                                                      │
│  Queue Processor (handles job)                              │
│      ↓                                                      │
│  Service (business logic)                                   │
│      ↓                                                      │
│  Prisma / ClickHouse                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

主な原則:

  • Web:UI 用の tRPC プロシージャ、または SDK 用のパブリック API ルート → サービス → データベース
  • Worker:キュープロセッサー → サービス → データベース
  • packages/shared:Web と Worker の共有コード

詳しくは、architecture-overview.md を参照してください。


ディレクトリ構成

Web パッケージ(/web/)
web/src/
├── features/                # Feature-organized code
│   ├── [feature-name]/
│   │   ├── server/          # Backend logic
│   │   │   ├── *Router.ts   # tRPC router
│   │   │   └── service.ts   # Business logic
│   │   ├── components/      # React components
│   │   └── types/           # Feature types
├── server/
│   ├── api/
│   │   ├── routers/         # tRPC routers
│   │   ├── trpc.ts          # tRPC setup & middleware
│   │   └── root.ts          # Main router
│   ├── auth.ts              # NextAuth.js config
│   └── db.ts                # Database client
├── pages/
│   ├── api/
│   │   ├── public/          # Public REST APIs
│   │   └── trpc/            # tRPC endpoint
│   └── [routes].tsx         # Next.js pages
├── __tests__/               # Jest tests
│   └── async/               # Integration tests
├── instrumentation.ts       # OpenTelemetry (FIRST IMPORT)
└── env.mjs                  # Environment config
Worker パッケージ(/worker/)
worker/src/
├── queues/                  # BullMQ processors
│   ├── evalQueue.ts
│   ├── ingestionQueue.ts
│   └── workerManager.ts
├── features/                # Business logic
│   └── [feature]/
│       └── service.ts
├── instrumentation.ts       # OpenTelemetry (FIRST IMPORT)
├── app.ts                   # Express setup + queue registration
├── env.ts                   # Environment config
└── index.ts                 # Server start
共有パッケージ(/packages/shared/)
shared/src/
├── server/                  # Server utilities
│   ├── auth/                # Authentication helpers
│   ├── clickhouse/          # ClickHouse client & schema
│   ├── instrumentation/     # OpenTelemetry helpers
│   ├── llm/                 # LLM integration utilities
│   ├── redis/               # Redis queues & cache
│   ├── repositories/        # Data repositories
│   ├── services/            # Shared services
│   ├── utils/               # Server utilities
│   ├── logger.ts
│   └── queues.ts
├── encryption/              # Encryption utilities
├── features/                # Feature-specific code
├── tableDefinitions/        # Table schemas
├── utils/                   # Shared utilities
├── constants.ts
├── db.ts                    # Prisma client
├── env.ts                   # Environment config
└── index.ts                 # Main exports

インポートパス(package.json の exports):

共有パッケージでは、用途別に特定のインポートパスを公開しています。

インポートパス対応先用途
@langfuse/shareddist/src/index.js一般的な型、スキーマ、ユーティリティ、定数
@langfuse/shared/src/dbdist/src/db.jsPrisma クライアントとデータベースの型
@langfuse/shared/src/serverdist/src/server/index.jsサーバー側のユーティリティ(キュー、認証、サービス、計装)
@langfuse/shared/src/server/auth/apiKeysdist/src/server/auth/apiKeys.jsAPI キー管理ユーティリティ
@langfuse/shared/encryptiondist/src/encryption/index.js暗号化と署名のユーティリティ

使用例:

// General imports - types, schemas, constants, interfaces
import {
  CloudConfigSchema,
  StringNoHTML,
  AnnotationQueueObjectType,
  type APIScoreV2,
  type ColumnDefinition,
  Role,
} from "@langfuse/shared";

// Database - Prisma client and types
import { prisma, Prisma, JobExecutionStatus } from "@langfuse/shared/src/db";
import { type DB as Database } from "@langfuse/shared";

// Server utilities - queues, services, auth, instrumentation
import {
  logger,
  instrumentAsync,
  traceException,
  redis,
  getTracesTable,
  StorageService,
  sendMembershipInvitationEmail,
  invalidateApiKeysForProject,
  recordIncrement,
  recordHistogram,
} from "@langfuse/shared/src/server";

// API key management (specific path)
import { createAndAddApiKeysToDb } from "@langfuse/shared/src/server/auth/apiKeys";

// Encryption utilities
import { encrypt, decrypt, sign, verify } from "@langfuse/shared/encryption";

配置先:

共有パッケージは、ウェブパッケージとワーカーパッケージの両方で使用する型、ユーティリティ、サーバーコードを提供します。フロントエンドとバックエンドのアクセスを制御する5 つのエクスポートパスがあります。

インポートパス使用方法含まれるもの
@langfuse/shared✅ フロントエンド+バックエンドPrisma の型、Zod スキーマ、定数、テーブル定義、ドメインモデル、ユーティリティ
@langfuse/shared/src/db🔒 バックエンドのみPrisma クライアントインスタンス
@langfuse/shared/src/server🔒 バックエンドのみサービス、リポジトリ、キュー、認証、ClickHouse、LLM 統合、計装
@langfuse/shared/src/server/auth/apiKeys🔒 バックエンドのみAPI キー管理(循環依存を避けるため分離)
@langfuse/shared/encryption🔒 バックエンドのみデータベースフィールドの暗号化/復号

命名規則:

  • tRPC ルーター:camelCaseRouter.ts - datasetRouter.ts
  • サービス:機能ディレクトリ内の service.ts
  • キュープロセッサー:camelCaseQueue.ts - evalQueue.ts
  • 公開 API:kebab-case.ts - dataset-items.ts

コア原則

1. tRPC プロシージャはサービスに処理を委譲します
// ❌ NEVER: Business logic in procedures
export const traceRouter = createTRPCRouter({
  byId: protectedProjectProcedure
    .input(z.object({ traceId: z.string() }))
    .query(async ({ input, ctx }) => {
      // 200 lines of logic here
    }),
});

// ✅ ALWAYS: Delegate to service
export const traceRouter = createTRPCRouter({
  byId: protectedProjectProcedure
    .input(z.object({ traceId: z.string() }))
    .query(async ({ input, ctx }) => {
      return await getTraceById(input.traceId);
    }),
});
2. 設定には env.mjs 経由でアクセスし、process.env は絶対に使用しないでください
// ❌ NEVER (except in env.mjs itself)
const dbUrl = process.env.DATABASE_URL;

// ✅ ALWAYS
import { env } from "@/src/env.mjs";
const dbUrl = env.DATABASE_URL;
3. すべての入力を Zod v4 で検証します
import { z } from "zod/v4";

const schema = z.object({
  email: z.string().email(),
  projectId: z.string(),
});
const validated = schema.parse(input);
4. サービスでは、単純な CRUD には Prisma を直接使用し、複雑なクエリにはリポジトリを使用します
// Services use Prisma directly for simple CRUD
import { prisma } from "@langfuse/shared/src/db";

const dataset = await prisma.dataset.findUnique({
  where: { id: datasetId, projectId }, // Always filter by projectId for tenant isolation
});

// Or use repositories for complex queries (traces, observations, scores)
import { getTracesTable } from "@langfuse/shared/src/server";

const traces = await getTracesTable({
  projectId,
  filter: [...],
  limit: 1000,
});
6. 可観測性:OpenTelemetry + DataDog(バックエンドでは Sentry を使用しない)

Langfuse はバックエンドの可観測性に OpenTelemetry を使用し、トレースとログを DataDog に送信します。

// Import observability utilities
import {
  logger,          // Winston logger with OpenTelemetry/DataDog context
  traceException,  // Record exceptions to OpenTelemetry spans
  instrumentAsync, // Create instrumented spans
} from "@langfuse/shared/src/server";

// Structured logging (includes trace_id, span_id, dd.trace_id)
logger.info("Processing dataset", { datasetId, projectId });
logger.error("Failed to create dataset", { error: err.message });

// Record exceptions to OpenTelemetry (sent to DataDog)
try {
  await operation();
} catch (error) {
  traceException(error); // Records to current span
  throw error;
}

// Instrument critical operations (all API routes auto-instrumented)
const result = await instrumentAsync(
  { name: "dataset.create" },
  async (span) => {
    span.setAttributes({ datasetId, projectId });
    // Operation here
    return dataset;
  },
);

注:フロントエンドでは Sentry を使用しますが、バックエンド(tRPC、API ルート、サービス、ワーカー)では OpenTelemetry + DataDog を使用します。

7. 包括的なテストが必須です

新機能やバグ修正には、すべてテストを作成してください。詳しい例はtesting-guide.mdを参照してください。

テストの種類:

種類フレームワーク場所目的
統合Jestweb/src/__tests__/async/API エンドポイント全体のテスト
tRPCJestweb/src/__tests__/async/認証付きの tRPC プロシージャ
サービスJestweb/src/__tests__/async/repositories/リポジトリ/サービス関数
ワーカーVitestworker/src/__tests__/キュープロセッサーとストリーム

簡単な例:

// Integration Test (Public API)
const res = await makeZodVerifiedAPICall(
  PostDatasetsV1Response, "POST", "/api/public/datasets",
  { name: "test-dataset" }, auth
);
expect(res.status).toBe(200);

// tRPC Test
const { caller } = await prepare(); // Creates session + caller
const response = await caller.automations.getAutomations({ projectId });
expect(response).toHaveLength(1);

// Service Test
const result = await getObservationsWithModelDataFromEventsTable({
  projectId, filter: [...], limit: 1000, offset: 0
});
expect(result.length).toBeGreaterThan(0);

// Worker Test (vitest)
const stream = await getObservationStream({ projectId, filter: [] });
const rows = [];
for await (const chunk of stream) rows.push(chunk);
expect(rows).toHaveLength(2);

主な原則:

  • テスト間の干渉を避けるため、一意の ID(randomUUID())を使用する
  • テストデータをクリーンアップするか、一意のプロジェクト ID を使用する
  • テストは互いに独立しており、どの順序でも実行できる必要があります
  • テストでpruneDatabaseを使用しない
8. テナントを分離するため、常に projectId でフィルタリングする
// ✅ CORRECT: Filter by projectId for tenant isolation
const trace = await prisma.trace.findUnique({
  where: { id: traceId, projectId }, // Required for multi-tenant data isolation
});

// ✅ CORRECT: ClickHouse queries also require projectId
const traces = await queryClickhouse({
  query: `
    SELECT * FROM traces
    WHERE project_id = {projectId: String}
    AND timestamp >= {startTime: DateTime64(3)}
  `,
  params: { projectId, startTime },
});

共通のインポート

// tRPC (Web)
import { z } from "zod/v4";
import {
  createTRPCRouter,
  protectedProjectProcedure,
} from "@/src/server/api/trpc";
import { TRPCError } from "@trpc/server";

// Database
import { prisma } from "@langfuse/shared/src/db";
import type { Prisma } from "@prisma/client";

// ClickHouse
import {
  queryClickhouse,
  queryClickhouseStream,
  upsertClickhouse,
} from "@langfuse/shared/src/server";

// Observability - OpenTelemetry + DataDog (NOT Sentry for backend)
import {
  logger,          // Winston logger with OTEL/DataDog trace context
  traceException,  // Record exceptions to OpenTelemetry spans
  instrumentAsync, // Create instrumented spans for operations
} from "@langfuse/shared/src/server";

// Config
import { env } from "@/src/env.mjs"; // web
// or
import { env } from "./env"; // worker

// Public API (Web)
import { withMiddlewares } from "@/src/features/public-api/server/withMiddlewares";
import { createAuthedProjectAPIRoute } from "@/src/features/public-api/server/createAuthedProjectAPIRoute";

// Queue Processing (Worker)
import { Job } from "bullmq";
import { QueueName, TQueueJobTypes } from "@langfuse/shared/src/server";

クイックリファレンス

HTTP ステータスコード
コード用途
200成功
201作成済み
400不正なリクエスト
401認証されていません
403禁止
404見つかりません
500サーバーエラー
参考にできる機能の例

実装パターンを確認するには、既存の Langfuse の機能を参照してください。

  • データセット(web/src/features/datasets/) - tRPC ルーター、パブリック API、サービスを備えた完全な機能
  • プロンプト(web/src/features/prompts/) - バージョン管理とテンプレートを備えた機能
  • 評価(web/src/features/evals/) - ワーカーとの連携を含む複雑な機能
  • パブリック API(web/src/features/public-api/) - ミドルウェアとルートのパターン

避けるべきアンチパターン

❌ ルート/プロシージャにビジネスロジックを記述する ❌ process.envを直接使用する(常に env.mjs/env.ts を使用してください) ❌ エラーハンドリングが不足している ❌ 入力検証がない(常に Zod v4 を使用してください) ❌ テナントスコープのクエリで projectId フィルターが不足している ❌ logger/traceException(OpenTelemetry)の代わりに console.log を使用する


ナビゲーションガイド

必要なこと...参照先
アーキテクチャを理解するarchitecture-overview.md
ルート/コントローラーを作成するrouting-and-controllers.md
ビジネスロジックを整理するservices-and-repositories.md
ミドルウェアを作成するmiddleware-guide.md
データベースにアクセスするdatabase-patterns.md
設定を管理するconfiguration.md
テストを作成するtesting-guide.md

リソースファイル

architecture-overview.md

3 層アーキテクチャ(tRPC/パブリック API → サービス → データアクセス)、tRPC/パブリック API/ワーカーのリクエストライフサイクル、Next.js 14 のディレクトリ構造、2 種類のデータベースシステム(PostgreSQL + ClickHouse)、関心の分離、複雑なクエリ向けのリポジトリパターン

routing-and-controllers.md

Next.js のファイルベースルーティング、tRPC ルーターのパターン、パブリック REST API ルート、階層化アーキテクチャ(エントリーポイント → サービス → リポジトリ → データベース)、サービスレイヤーの構成、避けるべきアンチパターン

services-and-repositories.md

サービスレイヤーの概要、依存性注入のパターン、シングルトンのパターン、データアクセス向けのリポジトリパターン、サービス設計の原則、キャッシュ戦略、サービスのテスト

middleware-guide.md

tRPC ミドルウェア(withErrorHandling、withOtelInstrumentation、enforceUserIsAuthed)、7 種類の tRPC プロシージャタイプ(publicProcedure、authenticatedProcedure、protectedProjectProcedure など)、Public API ミドルウェア(withMiddlewares、createAuthedProjectAPIRoute)、認証パターン(tRPC の NextAuth、Public API の Basic Auth)

database-patterns.md

デュアルデータベースアーキテクチャ(Prisma 経由の PostgreSQL と直接クライアント経由の ClickHouse)、PostgreSQL の CRUD 操作、ClickHouse のクエリパターン(queryClickhouse、queryClickhouseStream、upsertClickhouse)、複雑なクエリ向けのリポジトリパターン、projectId フィルタリングによるテナント分離、データベースの使い分け

configuration.md

Zod による環境変数の検証、パッケージ固有の設定(t3-oss/env-nextjs を使用する web/env.mjs、worker/env.ts、shared/env.ts)、NEXT_PUBLIC_LANGFUSE_CLOUD_REGION の使用方法、エンタープライズ機能向けの LANGFUSE_EE_LICENSE_KEY、環境変数管理のベストプラクティス

testing-guide.md

統合テスト(makeZodVerifiedAPICall を使用した Public API のテスト)、tRPC テスト(createInnerTRPCContext、appRouter.createCaller)、サービスレベルのテスト(リポジトリ/サービス関数)、ワーカーテスト(ストリームを使用する vitest)、テスト分離の原則、テストの実行(web は Jest、worker は vitest)


関連スキル

  • database-verification - カラム名とスキーマの一貫性を検証します
  • skill-developer - スキルの作成と管理のためのメタスキルです

スキルのステータス: 完了 ✅ 行数: 約 540 行 段階的開示: リソースファイル 7 個 ✅

コメント