Skip to content

관리자 Material 레일·반응형 데이터 UI 회귀

항목고정값
frontend revisionfbed8f864542ddd26d6756e368a003795c669adf
frontend tree05f0343c0db9de667d35eba53ccc6b2add59fa80
production build digestsha256:1c0e8c638d866f77e4bd51cb35d176e4b455d6b8ee01ce2ad5256cb52f5d3052
Astro7.1.0
MUI Material / Icons9.2.0
TanStack React Table8.21.3
capture / conversionPlaywright CLI 0.1.17, HeadlessChrome 146.0.0.0, Sharp 0.34.5 lossless
environmentlocal production Astro build · route interception 없음 · mock network 없음

MUI 9.2.0에는 native Navigation Rail component가 없다. 따라서 이 화면은 native rail이라고 과장하지 않고, Google Material 3 지침을 MUI permanent/temporary Drawer와 list primitive로 구성한 M3-informed rail이다. table과 card는 TanStack의 같은 getRowModel()을 소비한다. 현재 component capability, 결손, MIT 라이선스, upgrade trigger는 관리자 Material navigation·data UI trap sheet에 고정했다.

Navigation은 viewport, data collection은 자신의 container를 기준으로 판단한다.

경계navigationdata mode
viewport 0–599pxapp bar + temporary drawer 296px각 collection 폭에 따름
viewport 600px 이상permanent rail 88px / expanded 280px각 collection 폭에 따름
standard collection 0–899px해당 없음별도 vertical card collection
standard collection 900px 이상해당 없음semantic table
wide collection 0–1119px해당 없음별도 vertical card collection
wide collection 1120px 이상해당 없음semantic table

따라서 1440px viewport라도 rail을 280px로 확장해 content container가 좁아지면 열이 많은 출산정보·일일 리포트는 card로 바뀐다. table을 억지로 줄이거나 horizontal scroll 안에 숨기지 않는다.

viewport / railnavigation / body offsettable groupcard group / cardwidth invariant
390x844app bar, drawer 296px04 / 19390 = 390
599x420app bar, body offset 004 / 19599 = 599
600x420rail 88px, body offset 88px04 / 19600 = 600
1024x900rail 88px, body offset 88px04 / 191024 = 1024
1440x900 collapsedrail 88px, body offset 88px40 / 01440 = 1440
1440x900 expandedrail 280px, body offset 280px22 / 101440 = 1440

expanded 상태에서 rail right는 280px, heading left는 312px였다. rail이 본문 앞 192px를 덮던 overlay 결함과 600–899px의 빈 88px gutter가 모두 재현되지 않았다.

1440픽셀 관리자 화면에서 88픽셀 레일과 280픽셀 레일 사이를 전환할 때 본문도 함께 재배치되고 wide table은 card로 바뀌는 두 프레임 회귀
Rail reflow · 88px → 280px · body offset도 동일하게 전환 · overlay 0
같은 출산정보 row model이 넓은 container에서는 표이고 좁아진 container에서는 세로 카드로 표시되는 두 프레임 회귀이며 식별 정보는 마스킹됨
Wide collection · semantic table ↔ vertical cards · capture-time privacy masking
599픽셀 관리자 화면의 상단 app bar와 카드형 데이터
599px · app bar · body offset 0 · table 0
600픽셀 관리자 화면의 88픽셀 permanent rail과 카드형 데이터
600px · permanent rail 88px · body offset 88px · blank gutter 0
390픽셀 관리자 지점 실적이 각 항목 label과 value를 세로로 읽는 카드 목록으로 표시됨
390px · branch card crop 358x1607 · horizontal overflow 0
1024픽셀 관리자 지점 실적이 좁은 collection 안에서 세로 카드 목록으로 표시됨
1024px · viewport가 아니라 collection width로 card 선택
1440픽셀 collapsed rail 관리자 화면에서 지점 실적이 caption을 가진 semantic table로 표시됨
1440px collapsed · all table groups 4 · card groups 0
1440픽셀 collapsed rail에서 출산정보가 마스킹된 semantic table로 표시됨
wide container · birth table · safe Korean placeholders
1440픽셀 expanded rail에서 출산정보가 마스킹된 세로 카드 목록으로 치환됨
same viewport, narrower container · birth cards · safe Korean placeholders
390픽셀 관리자 화면에서 296픽셀 temporary drawer가 열린 상태
390px · temporary drawer · Enter open / Escape close / focus return
1440px rail 정적 frame 보기
1440픽셀 88픽셀 collapsed rail과 재배치된 관리자 본문
collapsed · rail/body 88px · table 4
1440픽셀 280픽셀 expanded rail과 재배치된 관리자 본문
expanded · rail/body 280px · table 2 + card group 2
  1. A — 범위 고정 fixture UI regression이며 actor·business acceptance가 아님을 먼저 고정한다.
  2. B — revision 고정 clean frontend revision, tree, production build digest가 위 표와 같은지 확인한다.
  3. C — OSS 권위 확인 Material adaptive navigation, MUI v9 Drawer/container query, TanStack v8 공식 문서를 확인한다.
  4. D — focused behavior test AdminNavigation, AdminShell, AdminResponsiveDataCollection과 dashboard 관련 6개 test file, 12개 test를 통과시킨다.
  5. E — full frontend gate 전체 89개 file, 563개 test와 lint, Astro check를 통과시킨다.
  6. F — production build Astro build를 통과시키고 dist 정렬 hash를 기록한다.
  7. G — local runtime Node standalone production output을 loopback에서 실행한다.
  8. H — browser 격리 새 Playwright session을 열고 route interception과 mock을 추가하지 않는다.
  9. I — 599 compact boundary app bar, body offset 0, table 0, card group 4, horizontal overflow 0을 확인한다.
  10. J — 600 rail boundary permanent rail 88px와 body offset 88px가 동시에 시작하는지 확인한다.
  11. K — medium collection 1024px에서 네 collection이 모두 card이고 table은 0인지 확인한다.
  12. L — wide collapsed 1440px collapsed에서 rail/body 88px, table 4, card group 0인지 확인한다.
  13. M — expanded reflow 실제 toggle로 rail/body를 280px로 바꾸고 rail right 280px보다 heading left가 큰지 확인한다.
  14. N — container response 같은 1440px에서 standard table 2개는 남고 wide collection 2개만 card 10개로 바뀌는지 확인한다.
  15. O — mobile drawer Enter로 열고 Escape로 닫은 뒤 focus가 menu button으로 돌아오는지 확인한다.
  16. P — navigation destination dashboard와 신규 지점 개설 두 실제 목적지가 모두 HTTP 200인지 검사한다.
  17. Q — width invariant 각 viewport에서 documentWidth와 clientWidth가 viewport width와 같은지 검사한다.
  18. R — mutually exclusive mode 각 collection에서 table과 card group이 동시에 보이지 않는지 검사한다.
  19. S — shared row model desktop table과 narrow card가 같은 TanStack getRowModel()을 소비하는지 source/test로 확인한다.
  20. T — semantic table desktop table에 head/body와 실제 caption이 있는지 확인한다.
  21. U — console 전체 전환 뒤 browser console error와 warning이 각각 0인지 확인한다.
  22. V — CSP / Emotion nonce style-src-elem의 self·nonce, style-src-attr의 unsafe-inline 분리와 header/DOM nonce 일치를 확인한다.
  23. W — privacy masking 식별·출산 fixture가 있는 두 capture는 PNG 작성 전에 안전한 Korean placeholder로 바꾼다.
  24. X — lossless WebP Sharp effort 6 lossless로 metadata를 제거한 10개 static·2개 animated WebP를 만든다.
  25. Y — manifest gate viewport와 element-crop 크기, asset hash, frame source/order, privacy review, canonical exclusion을 검사한다.
  26. Z — 범위 판정 UI regression만 PASS로 기록하고 phase·migration 완료 판정은 바꾸지 않는다.
검사관측
response cacheprivate, no-store
CSPstyle-src-elem self + request nonce, style-src-attr unsafe-inline
nonceheader 24 chars, DOM unique 1, header/DOM match true
Emotion stylestyle element 176, nonce style element 174
browserconsole error 0, warning 0, dead navigation 0
accessibility interactionEnter open, Escape close, focus return
privacycapture-time opaque safe placeholders, production data false, unmasked person data false

Machine SSOT는 docs/evidence/admin-material-responsive-ui/manifest.json, privacy 판정은 같은 디렉터리의 privacy-review.md다. checker는 genuine WebP bytes/hash/frame count뿐 아니라 viewport 크기와 element crop 크기를 분리해 검사하고, animation source 순서와 container-threshold 관측도 고정한다.

canonical docs/evidence/visual-evidence.json에는 이 fixture 회귀를 scenario/feature/step으로 추가하지 않았다. canonical actor registry가 요구하는 실제 actor outcome을 가장하지 않기 위해서다.

pnpm test:admin-material-evidence pnpm docs:admin-material-evidence:check pnpm docs:visual-evidence:check pnpm docs:check pnpm docs:build

영구 capture harness는 추가하지 않았다. 기존 Playwright CLI와 frontend-pinned Sharp가 이미 capture/conversion capability를 소유한다. 이 페이지의 A→Z와 manifest가 재캡처 입력을, 별도 checker가 게시 산출물의 불변성을 소유한다.