serverpod-endpoint-agent
Serverpod Endpoint 전문가. endpoint 및 service 클래스 생성에 사용합니다.
| 항목 | 내용 |
|---|---|
| 실행 명령 | /cc-serverpod:endpoint |
| 별칭 | /backend:endpoint, /api:create |
| 모델 | sonnet |
| 사용 도구 | Read, Edit, Write, Glob, Grep |
| 연계 스킬 | serverpod |
한마디로#
앱 화면이 서버와 데이터를 주고받을 때 쓰는 "창구(API)"를 자동으로 만들어주는 도우미입니다. 식당에 비유하면, 손님 주문을 받아 주방에 전달하는 "주문 창구"와 그 뒤에서 실제로 요리하는 "주방"을 한 번에 차려주는 셈이에요.
누가·언제 쓰나요#
- 새 기능에 필요한 서버 API(데이터를 만들고·읽고·고치고·지우는 기능)를 만들어야 할 때
-
직접
/cc-serverpod:endpoint명령을 실행하거나, 전체 기능을 한 번에 만드는/cc-flutter:feature:create작업의 한 단계로 자동 호출될 때
무엇을 해주나요#
기능 이름과 데이터 이름만 알려주면, 아래 파일들을 일정한 규칙에 맞춰 만들어 줍니다.
- 앱용 창구(
{feature_name}_endpoint.dart) — 일반 사용자 앱이 쓰는 API - 관리자용 창구(
{feature_name}_console_endpoint.dart) — 관리자 전용 API (권한 확인 포함) - 실제 처리 로직(
{feature_name}_service.dart) — 데이터를 다루는 핵심 업무 처리 - 입력값 검증(
{feature_name}_validator.dart) — 잘못된 입력을 걸러내는 장치
만들기만 하고 끝나는 게 아니라, 서버가 이 새 창구를 인식하도록 마무리 작업(코드 생성)까지 자동으로 실행합니다. 이 마무리를 빠뜨리면 새 API를 앱에서 부를 수 없으니 꼭 필요한 단계예요.
어떻게 쓰나요#
# 기본 (앱용 API, 전체 CRUD 자동 생성)
/cc-serverpod:endpoint
# 같은 일을 하는 다른 이름(별칭)으로도 호출 가능
/backend:endpoint
/api:create
전달할 수 있는 값:
feature_name(필수) — 기능 모듈 이름 (snake_case, 예:banner)entity_name(필수) — 데이터 이름 (PascalCase, 예:Banner)-
endpoint_type(선택) —app(앱용) /console(관리자용) /both(둘 다), 기본값은app methods(선택) — 만들 기능 목록, 기본값은 전체 CRUD(생성·조회·수정·삭제)
안에서 무슨 일이 벌어지나요#
- 창구와 주방을 차립니다 — 앱용·관리자용 API 창구와, 그 뒤에서 실제로 데이터를 처리하는 로직 파일을 규칙에 맞게 생성합니다.
- 권한을 챙깁니다 — 관리자용 창구에는 "로그인 필수 + 관리자 권한" 같은 보호 장치를 걸고, 앱용 창구에는 로그인 사용자 확인을 넣습니다.
- 안전하게 삭제합니다 — 데이터를 진짜로 지우지 않고 "지워진 표시"만 남기는 방식(soft delete)을 적용합니다.
- 마무리 작업을 실행합니다 — 서버가 새 API를 인식하도록 의존 모듈 → 기능 모듈 → 호스트 codegen을 실행합니다.
⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)
Role#
Generates Serverpod Endpoint and Service classes. Consistently implements App/Console endpoint separation, CRUD method patterns, and error handling.
Activation Conditions#
- Activated on
/cc-serverpod:endpointcommand invocation - Called in Step 2 of
/cc-flutter:feature:createorchestration
Parameters#
| Parameter | Required | Description |
|---|---|---|
feature_name | ✅ | Feature module name (snake_case) |
entity_name | ✅ | Entity name (PascalCase) |
endpoint_type | ❌ | app, console, both (default: app) |
methods | ❌ | List of methods to generate (default: full CRUD) |
Generated Files#
먼저 .cob/feature-layout.json을 읽고, 없으면 cob의 기존 legacy 트리 판정 → 나머지는 bundle을 따른다. marker를 보존하고 생성 배치 계약을 적용한다. 모듈은 {feature_name}_server(type: module), SDK는 feature/{feature_name}/client의 {feature_name}_client다. bundle.json(조립)과 host-integration.json(호스트 결합)을 나누며 신규 기본은 공식 Serverpod 4.0.3이다.
feature/{feature_name}/server/lib/src/
├── endpoint/
│ ├── {feature_name}_endpoint.dart # App endpoint
│ └── {feature_name}_console_endpoint.dart # Console endpoint
├── service/
│ └── {feature_name}_service.dart # Business logic
└── validation/
└── {feature_name}_validator.dart # Input validationImport Order (Required)#
// 1. Serverpod framework
import 'package:serverpod/server.dart';
// 2. Generated protocol (models)
import 'package:{feature_name}_server/src/generated/protocol.dart';
// 3. Feature internal services
import 'package:{feature_name}_server/src/service/{service}.dart';
// 4. Module-owned session-aware host ports (never import the executable host)
import 'package:{feature_name}_server/src/host/{feature_name}_host_bindings.dart';
Core Pattern Summary#
App Endpoint#
- Set
requireLogin => truewhen authentication is required - Resolve identity through
{Feature}HostBindings.forSession(session); bind once per Serverpod instance in the host. Missing bindings or unimplemented host adapters fail closed - Delegate logic to Service classes
Console Endpoint#
requireLogin => truerequiredScopes => {Scope.admin}- Admin-only methods
Service Pattern#
- Use static methods
- try-catch +
session.log()error handling - Soft delete:
isDeleted: true
DB Query Patterns#
| Operation | Pattern |
|---|---|
| Create | Entity.db.insertRow(session, entity) |
| Read | Entity.db.findById(session, id) |
| List | Entity.db.find(session, where: ..., limit: ...) |
| Update | Entity.db.updateRow(session, updated) |
| Delete | Soft delete recommended |
| Count | Entity.db.count(session, where: ...) |
Reference Files#
feature/banner/server/lib/src/endpoint/banners_endpoint.dart
feature/banner/server/lib/src/endpoint/banners_console_endpoint.dart
feature/banner/server/lib/src/service/banner_service.dart
feature/banner/server/lib/src/host/banner_host_bindings.dart
backend/{project}_server/lib/src/host/ # instance-bound adapter/assembly onlyRequired Post-Generation Steps#
After generating endpoint/service files, run the project's bundle-aware codegen in requires DAG order: dependency modules → feature module → host. For example, use root dart run tool/feature_codegen.dart when present; inspect the actual scripts rather than assume a host-only command handles modules. The host owns DB/HTTP integration tests and cross-feature services.
# Root bundle-aware generation (when provided by the project)
dart run tool/feature_codegen.dartImportant#
If module→host codegen is skipped:
- New endpoints will not be registered in routing
- Cannot call new API methods from the module/host SDK
- Frontend build errors will occur
For a project resolved as legacy only, use its existing backend:pod:generate script and auth helpers. Do not import those host helpers into a bundle module.
Checklist#
- Follow import order
- KDoc comments on all methods
- Authentication guards + session-aware, fail-closed identity port (for authenticated methods)
- Set permissions on Console endpoints
- Separate business logic into Services
- Implement error handling and logging
- Apply soft delete pattern
- Dependency module → feature module → host generation complete
Related Documents#
Note: kobic has no separate Repository layer. Business logic lives in
service/{feature}_service.dart, which callsEntity.db(Serverpod ORM) directly. Endpoints delegate to services.