Tool
Tool(도구)은 Fascia에서 백엔드 연산의 기본 구성 요소입니다. 각 Tool은 하나의 실행 가능한 서버 로직 단위를 나타내며, API 엔드포인트, 웹훅 핸들러, 크론 작업에 해당합니다. Tool은 전적으로 구조화된 스펙으로 정의되며, 실행은 불변의 Execution Contract(실행 계약)를 따릅니다.
Tool 스펙 구조
Tool 스펙은 다음 구성 요소를 포함합니다:
| Field | Description |
|---|---|
name | camelCase 형식의 고유 식별자 (예: createReservation, processPayment) |
version | 변경 시마다 증가하는 불변 버전 번호 |
description | Tool의 기능에 대한 사람이 읽을 수 있는 설명 |
trigger | Tool이 호출되는 방식 (HTTP, webhook, cron, queue) |
input | 예상 입력 페이로드를 정의하는 JSON Schema |
output | 응답 형식을 정의하는 JSON Schema |
flow | 실행 로직을 정의하는 Flow 그래프 (노드와 엣지) |
policies | 이 Tool에 적용되는 Policy 스펙 참조 목록 |
auth | 인증 및 인가 설정 |
riskLevel | Risk Engine이 부여하는 등급: green, yellow, red |
concurrencyStrategy | 동시 호출 처리 방식 |
idempotencyKey | 중복 호출을 방지하기 위한 멱등성 키 표현식 |
트리거 유형
트리거는 Tool이 호출되는 방식을 결정합니다:
| Trigger | Description | Use Case |
|---|---|---|
http | HTTP를 통해 tool.call(name, payload)로 호출 | API 엔드포인트, 폼 제출 |
webhook | 외부 서비스 콜백으로 호출 | 결제 확인, 서드파티 알림 |
cron | 스케줄에 따라 호출 | 일간 보고서, 주기적 정리, 반복 청구 |
queue | 메시지 큐 이벤트로 호출 (향후 지원) | 비동기 처리, 이벤트 기반 워크플로우 |
인증 설정
모든 Tool은 인증 요구사항을 지정합니다:
required-- Tool 호출에 인증이 필요한지 여부. 공개 Tool(상태 페이지 등)은false로 설정할 수 있습니다.allowedRoles-- Tool을 호출할 수 있는 역할. RBAC(역할 기반 접근 제어)를 따르며,admin,staff,customer등의 역할을 지정합니다.
인증 검사는 Execution Contract의 2단계에서 수행됩니다. 인가되지 않은 요청은 비즈니스 로직이 실행되기 전에 거부됩니다.
리스크 등급
모든 Tool은 Flow 패턴을 기반으로 Risk Engine이 리스크 등급을 부여합니다:
| Level | Meaning | Deployable? |
|---|---|---|
| Green | 안전한 패턴만 사용 -- 트랜잭션 내 Entity 작업, 무제한 쿼리 없음 | 배포 가능 |
| Yellow | 경고 패턴 감지 -- 상태 전이 내 외부 호출, Retry 설정 누락 | 확인 후 배포 가능 |
| Red | 위험 패턴 -- 원시 쓰기(raw write), 트랜잭션 누락, 롤백 없는 결제 | 차단 |
Red 등급 Tool은 어떤 상황에서도 배포할 수 없습니다. 문제를 먼저 해결해야 합니다. 전체 분류 기준과 자동 수정 제안은 리스크 규칙 레퍼런스를 참고하세요.
예시: processPayment Tool
{
"name": "processPayment",
"version": 1,
"description": "Process a payment for a confirmed reservation",
"trigger": { "type": "http", "method": "POST", "path": "/payments/process" },
"input": {
"type": "object",
"properties": {
"reservationId": { "type": "string", "format": "uuid" },
"amount": { "type": "number", "minimum": 0 },
"paymentMethod": { "type": "string", "enum": ["card", "bank_transfer"] }
},
"required": ["reservationId", "amount", "paymentMethod"]
},
"output": {
"type": "object",
"properties": {
"paymentId": { "type": "string" },
"status": { "type": "string" },
"processedAt": { "type": "string", "format": "date-time" }
}
},
"auth": {
"required": true,
"allowedRoles": ["admin", "staff", "customer"]
},
"flow": {
"startNode": "validate-reservation",
"nodes": [
{
"id": "validate-reservation",
"type": "Read",
"config": { "entity": "Reservation", "filter": { "id": "input.reservationId" } }
},
{
"id": "check-status",
"type": "Assert",
"config": { "expression": "reservation.status == 'confirmed'", "message": "Reservation must be confirmed" }
},
{
"id": "tx-start",
"type": "Transaction",
"config": { "action": "begin" }
},
{
"id": "create-payment",
"type": "Write",
"config": { "entity": "Payment", "action": "create" }
},
{
"id": "tx-end",
"type": "Transaction",
"config": { "action": "commit" }
},
{
"id": "charge",
"type": "Payment",
"config": { "provider": "stripe", "action": "charge" }
}
],
"edges": [
{ "from": "validate-reservation", "to": "check-status" },
{ "from": "check-status", "to": "tx-start" },
{ "from": "tx-start", "to": "create-payment" },
{ "from": "create-payment", "to": "tx-end" },
{ "from": "tx-end", "to": "charge" }
]
},
"policies": ["requireTransaction", "paymentRollback"],
"riskLevel": "yellow",
"idempotencyKey": "concat(input.reservationId, '-', input.amount)"
}
이 Tool은 예약(reservation)을 조회하고, confirmed 상태인지 검증한 후, 트랜잭션 내에서 결제 레코드를 생성하고, 트랜잭션 경계 밖에서 결제 서비스를 호출합니다. 외부 결제 호출이 트랜잭션 커밋 이후에 배치된 것은 의도적입니다 -- 트랜잭션이 롤백되더라도 이미 처리된 결제를 자동으로 되돌릴 수 없기 때문입니다. idempotencyKey는 동일한 예약과 금액에 대한 중복 결제를 방지합니다.