# BE/FE 컴포넌트 표준 ## 1. Backend ### 1.1 Endpoint - HTTP parsing, auth, idempotency header, ProblemDetails 변환만 수행한다. - 생산형 Command는 `PositionLotId`, `AsOf` 등 업무 식별자만 받는다. - 모델버전·임계값·Evidence를 클라이언트가 지정하지 못한다. ### 1.2 Application - 트랜잭션과 유스케이스 오케스트레이션을 담당한다. - 재시도 가능한 Command는 IdempotencyKey를 필수로 한다. - 외부 호출과 DB transaction을 혼합하지 않는다. ### 1.3 Domain Policy - 순수 함수다. - 시간, DB, 네트워크, 랜덤을 직접 사용하지 않는다. - 순서·단위·경계값을 Unit/Golden test로 고정한다. ### 1.4 Dapper/SQL - schema-qualified table과 명시적 column만 사용한다. - `SELECT *` 금지. - SQL은 Slice 가까이에 두되 공통 query abstraction을 과도하게 만들지 않는다. - immutable table은 trigger와 권한으로 update/delete를 차단한다. ## 2. Frontend ### 2.1 상태 소유권 - Server state: TanStack Query. - User/session/role/UI preference: Pinia. - Form: vee-validate + Zod. - URL shareable state: vue-router query/params. - 대량 표: AG Grid server-side model. ### 2.2 계약 - Zod schema를 request/response runtime validation에 사용한다. - TypeScript type은 `z.infer`로 파생한다. - 같은 명령의 retry는 동일 Idempotency-Key를 재사용한다. - 409/422/429/503을 서로 다른 UX로 처리한다. ### 2.3 공통 컴포넌트 - `QueryStateBoundary`: loading/empty/partial/stale/warn/error/401/403/409/expired/readonly. - `PermissionGuard`: 역할 기반 표시경계. 서버 권한검사를 대체하지 않는다. - `DataFreshnessBadge`: as-of와 stale 상태. - `VersionConflictDialog`: If-Match/409 처리. - `DataGridShell`, `CrudForm`은 실제 반복이 확인된 후 추가한다. ### 2.4 도메인 컴포넌트 - EvidencePanel. - ProtectionFloorPanel. - ReentryTimeline. - ApprovalPanel. - OutcomeAttributionPanel. 업무 의미가 다른 화면을 props가 많은 범용 컴포넌트 하나로 합치지 않는다.