Feature 소유 구조 — 소스 · 테스트 · 카탈로그
`.cob/feature-layout.json`과 [배치 계약](../../../../cc-bricks/rules/feature-placement.md)이
.cob/feature-layout.json과 배치 계약이
프로젝트의 외부 패키지 경계를 정한다. 기존 legacy 표면 분류는 보존하고 역할 패키지
안의 소유권을 아래 원칙으로 정리한다. 이름을 client로 바꾸거나 새 상위 계층을 만들지 않는다.
Flutter UI 역할#
feature/<name>/{app,console}/
lib/
<feature>.dart
{data,domain,presentation,route}.dart
src/
data/{cache,local,repository}/
di/injector.dart
domain/{entities,exceptions,failures,repository,usecase,util}/
key/<feature>_keys.dart
presentation/{bloc,constant,error,page,util,widget}/
route/<feature>_route.dart
test/
fixtures/ # JSON·미디어 입력
flutter_test_config.dart
src/
data/repository/
domain/usecase/
presentation/{bloc,widget}/
golden/ # 테스트 + 생성기 규약의 상대 goldens/
bdd/ # co_bdd 모드의 .feature·step·생성 widget 시나리오
{integration,regression,structure,support,unit,perf}/
widgetbook/ # 별도 workspace pub 패키지
{pubspec,build,analysis_options}.yaml
lib/
<feature>_widgetbook.dart
<feature>_widgetbook.directories.g.dart
fixtures.dart # 필요한 공개 fixture API
src/{use_case,fixture}/
실제 존재하는 역할만 만든다. 역할과 하위 디렉터리에 필요한 배럴을 두고, part of는
소유 라이브러리를 통해 내보낸다. 조건부 플랫폼 파일을 무조건 직접 export하지 않는다.
Cubit은 presentation/bloc, dialog/panel/tab은 presentation/widget
아래에 둔다.
공용 UI는 그 공용 패키지가 같은 방식으로 test/widgetbook을 소유한다.
Backend 역할#
feature/<name>/server/
lib/src/
<feature>.dart
{constant,endpoint,exception,helper,service,validation}/
model/<entity>.spy.yaml # table 모델
model/{dto,enum,exception}/ # 각 YAML 모델 종류
generated/ # 공식 생성물
test/unit/ # Session·실제 DB가 없는 정책/서비스
schema/ # 필요한 경우만, 기능 소유 계약 하위 패키지
backend/<project>_server/test/integration/ # DB·Session·dispatcher·HTTP/SDK·교차 기능
큰 core 모듈에 업무 구현을 모아 독립 완료로 보고하지 않는다. 모델/테이블은 단일 소유자를 가지며 schema→업무 구현 역방향 의존을 금지한다. endpoint 원본은 기능 소유, 호스트는 조립과 검증된 생성 바인딩을 소유한다. 중앙 SDK 배치는 선언된 모듈별 패키지/namespace를 유지한다. Serverpod 인스턴스별 바인딩과 현재 Session/Transaction 전달을 검증한다. 상세: independent-features.
조립 sink와 실행 위치#
- 중앙 Widgetbook은 feature fragment와 addons를 조립한다. feature 전시 구현을 소유하지 않는다.
- 중앙 golden gallery는 feature report/이미지를 namespace별로 모으고 표시·배포한다.
- feature-local 테스트는 소유 pubspec 루트에서 실행한다. 이동한 import/part/fixture 경로와 test 설정을 함께 갱신한다. 파일 개수나 전체 PASS만으로 AC 커버리지를 단정하지 않는다.
- cross-feature BDD/Patrol은 실제 실행 앱이 소유한다. co_bdd와 수기 Patrol legacy의 소스·생성·실행 위치는 feature-verification의 모드 표를 따른다.
- 선택되지 않은 feature를 중앙 registry가 import하지 않게 생성한다. workspace 등록, pubspec 실제 의존, source imports, 카탈로그/골든 수집 목록을 대조한다.
- 등록 누락·의존 순환·중복 경로·누락 이미지·실행 대상 없는 Patrol 생성은 실패시킨다.
- latest demo snapshot은 명시적 데모 정책에서만 적용한다. 운영 이력/공유 DB를 reset하거나 테스트를 통과시키기 위해 namespace/hash/migration history를 임의로 고치지 않는다.