실제 제품을 적절한 조작 환경에서 실행해 변경 사항을 검증하고, 사용자가 확인할 수 있는 증거를 모아 인수 보고서로 게시합니다. 기존 검증 계획을 확인하거나 점검 항목을 만들고, `lh` CLI로 결과를 게시할 수 있습니다.
- 변경된 제품 동작을 실제로 확인하기
- 스크린샷 등 검증 증거 수집하기
- 검증 계획과 보고서 작성하기
서버 측 tRPC 라우터에 쿼리나 변경 절차를 추가할 때 참고하는 안내서입니다. Zod 입력 검증, 미들웨어를 통한 모델 전달, 응답 형식과 오류 처리, 관련 데이터를 병렬로 조회하는 상세 절차를 설명합니다.
Use for server TRPC routers, procedures and API endpoints in apps/server/src/routers.
실행 점수 미검증
설치 방법 보기이 안내서는 서버 측 tRPC 라우터와 쿼리, 변경 절차를 추가하는 방법을 설명합니다. 라우터 파일의 위치와 기본 구조를 확인할 수 있습니다. 입력값은 Zod 스키마로 검증하고, 모델은 미들웨어를 통해 절차의 컨텍스트에 전달한 뒤 내부에서 사용합니다. 쿼리와 변경 절차의 응답 형식, TRPCError 처리, 오류 로그 작성법, 라우터 안에서 절차 이름을 배열하는 규칙도 다룹니다. 여러 관련 데이터가 필요한 상세 조회에는 데이터를 병렬로 가져오는 예시가 포함되어 있습니다.
새 API 절차를 추가하면서 기존 프로젝트 규칙을 따르고 싶을 때 참고할 수 있습니다. 공통 미들웨어가 제공하는 모델을 절차에서 사용하거나, 예상하지 못한 오류를 일정한 형식으로 처리하고 싶을 때도 도움이 됩니다. 화면이나 CLI가 필요한 관련 정보를 한 번의 요청으로 가져오도록 상세 조회를 설계할 때 활용할 수 있습니다.
이 안내서는 apps/server/src/routers 아래의 서버 측 tRPC 라우터를 대상으로 합니다.
이 소개문은 공개된 SKILL.md를 바탕으로 AI(OpenAI Codex)가 작성했습니다. 정확한 사양은 아래 원문을 확인하세요.
AI가 SKILL.md의 내용에서 주의가 필요한 작업과 도입 전제를 확인했습니다. 점수는 실제로 실행한 결과(실행 검증)만으로 매깁니다.
점수에는 넣지 않았습니다. 2026년 10월 26일 기준으로 AI(OpenAI Codex)가 판정했습니다. 참고용이므로 설치 전에 원문도 확인해 주세요.
설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
apps/server/src/routers/lambda/<domain>.tsapps/server/src/routers/lambda/_helpers/apps/server/src/routers/lambda/_schema/import { TRPCError } from '@trpc/server';
import { z } from 'zod';
import { SomeModel } from '@/database/models/some';
import { authedProcedure, router } from '@/libs/trpc/lambda';
import { serverDatabase } from '@/libs/trpc/lambda/middleware';
Always use middleware to inject models into ctx instead of creating new Model(ctx.serverDB, ctx.userId) inside every procedure.
const domainProcedure = authedProcedure.use(serverDatabase).use(async (opts) => {
const { ctx } = opts;
return opts.next({
ctx: {
fooModel: new FooModel(ctx.serverDB, ctx.userId),
barModel: new BarModel(ctx.serverDB, ctx.userId),
},
});
});
Then use ctx.fooModel in procedures:
// Good
const model = ctx.fooModel;
// Bad - don't create models inside procedures
const model = new FooModel(ctx.serverDB, ctx.userId);
Exception: When a model needs a different userId (e.g., watchdog iterating over multiple users' tasks), create it inline.
export const fooRouter = router({
// Query
find: domainProcedure.input(z.object({ id: z.string() })).query(async ({ input, ctx }) => {
try {
const item = await ctx.fooModel.findById(input.id);
if (!item) throw new TRPCError({ code: 'NOT_FOUND', message: 'Not found' });
return { data: item, success: true };
} catch (error) {
if (error instanceof TRPCError) throw error;
console.error('[foo:find]', error);
throw new TRPCError({
cause: error,
code: 'INTERNAL_SERVER_ERROR',
message: 'Failed to find item',
});
}
}),
// Mutation
create: domainProcedure.input(createSchema).mutation(async ({ input, ctx }) => {
try {
const item = await ctx.fooModel.create(input);
return { data: item, message: 'Created', success: true };
} catch (error) {
if (error instanceof TRPCError) throw error;
console.error('[foo:create]', error);
throw new TRPCError({
cause: error,
code: 'INTERNAL_SERVER_ERROR',
message: 'Failed to create',
});
}
}),
});
For views that need multiple related data, create a single detail procedure that fetches everything in parallel:
detail: domainProcedure.input(idInput).query(async ({ input, ctx }) => {
const item = await resolveOrThrow(ctx.fooModel, input.id);
const [children, related] = await Promise.all([
ctx.fooModel.findChildren(item.id),
ctx.barModel.findByFooId(item.id),
]);
return {
data: { ...item, children, related },
success: true,
};
}),
This avoids the CLI or frontend making N sequential requests.
{ data, success: true } for queries, { data?, message, success: true } for mutationsTRPCError, wrap others with console.error + new TRPCErrorzod schemas, define at file topexport const fooRouter = router({ ... })[domain:procedure] format, e.g. [task:create]아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
실제 제품을 적절한 조작 환경에서 실행해 변경 사항을 검증하고, 사용자가 확인할 수 있는 증거를 모아 인수 보고서로 게시합니다. 기존 검증 계획을 확인하거나 점검 항목을 만들고, `lh` CLI로 결과를 게시할 수 있습니다.
LobeHub에 AI 모델 제공자를 추가하는 과정을 안내합니다. 런타임 연동, 모델 정보와 설정, 브랜드 표시, 문서화 및 인수 확인을 다루며, 기존 제공자에 모델만 추가하는 경우와 새 연동이 필요한 경우를 구분합니다.
서버 환경 변수로 사용자 설정의 기본값을 지정하도록 구현하는 절차를 안내합니다. 변수 검증, 서버 설정 구성, 사용자 저장소 반영부터 예시 환경 파일과 셀프 호스팅 문서 갱신까지 다룹니다.
에이전트 실행 단계, 도구 호출, 사람의 승인, 컨텍스트 압축, 하위 에이전트 호출에 훅을 등록하는 방법을 안내합니다. 이벤트를 관찰하고 로컬 도구 결과를 모의하거나 설정에 따라 웹훅으로 도구 호출을 허용 또는 거부할 수 있습니다.
에이전트의 이벤트 기반 백그라운드 작업을 설계하고 구현하도록 돕습니다. 소스, 시그널, 액션, 정책의 역할을 나누고 비동기 처리, 중복 실행 방지, 완료 기록과 관측 기능을 다룹니다.
실제 데스크톱 채팅 앱에서 봇 채널의 인수 테스트를 진행합니다. Discord, Slack, Telegram, WeChat, Lark, QQ에서 메시지를 보내고 응답을 기다린 뒤 결과 화면을 캡처합니다. iMessage는 BlueBubbles 브리지를 사용합니다.