Skip to content

Latest commit

 

History

History
69 lines (48 loc) · 6.07 KB

File metadata and controls

69 lines (48 loc) · 6.07 KB

T6 — Lab UI

완료일: 2026-09-10

작업 범위

기존 SQLite·PostgreSQL Alembic runtime을 실제 사용 가능한 실습 화면에 연결한다. 파일 편집 → 명령 실행 → revision DAG·DB schema/data·diff 확인을 하나의 흐름으로 제공한다. T7 lesson validator, actor 복제 및 T8 영속 저장·체크포인트 복원은 포함하지 않는다.

구현 결과

  • SQLite/PostgreSQL 환경 선택, 독립 workspace 생성·전환·확인 후 초기화. 최대 4개 runtime을 유지한다.
  • 파일 탐색기와 Python/SQL/INI CodeMirror 편집기. 편집 초안 유지, 명시적 저장, Ctrl/⌘+S, 저장 전 실행 차단.
  • Python shlex와 기존 allowlist를 사용하는 Alembic 터미널. 명령 예시, 위·아래 방향키 기록, 실행 중 중복 요청 차단.
  • 실제 ScriptDirectory 경로로 파일과 DAG를 연결한다. head, DB current, branch, merge, depends_on 관계를 표시하고 키보드용 revision 목록을 제공한다.
  • 실제 Inspector의 타입·컬럼·constraint·index와 alembic_version 표시. FK와 current revision에서 관련 테이블·파일로 이동한다.
  • 실제 테이블 데이터 최대 50행 조회. 큰 정수·Decimal·시간·binary 등을 tagged 값으로 전달하며 preview는 1 MiB로 제한한다.
  • 파일 변경 목록과 schema 변경의 Before/After 상세. diff에서 파일 또는 DB 테이블로 이동한다.
  • 최근 100개 명령의 stdout/stderr/traceback과 별도 학습 설명.
  • 초기화·처리 중 진행 메시지, 실패 후 실제 snapshot, timeout/Worker crash 후 마지막 snapshot 표시 및 복원 불가 안내.
  • 데스크톱 2열 분할 화면과 850px 이하 탭 화면. 패널 탭의 방향키/Home/End 접근.

변경 파일

  • 화면: src/App.tsx, src/styles.css, src/lab/CodeEditor.tsx, src/lab/RevisionGraph.tsx, src/lab/Panels.tsx
  • UI 상태와 실행 조율: src/lab/store.ts
  • 런타임 연결: src/runtime/alembic-runtime-client.ts, src/runtime/protocol.ts, src/runtime/pyodide.worker.ts, src/runtime/python/alembic_runtime.py
  • 검증: src/App.test.tsx, src/lab/store.test.ts, src/runtime/protocol.test.ts, src/runtime/alembic-runtime-client.test.ts, tests/e2e/lab-ui.spec.ts, tests/e2e/capabilities.spec.ts
  • 의존성: package.json, pnpm-lock.yaml
  • 정적 자산 응답: vite.config.ts, public/_headers
  • 문서: README.md, docs/SPEC.md, docs/DEPLOYMENT.md, docs/T6.md, 로컬 docs/TASKS.md

의존성 검토

CodeMirror 6, React Flow 12.11.6, Zustand 5.0.15를 exact version으로 설치했다. 추가한 패키지는 MIT license이며 브라우저 UI에서 실행된다. Python/PGlite 연산은 기존 Worker에 남겨 두었다. 모든 UI dependency는 Vite가 동일 출처 정적 자산으로 묶으므로 런타임 CDN 요청을 추가하지 않는다.

UI JS는 약 0.9 MB(압축 전)다. 개별 정적 파일 25 MiB 게이트는 유지된다. 기존 PGlite 내부 eval 경고와 큰 UI chunk 경고는 남아 있으며 지연 로딩 최적화는 T8에서 검토할 수 있다.

검증

  • UI 전용 E2E: 두 DB의 실제 init → revision 편집·저장 → upgrade → schema/data/diff → downgrade → branch/merge → 원본 오류 확인.
  • 명령 중 main thread 패널 전환, 저장 전 실행 차단, 데이터 50행 제한과 2^53 초과 정수 보존, 초기화 확인 취소/승인, 좁은 화면 키보드 탐색을 검증한다.
  • 단위 테스트: workspace 전환과 초안 보존, 중복 실행 차단, 실제 실패 snapshot, timeout 후 명시적 재시작, 선택 workspace 초기화, progress의 비종결 처리, idle Worker crash 알림, protocol runtime validation.

최종 검증은 프로젝트 루트에서 mise exec -- 환경으로 수행했다.

  • pnpm lint: 통과
  • pnpm test: 7개 파일, 31개 테스트 통과
  • pnpm test:e2e --workers=1: Chromium·Firefox·WebKit 전체 51개 테스트 통과 (3.8분)
  • pnpm build: TypeScript 검사, 테스트 hook 없는 production build, 정적 파일 크기 검사 통과. 28개 파일 중 최대 9.62 MiB로 모두 25 MiB 미만.
  • pnpm peers check: peer dependency 문제 없음
  • git diff --check: 통과

WebKit 반복 초기화 수정

WebKit에서 첫 workspace는 정상 생성되지만 같은 Worker/모듈을 다시 로딩할 때 캐시 응답이 COEP로 차단되는 오류를 재현했다. 확인창 자체가 원인은 아니었으며, 반복 로딩 시 캐시를 사용하지 않으면 해결됨을 확인했다. 유사한 캐시/COEP 문제는 WebKit 버그 보고에도 기록되어 있다.

JS/MJS 모듈에 한정해 production preview와 Cloudflare _headersCache-Control: no-store를 적용했다. 큰 WASM/data/wheel 자산은 기존 캐시 가능성을 유지한다. preview의 304 응답에도 COOP/COEP/CORP를 붙인다. 개발 서버는 전체 응답을 no-store로 제공한다. 헤더 경로 패턴은 Cloudflare 공식 문서를 따른다.

초기화 확인에는 focus가 제한되고 Escape로 취소할 수 있는 HTML dialog를 사용한다. 동일 탭에서 두 번째 workspace 생성, 원래 workspace 재선택, 초기화 취소/확인, JS와 WASM의 서로 다른 캐시 정책을 브라우저 테스트에 포함한다.

현재 한계

  • 파일·DB는 현재 탭 메모리에만 유지된다. 새로고침·Worker 종료 후 자동 복원은 T8에서 구현한다.
  • timeout UI는 복원에 성공했다고 표시하지 않는다. 새 workspace 생성 또는 사용자 확인 후 초기화로 다시 시작한다.
  • 파일 diff는 추가·변경·삭제 목록이며 줄 단위 비교는 제공하지 않는다. schema diff는 전후 상세를 제공한다.
  • 원본 로그는 명령 완료 시 표시한다. 단계 진행 메시지는 전달하지만 stdout/stderr 스트리밍은 제공하지 않는다.
  • 가이드 설명은 정적인 개념 안내이며 학습 단계의 성공 판정이나 Alice/Bob workspace 병합은 T7 범위다.

Commit 메시지: feat: 파일 편집부터 migration 실행과 DB 변화 확인까지 Lab UI 구현