문서 목차
이 페이지에서목차

업무별 독립 feature 패키지

사용자가 모든 업무의 기능별 독립 패키지를 요청하면, 각 업무의 endpoint·서비스·모델을

완료의 의미#

사용자가 모든 업무의 기능별 독립 패키지를 요청하면, 각 업무의 endpoint·서비스·모델을 그 기능의 디렉터리와 패키지가 소유하게 한다. clinical_core·platform·shared_business 같은 하나의 모듈에 여러 업무 구현을 옮긴 것으로 완료 판정을 하지 않는다. 호스트 추출, 경로 정리, 독립 업무 분리를 각각 별도 상태로 보고한다.

독립 패키지는 필요한 공개 계약에 의존할 수 있다. 무의존 패키지나 독립 프로세스 배포를 뜻하지 않는다. 실제 pubspec/import 그래프에 순환이 없고, 필요한 런타임 구현을 호스트가 명시적으로 조립하며, 누락된 바인딩은 요청 전 실패해야 한다.

조사 순서#

  1. 작업 전 열린 PR·현재 base·해당 source 변경을 확인한다.
  2. 모델 참조, FK, 서비스 import, 교차 업무 쓰기, 공통 인증, 동기화 후처리를 각각 집계한다. 파일명이나 endpoint 수로만 경계를 추측하지 않는다.
  3. 하나의 테이블/DTO/enum에 하나의 소유자를 지정한다. DB 테이블 이름·컬럼·제약과 serverOnly 범위를 유지한다. 다른 패키지에 같은 ORM 모델을 복제하지 않는다.
  4. 순수 공통 계산, 양쪽이 사용하는 타입 계약, 역방향 서비스 호출 중 어느 종류의 순환인지 구분하고 가장 작은 경계를 끊는다. SCC를 새 core 이름으로 옮기는 것은 해소가 아니다.

모델과 업무 구현의 계층#

같은 기능의 테이블/불변 값 객체가 다른 기능에서 필요하지만 서비스끼리는 서로 호출하면, 모델/계약 하위 패키지를 둔다. 예시:

feature/patient/
  app/
  server/                         # patient_server: endpoint·서비스·요청/응답 DTO
    lib/src/{constant,endpoint,exception,helper,model,service,validation}/
    schema/                       # patient_schema_server: 환자 소유 테이블·값 객체
      lib/src/model/             # table 모델 + dto/enum/exception 분류
  bundle.json
  • 스키마 패키지는 업무 API 구현을 import하지 않는다. 서비스 패키지는 자기 스키마와 필요한 공개 데이터 계약을 의존한다. 실제 이 경계가 필요할 때만 하위 패키지를 추가한다.
  • 여러 도메인이 쓰는 소수의 enum/값 타입은 테이블·업무 서비스가 없는 타입 계약으로 추출할 수 있다. 모든 업무 모델/코드를 한 공통 스키마로 숨기지 않는다.
  • src/feature/<동일 기능> 같은 중복 계층은 만들지 않는다.
  • 패키지별 이름·역할·생성 경로·의존은 선언과 pubspec에서 일치해야 한다. 한 bundle의 server와 schema 사이에서 생기는 역할 관계를 bundle 순환으로 오인하지 않는다.

교차 호출과 트랜잭션#

역방향 호출의 계약은 호출하는 feature가 소유한다. 공급 feature를 다시 import하지 않고, 호스트가 실제 공급 구현을 바인딩한다. 바인딩 저장소는 서버 인스턴스별이고 호출할 때 현재 Session으로 선택한다. mutable process-global 구현 슬롯은 사용하지 않는다.

기존 Session, Transaction, 계정/병원 식별자를 그대로 전달한다. 포트 경계를 넘으며 새 Session을 만들거나 transaction을 누락하지 않는다. 예를 들어 예약→외부 회신, 문서→DUR/원외처방 줄, 동기화→접수 후처리, 요청 컨텍스트→IAM 검사를 계약으로 끊을 수 있다. 미구현 바인딩을 허용 권한·성공·빈 결과로 대신하지 않는다. 명시적으로 꺼진 선택 기능만 별도의 disabled 계약으로 표현하고, 활성 기능의 미등록과 구분한다.

생성 SDK와 호스트 endpoint#

프로젝트가 중앙 생성 SDK를 선언하면 backend/<project>_client/modules/<module> 같은 경로를 사용할 수 있다. 모듈별 Dart 패키지/namespace는 유지하고 client_package_path, workspace, bundle의 선언된 생성 경로, 합성 SDK export를 함께 갱신한다. 기존 조립 도구가 아직 중앙 배치를 지원하지 않으면 도구가 지원한다고 주장하지 말고 명시적 adapter/후속 작업으로 기록한다.

endpoint 원본은 기능이 소유한다. 기존 getter/URL을 유지하기 위한 호스트 thin wrapper 또는 검증된 생성 바인딩은 조립이며 업무 구현을 복제하지 않는다. 생성 바인딩을 쓰면 정규 generate와 공식 start/watch 재생성 경로가 모두 기존 API를 보존하는지 확인한다. 생성 코드의 수동 수정이나 런타임 reflection으로 계약 검사를 회피하지 않는다.

데모: 최신 스키마 스냅샷#

데모/localOnly·재생성 가능한 개발 DB에 최신 정책이 명시돼 있으면 현재 모델에서 고정 이름의 스냅샷 하나를 재생성한다. 프레임워크가 baseline 형식을 요구하면 같은 baseline 경로를 덮어 갱신하고, timestamp migration history를 추가하지 않는다. 공식 pinned schema/SQL renderer를 사용하고, 모델 스냅샷과 빈 DB 초기화가 일치하는지 테스트한다.

스키마가 바뀌면 schema fingerprint로 격리된 새 데모 DB/정식 초기화 절차를 사용한다. 공유 DB나 실제 데이터 DB에 자동 DROP/reset을 적용하지 않는다. 과거 이력이 회귀 fixture로 필요하면 불변 archive로 보존하고 runtime migration 폴더와 구분한다. snapshot 재생성은 diff 0으로 반복 가능하고, 데모 seed가 같은 최신 모델과 동작해야 한다.

SQLite 동기화는 같은 DB의 데이터와 미전송 쓰기를 보존해야 하는 실제 앱 문맥과 구분한다. 데모가 메모리 fixture만 쓰면 불필요한 cache migration을 추가하지 않는다. 영속 캐시가 있는 문맥은 실제 파일로 재개/업그레이드·미전송 보존을 별도로 검증한다.

운영/기존 데이터 DB#

운영 호환이 필요한 요청은 append-only 공식 migration과 구 SDK의 실제 HTTP/WS 검증을 따른다. 모듈 분리 후 옛 모듈의 프로젝트 스냅샷에 들어 있던 transitive 테이블이 사라지면 CLI가 다른 업무 테이블을 DROP 대상으로 계산할 수 있다. 전체 호스트의 현재 정의와 소유 테이블을 비교하고 DDL 0·데이터/OID 보존을 확인한다. 그런 DROP을 --force로 허용하지 않는다.

create-migration --empty는 변경이 없을 때도 생성하도록 허용하는 옵션이지, 계산된 DDL을 지우는 옵션이 아니다. 옵션 이름으로 빈 migration을 단정하지 말고 migration.json.actions, warnings, SQL을 검사한다. 과거 SQL과 버전 stamp를 손으로 고치지 않는다.

검증과 결과 보고#

UI를 가진 기능의 unit·widget·golden·Widgetbook·BDD 5종 작성·소유권·실행 증거는 feature-verification을 따른다. 순수 서버는 UI 3종의 N/A 근거를 기록하고 unit·실제 API/DB 시나리오를 검증한다. 운영 기능은 preview tooling을 의존하지 않고, 중앙 Widgetbook/골든 갤러리는 조립 sink다.

독립 모듈 수가 늘면 생성기의 transitive TableDefinition getter와 실패 기반 codec 탐색도 실측한다. 같은 물리 테이블 정의가 반복 펼쳐지거나 구체 타입 하나를 찾기 위해 전체 DAG를 매번 탐색하면, 스키마를 바꾸지 않는 결정적 메타데이터 중복 제거/캐시와 타입 경로를 생성 어댑터로 검증한다. subtype·unknown-tag fallback과 SQL 의미를 보존하고 수동 생성물 수정은 하지 않는다. 길어진 테스트 timeout으로 이런 성능 회귀를 숨기지 않는다.

  • 실제 패키지 DAG: pubspec/import/모델 소유권, 누락·순환·상위→하위 역할 위반 0.
  • 각 업무의 endpoint·서비스·모델 경로, 남겨진 큰 통합 업무 모듈 0.
  • 런타임 포트: 미등록 실패, 서버 인스턴스 격리, 실제 호스트 등록 완결성.
  • 교차 업무: 현재 Session/Transaction·권한·병원 격리·멱등 후처리 유지.
  • 같은 테이블의 모델 중복 0, 생성 SDK namespace/export와 접근 제한 유지.
  • 서버/클라이언트 동기화 테이블·해시 일치. enum의 qualified 이름이 바뀌어 해시가 달라지면 버전·해시를 함께 갱신하고 재연결·캐시/미전송 데이터를 검증한다. 상수를 바꿔 실패를 숨기지 않는다.
  • pinned codegen 의존 순서·재생성 diff 0, unit/integration·빌드·골든/앱 smoke.
  • 완료 보고는 업무 패키지, 공통 계약, 호스트 조립, 생성물, DB 정책과 검증을 구체적으로 적는다.

후속 co-bricks·bricks 개선#

이 규칙을 문서에 반영한 것과 조립 도구가 지원하는 것은 별개의 완료 항목이다. 도구 리팩토링은 역할별 실제 패키지 DAG, feature 소유 schema/계약 패키지, 중앙 SDK 경로, 인스턴스별/Session-aware binding, demo latest snapshot을 생성·apply·sync의 공통 계약으로 흡수해야 한다. 단일 feature PoC와 전수 독립 분리 증명을 구분하고, 기존 출력 fixture와 새 출력 fixture를 함께 돌려 경로·버전·바인딩·history 정책의 회귀를 검증한다.

후속 작업: co-bricks #851, bricks #500.

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기