Skip to content

Barbelic 앱 / 관리자·문서 저장소 분리 검토

이 문서는 구현 전 조사 기록이다. 후속 #1463에서 dekerd/Barbelic-docs와 앱 v0.17.7 분리가 승인되었다. 아래의 "이름 미확정"·"이관 미실행"은 조사 시점이며, 현행 저장소 경계독립 운영·실제 전환 상태를 따른다.

조사일: 2026-09-09. 사용자 요청: 문서 수정 때문에 앱 main이 변경되고 CI·승격을 반복하는 문제를 없애기 위한 저장소 분리 검토.

확정한 방향

사용자는 앱 저장소에 구현 코드만 두고, 정책을 포함한 모든 문서를 관리자·문서 저장소로 옮기는 방향을 확정했다. 기존 dekerd/Barbelic은 앱과 공통 백엔드의 구현·테스트·실행 설정·자산을 소유하고, 새 저장소(가칭 Barbelic-ops, 이름 미확정)는 관리자 프론트엔드와 모든 문서를 소유한다. 목표는 문서 변경으로 앱 저장소에 커밋·PR·CI·배포가 생기지 않는 것이다. 실제 저장소 생성·이관은 아직 수행하지 않았다.

Vercel 프로젝트만 나누는 작업은 이미 일부 되어 있다. 필요한 것은 소스 의존성, 검증, 배포, 문서 작성 절차의 분리다. docs/를 통째로 옮기면서 현재 문서를 직접 읽는 검사와 관리자 빌드 참조도 함께 바꾼다. 검사에 필요하다는 이유로 문서를 앱에 남기지 않는다. 앱 저장소를 새 저장소에서 다시 clone하거나 submodule로 가져와 빌드하는 결합도 만들지 않는다.

조사 범위와 확인 수준

  • 현재 main: 8ea0f1d134b76687a4f8b58cfd7c5e395d6ac49a.
  • 예정 워크플로: PR #1460의 31f60b6f217933e3665af69401441b7b9208d854. 조회 당시 OPEN으로, main 활성화 전이다.
  • release/v0.17.6 조회 SHA: 23cfb4a3a9bc6c6002a8d439ce6f9264e660699f.
  • 소스·GitHub 상태·배포 기록 조회와 TypeScript 구문 분석으로 의존성을 조사했다. 현재 main과 #1460의 CI 핵심 경로를 대조했다. 앱 소스 수정, CI/빌드, 원격 저장소 생성, PR 변경, 운영 DB 변경은 하지 않았다.
  • 조회한 기존 v0.17.5 운영 Deploy 34309502657, staging Deploy 34309191453은 success였다. 이것을 새 저장소 분리의 배포 검증으로 간주하지 않는다. Vercel 연결·도메인·권한·요금의 현재 콘솔 상태는 이번에 재조회하지 않았다.

왜 문서 때문에 앱 CI가 도는가

  1. 문서 예외와 실제 CI 실행 코드가 어긋나 있다. docs/* → main 경로는 허용하지만, check-promotion.mjs는 그 경로도 requires_full=true로 출력한다. hosted workflow가 이 값을 사용해 DB·브라우저·viewport까지 실행한다. 로컬 검사에 있는 Markdown 경량 분류는 이 hosted 경로에서 사용되지 않는다. 현재 main에도 이미 있는 문제로, #1460의 개명으로 해결되지 않는다. 현재 main의 판정 코드, 호출 workflow.
  2. 문서 커밋도 운영 승격의 비교 대상이다. main에 합쳐질 전체 tree와 staging tree의 일치를 요구한다. 문서만 main에 먼저 들어가도 두 tree가 달라져 해당 커밋을 release/staging에 다시 포함하고 검증해야 하는 상황을 만든다. 이는 단순 CI 실행 횟수 조정보다 깊은 결합이다. 승격 tree 검사.
  3. 모든 작업의 release 큐가 docs/admin 빌드를 요구한다. 큐의 최종 증거에 앱 full뿐 아니라 docs 성공도 필수다. 앱 코드만 바꾸어도 문서 프로젝트와 관리자 산출물을 검증한다. 큐의 빌드와 필수 증거.
  4. 배포도 같은 SHA에 묶여 있다. VERCEL_DOCS_PROJECT_ID는 별도지만 docs 배포는 앱의 DB·Edge 완료에 의존하고 같은 커밋을 사용한다. docs/vercel.json의 Git ignore 조건으로 Actions의 명시적 CLI 배포를 막을 수 없다. docs 배포 job.

requires_full의 문서 분기만 고치면 당장 과도한 CI를 줄일 수 있다. 그러나 앱 main 변경·승격 tree·관리자 동봉 빌드는 남는다. 저장소 분리의 대체 해결책으로 보지는 않는다. 또한 workflow 전체를 path filter나 커밋 문구로 건너뛰면 필수 검사가 Pending에 남을 수 있으므로 단순 skip 추가도 적합하지 않다. GitHub 공식 설명.

docs 전체 이관과 함께 바꿀 참조

관리자 빌드는 현재 앱 소스를 사용한다

docs/package.json의 build는 VitePress 뒤에 docs/scripts/build-admin.mjs를 실행한다. 이 스크립트는 부모 저장소의 vite.admin.config.mjs, src/, 루트 node_modules를 요구하고 필요하면 루트 npm ci까지 실행한다. 부모 설정이 없으면 성공 종료하면서 관리자 빌드를 생략한다. 분리 후 문서는 뜨는데 /admin/은 빠지는 실패가 가능하다. 실제 빌드 코드.

관리자 진입점은 별도여서 분리의 출발점은 있다. 하지만 AdminStandaloneRoot와 feature/controller는 앱 전체 BarbelicApi, 공용 로그인 셸, ViewMapper를 가져오고 관리자 main은 desktop CSS 전체를 import한다. 관리자 루트, 관리자 CSS·부팅 의존성.

정적 import 그래프에서는 관리자 진입점의 도달 파일 193개 중 앱과 겹치는 파일이 162개, 관리자 쪽에만 도달하는 파일은 31개였다. 타입 import·재수출까지 포함한 소스 의존성 수이며 실제 번들 크기나 실행되는 코드 수가 아니다. 상대 import 해석 실패는 0개였다. 공유 경로에는 운동·달력·네이티브 인증·저장 영수증 코드까지 들어간다. 따라서 162개를 그대로 복제하기보다 관리자가 쓰는 작은 API·브라우저 인증·입력 타입·스타일 경계를 추출하는 것이 적합하다.

파일명으로도 단순 분류할 수 없다. adminDomain.ts에는 일반 사용자의 데이터 내보내기가 있고, api/admin/*는 앱의 사용자 화면 대리 열람 기능에서도 사용한다. 이 코드는 관리자 사이트 폴더라는 이유로 통째로 이동하면 안 된다. 데이터 내보내기, 앱의 대리 열람 소비.

문서가 검증 입력인 현재 구조를 해소한다

현재 파일 종류분리 시 소유권
가이드·운영 절차·로드맵·작업 기록·버그 리포트·README·에이전트 지침위치와 무관하게 전부 새 ops 저장소
관리자 화면·관리자 전용 controller·import UI·스타일새 ops 저장소
SQL/migrations/RLS/Edge·사용자 기록·통계 계산앱/백엔드 저장소 유지
docs/policies/**의 정책 설명·명세·이력·문서용 JSON/CSV전부 ops로 이동. 실행 수치·테스트 데이터는 앱의 버전 있는 코드 상수·SQL·테스트 생성기로 정의하고 문서 파일 참조 제거
DB 모델·커버리지의 생성 문서문서는 ops 소유. 앱은 DB·코드의 정합성을 직접 검사하고 필요하면 버전 고정 계약 산출물을 제공
RPC·UI props·한도 등 코드가 직접 읽는 계약 문서모든 문서 원본을 ops로 이동. 앱 검사는 타입·스키마·실제 응답·동작 검사로 대체
public/legal/** 등 약관 원문ops에서 버전별 게시. 앱에는 문서 주소·버전 식별자·동의 처리 구현을 두고 기존 주소와 동의 의미 보존

특히 기존 DB 정책의 docs_path 자체를 검사하는 테스트도 있다. 과거에 저장된 출처 식별자를 보존하는 것과 앱에 그 경로의 문서 파일을 계속 두는 것은 별개다. 문서 위치를 바꾸려고 적용된 migration·정책 식별자·기존 기록의 해시를 다시 쓰지 않는다. 새 문서 위치는 해당 이력과 연결하고, 앱 검사는 문서 존재·문구 대신 실행 정책 버전과 계산 결과를 확인하도록 바꾼다. 현재 정책 원본 검사, 현재 정책 경로 계약.

앱 테스트가 Markdown 표·문구·해시·문서 생성 결과를 읽어야 통과하는 구조는 없앤다. 보호해야 할 요구사항은 입력 검증, 계산 결과, API/RPC 응답, 권한, DB 불변식, 네트워크 오류와 동시성 검사로 옮긴다. 예를 들어 점수 정책 문구의 존재를 검사하는 대신 독립적으로 정한 입력과 예상 점수로 계산을 검사한다. 예상값을 검증 대상 함수에서 그대로 만들어 자기 자신을 검증하지 않는다.

테스트용 데이터도 가능하면 코드와 SQL로 정의한다. package.json, 잠금 파일, CI 설정, 이미지·폰트 등 실행에 필요한 파일은 유지한다. 파일 확장자 자체를 제한하는 작업이 아니라 문서 저장소 없이 앱을 설치·빌드·검증할 수 있게 만드는 작업이다. 문서용 링크·형식·게시 검사는 ops에서만 수행한다.

제안 구조

text
dekerd/Barbelic                       새 저장소: Barbelic-ops (이름 미확정)
  앱 Web / iOS / Android               admin/ 관리자 프론트엔드
  API / Edge / Supabase                docs/ 모든 정책·명세·가이드·운영 절차
  migrations / RLS / 통계               updates/ 작업 기록·로드맵
  타입·실행 정책 코드·앱 테스트          bug-report/ 장애 기록
  앱 CI / DB·앱 배포                    독립 의존성·CI·배포
          │                                     │
          └─ 서버 API/RPC + 버전이 고정된 계약 ──┘
  • DB의 생성·마이그레이션·권한·통계 계산 소유자는 한 곳으로 유지한다. 관리자 UI의 독립 배포를 위해 운영 DB를 분리하거나 사용자 데이터를 이관할 이유는 없다.
  • 관리자 전용 API adapter와 브라우저 인증 경계를 두고 기존 서버의 관리자 권한/RLS 검증을 유지한다. 서버 관리 키를 새 프론트엔드에 옮기지 않는다. 앱에서도 사용하는 /api/admin/*는 일단 앱 백엔드에 유지한다. 관리자가 다른 origin에서 호출할 엔드포인트가 있으면 명시적 API 주소·CORS 또는 제한된 프록시를 검증한다.
  • 두 저장소가 공통으로 필요한 타입·입력 계약은 작은 버전 고정 산출물로 제공한다. 처음부터 세 번째 공유 저장소나 거대한 공통 SDK를 만들지 않는다. 새 repo가 앱 main을 매번 내려받아 빌드하는 의존성을 만들지 않는다.
  • 앱과 관리자에 같은 Git SHA를 요구하는 대신, 지원하는 API/RPC 계약과 환경을 검증한다. 호환 변경은 서버에 먼저 추가 → 새 관리자 배포 → 이전 계약 제거 순서로 처리한다. 백엔드 계약 변경 때만 관련 관리자 호환 검사를 수행한다.
  • 에이전트 지침 본문도 ops에 둔다. 작업자의 전역·워크스페이스 설정에서 이 문서 저장소를 참조하도록 연결하며 앱에 지침·보고서를 복제하지 않는다. 이전 지침의 “모든 기록은 앱 docs에 등록” 경로는 이관 후 문서 저장소 기준으로 해석한다.

같은 ops repo 안에서도 문서와 관리자의 CI 범위를 구분한다. 문서 배포까지 완전히 독립시키려면 docs와 admin을 별도 배포 대상으로 두는 편이 명확하다. 현재 /admin/ 주소를 유지해야 하면 라우팅으로 연결할 수 있지만 실제 경로·인증 확인이 필요하다. 같은 Vercel 산출물에 계속 동봉할 수도 있으나, 그 경우 문서 배포가 관리자 산출물을 다시 포함하는 결합은 남는다. 어떤 경우에도 앱 저장소를 다시 빌드하지 않는 것이 첫 완료 기준이다.

기존 Vercel 프로젝트의 연결 GitHub 저장소는 변경할 수 있다. 따라서 무조건 새 도메인으로 갈아탈 필요는 없으며, 실제 전환 전 기존 Root Directory·빌드 명령·환경·Git 연결을 확인해야 한다. Vercel 공식 문서.

작업자의 문서 참조·갱신 절차

  1. 작업 시작 시 문서 저장소의 최신 상태, 공통 작업 규칙, 해당 작업에 관련된 정책·설계·운영 절차를 확인한다. 모든 문서를 매번 읽는 대신 관련 문서와 변경된 부분을 읽고 코드의 적용 버전과 대조한다.
  2. 구현으로 정책·계약·구조·운영 방식이 달라지면 관련 문서도 함께 갱신한다. 계획·미출시 구현·실제 운영 반영을 구분한다. 영향이 없는 문서는 억지로 수정하지 않는다.
  3. 코드 PR/커밋과 문서 PR/커밋을 서로 연결하고 적용 릴리스를 남긴다. 작업·업데이트·장애 기록은 문서 저장소에만 작성한다. 기록 때문에 앱 main을 추가 갱신하지 않는다.
  4. 문서 수정은 문서 검사·게시로 끝낸다. 실행 정책 자체를 바꾸는 작업은 코드·테스트·앱 릴리스도 변경한다. 앱 CI가 변경 가능한 docs main을 받아 실행하거나 문서 수정이 앱 CI를 발화하지 않도록 한다.

이관 전에는 기존 문서가 이전할 원본이다. 이번에 갱신한 것은 로컬 분리 계획과 Codex 전역지침이며 원격 공통 지침·Claude 설정·기존 작업 세션이 자동 갱신된 상태는 아니다. 실제 이관에서 모든 작업자의 문서 repo 참조 경로와 갱신 절차를 함께 전환한다.

실행 순서 제안

Phase작업완료 증거
Phase 1모든 문서의 이관 목록과 현재 문서 의존 검사, 관리자 API·스타일 경계를 정리문서 잔류 예외 없음; 각 검사의 대체 동작 검증과 단일 백엔드 소유권 명확화
Phase 2모든 문서 이관·앱의 문서 의존 검사 대체·관리자 추출; 관련 테스트를 소유 repo로 이동앱은 docs checkout 없이 검증; ops는 앱 checkout 없이 빌드; /admin/ 누락 시 실패, 로그인·비관리자 차단·카탈로그·매핑·인입 회귀 통과
Phase 3ops CI·배포와 문서 게시 경로를 준비한 뒤 기존 Vercel 연결·필요한 인증 redirect를 전환새 docs/admin 배포·권한·환경 확인; 실패 시 이전 배포로 복귀 가능한 상태
Phase 4앱 큐·hosted CI·Deploy의 docs/admin 강제 빌드·증거·동일 SHA 요구 제거; 모든 작업자의 문서 참조·갱신 경로 전환문서 PR로 앱 main·큐·배포 변경 0; 코드 작업에서 관련 문서 확인·갱신과 상호 링크 확인

진행 중인 #1460이나 다른 담당자의 큐를 바꾸는 방식으로 끼워 넣지 않는다. 구현을 시작한다면 별도 인프라 작업으로 현재 릴리스 상황에 맞는 다음 0.17.n에 배정한다. 앱의 제거 변경은 기존 release 큐를 거치고, 모든 Phase의 검증을 소유 변경 범위에 맞춰 모은다. 위 순서는 제안이며 아직 repo 생성·배포 전환을 수행한 상태가 아니다.

예상 효과·개선사항

아래는 측정 결과가 아니라 분리 후 확인할 목표다. 현재 CI 시간이나 단축률은 새로 측정하지 않았으며 시간을 약속하지 않는다.

개선되는 것체감 대상확인 지표 전→후Phase
문서 때문에 앱 후보가 바뀌는 문제 제거사용자·앱 작업자문서 PR로 앱 main 변경 가능 → 변경 0건4
문서의 앱 full CI 제거모든 작업자·runner문서 lane도 full 판정 → 문서 PR의 앱 CI 0회4
문서 게시를 앱 출시와 분리문서 작성자다음 앱 배포 대기 가능 → docs 자체 검사·게시3
관리자 변경의 영향 범위 축소관리자 작업자·사용자앱 공용 source·전체 검증 → 관리자 범위 검사·계약 호환 확인2~4
원본 데이터 유지앱 사용자현재 DB → 동일 DB, 분리를 위한 데이터 이관 0건전체

부작용은 두 저장소의 계약 버전·접근 권한·배포 환경을 관리해야 한다는 점이다. 특히 관리자 프론트엔드의 독립 배포 후에도 실제 사용자 데이터를 수정하는 권한은 그대로이므로 관리자 쓰기·권한 검사를 생략할 수 없다. 반면 일반 Markdown을 바꿀 때 앱 DB 재생·운동 저장 e2e를 실행할 이유는 없어진다.

검토 결론

사용자 결정에 따라 정책을 포함한 모든 문서는 ops로 이관하고, 앱의 문서 의존 검증은 실제 동작 검증으로 대체한다. 관리자 코드의 앱 의존성도 함께 끊는다. **“문서 하나 수정 → ops에서 검증·게시 → 앱 커밋·CI·배포는 0”**과 작업자의 관련 문서 참조·갱신을 실제로 확인한 시점을 분리 완료로 삼는다.