LAXWorkspace
비서
알림
온라인입력 4.0M (캐시 85%) · 출력 66.0K
새 대화
세션 목록
지금 설정의 기능탭에서 상속포기하고 상속한정승인 추가 했는데, 현재 메뉴 클릭했을때 안떠. 왜 그런걸까?

기능탭에서 추가한 문서타입이 메뉴에 안 뜨는 문제군요. 코드를 직접 봐야 원인을 알 수 있습니다. 어떻게 등록되고 어떻게 렌더되는지 추적해보겠습니다.

🤖 서브에이전트 · 상속포기 메뉴 미표시 원인 추적
상속포기 메뉴 미표시 원인 추적

LAX-site 코드베이스(C:/Users/user/LAX-site)에서 다음 버그를 조사해줘.

증상: 설정(settings)의 "기능탭"에서 새 문서타입 "상속포기"와 "상속한정승인"을 추가했는데, 실제 메뉴를 클릭했을 때 해당 항목이 안 뜬다.

조사할 것:
1. 설정 기능탭에서 문서타입(기능/메뉴 항목)을 추가/저장하는 코드가 어디인지 (프론트+백엔드, DB 테이블/스키마 포함). "상속포기", "상속한정승인" 문자열이 들어간 데이터가 실제로 저장됐는지 확인할 수 있는 경로.
2. 메뉴를 렌더링하는 코드 — 저장된 문서타입 목록을 읽어 메뉴로 그리는 부분. 왜 새로 추가한 항목이 안 나오는지(필터 조건, 하드코딩된 화이트리스트, enabled 플래그, 캐시, 라우트 매핑 누락 등).
3. 문서타입 → 라우트(/docs/<슬러그> 또는 /complaint-draft?type=...) 매핑이 하드코딩되어 있어서 새 타입이 매핑 누락으로 안 뜨는지.

관련 키워드: 기능, 메뉴, doc_type, 문서타입, 상속포기, 상속한정승인, /docs/, complaint-draft, settings, feature.

코드를 grep/read로 실제로 확인하고, 파일경로:라인과 함께 근본원인 후보를 구체적으로 보고해줘. 추측만 하지 말고 실제 코드 인용으로.
🔍 검색 · 상속포기|상속한정승인
🔍 검색 · doc_type|docType|문서타입
🔍 검색 · complaint-draft
📖 읽기 · routes.tsx
C:\Users\user\LAX-site\src\app\features\routes.tsx
📖 읽기 · doc_slug.ts
C:\Users\user\LAX-site\src\shared\doc_slug.ts
📖 읽기 · 0055_legal_doc_catalog_family.sql
C:\Users\user\LAX-site\migrations\0055_legal_doc_catalog_family.sql
🔍 검색 · legal_doc_catalog
🔍 검색 · in_scope|mvp_built|feature_group
in_scope|mvp_built|feature_group
glob: **/*.{ts,tsx}
🔍 검색 · 기능탭|기능 탭|feature.*tab|설정
기능탭|기능 탭|feature.*tab|설정
glob: **/*.{ts,tsx}
📖 읽기 · doc_nav.ts
C:\Users\user\LAX-site\src\shared\doc_nav.ts
📖 읽기 · DocsEditor.tsx
C:\Users\user\LAX-site\src\app\settings\DocsEditor.tsx
📖 읽기 · 0051_user_doc_selections.sql
C:\Users\user\LAX-site\migrations\0051_user_doc_selections.sql
📖 읽기 · routes.tsx
C:\Users\user\LAX-site\src\app\settings\routes.tsx
🔍 검색 · buildDocNav
📖 읽기 · index.tsx
C:\Users\user\LAX-site\src\app\index.tsx
🔍 검색 · features|/docs
features|/docs
glob: src/app/index.tsx

핵심 원인은 잡혔습니다. 실제 DB 상태를 직접 확인해서 셋 중 무엇인지 확정하겠습니다.

명령 · cd /c/Users/user/LAX-site 2>/dev/null && ls migrations/ | grep -iE "0055|doc_catalog" ; ec…
cd /c/Users/user/LAX-site 2>/dev/null && ls migrations/ | grep -iE "0055|doc_catalog" ; echo "---wrangler/db 위치---"; ls *.toml 2>/dev/null; find . -maxdepth 3 -name "*.sqlite*" 2>/dev/null | grep -v node_modules | head
명령 · find . -path ./node_modules -prune -o -name "*.sqlite" -print 2>/dev/null | head; echo "--…
find . -path ./node_modules -prune -o -name "*.sqlite" -print 2>/dev/null | head; echo "--- local d1 state ---"; ls -d .wrangler/state/v3/d1/miniflare-D1DatabaseObject 2>/dev/null && ls -la .wrangler/state/v3/d1/miniflare-D1DatabaseObject/*.sqlite 2>/dev/null

로컬 D1는 6/23이라 오래됐습니다. 실제 운영(prod) D1에서 상속 관련 카탈로그와 핀 상태를 직접 확인하겠습니다.

명령 · npx wrangler d1 execute axwiki --remote --config wrangler.prod.toml --command "SELECT id, …
npx wrangler d1 execute axwiki --remote --config wrangler.prod.toml --command "SELECT id, doc_name, in_scope, mvp_built, builder_route FROM legal_doc_catalog WHERE doc_name LIKE '상속%'" 2>&1 | tail -30
명령 · grep -A4 "d1_database" wrangler.prod.toml | head -20
명령 · npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT id…
npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT id, doc_name, in_scope, mvp_built FROM legal_doc_catalog WHERE doc_name LIKE '상속%'" 2>&1 | tail -20
메뉴에 보이기만 하면 됨(핀 저장 점검)

메뉴에 보이게만 하면 되는군요. 그런데 핀 메커니즘에 함정이 하나 있어 먼저 확인하겠습니다 — 핀은 폴백을 대체하기 때문에, 2개만 핀하면 기존 코어 9종이 사라질 수 있습니다. 정확한 처리를 위해 로그인 이메일·폴백 동작·코어 구성을 확인합니다.

명령 · cd /c/Users/user/LAX-site; echo "=== getUser ==="; grep -rn "export function getUser\|expo…
cd /c/Users/user/LAX-site; echo "=== getUser ==="; grep -rn "export function getUser\|export const getUser" src/ | head; echo; echo "=== core 카탈로그 ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT id, tab, feature_group, doc_name, mvp_built FROM legal_doc_catalog WHERE in_scope='core' ORDER BY tab, sort_order, id" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);console.log(JSON.stringify(j[0].results,null,0))})"
📖 읽기 · auth.ts
C:/Users/user/LAX-site/src/shared/auth.ts

로그인은 JWT 이메일 기반(멀티유저)입니다. 핀은 계정마다 따로라 불안정하고, 게다가 핀을 걸면 기존 코어 9종이 사라지는 함정이 있습니다. "모두에게 메뉴에 보이게"가 목적이면 정공법은 이 두 항목을 기본 메뉴 집합(in_scope='core')에 편입하는 것입니다. 핀 불필요, 코어 9종도 그대로 유지됩니다.

마이그레이션 번호와 로컬 적용 도구를 확인하고 진행하겠습니다.

명령 · cd /c/Users/user/LAX-site; ls migrations/ | sort | tail -6; echo "=== 773/774 현재 in_scope …
cd /c/Users/user/LAX-site; ls migrations/ | sort | tail -6; echo "=== 773/774 현재 in_scope ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT id,doc_name,tab,feature_group,in_scope,mvp_built,sort_order FROM legal_doc_catalog WHERE id IN (773,774)" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);console.log(JSON.stringify(j[0].results,null,0))})"
명령 · cd /c/Users/user/LAX-site; ls migrations/ | grep -E "^00" | sort | tail -4

다음 마이그레이션은 0064입니다. 773·774를 core로 승격하는 마이그레이션을 작성하고 prod·로컬에 적용하겠습니다.

✏️ 쓰기 · 0064_catalog_inheritance_to_core.sql
C:/Users/user/LAX-site/migrations/0064_catalog_inheritance_to_core.sql
명령 · cd /c/Users/user/LAX-site; echo "=== PROD 적용 ==="; npx wrangler d1 execute lax-prod --remo…
cd /c/Users/user/LAX-site; echo "=== PROD 적용 ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --file migrations/0064_catalog_inheritance_to_core.sql 2>&1 | grep -iE "executed|error|changes" | head; echo "=== LOCAL 적용 ==="; npx wrangler d1 execute lax-prod --local --config wrangler.prod.toml --file migrations/0064_catalog_inheritance_to_core.sql 2>&1 | grep -iE "executed|error|changes" | head

Prod 적용 완료(로컬 D1는 카탈로그 테이블 자체가 없는 구버전 — prod가 라이브이므로 무관). prod에서 실제 nav 폴백 쿼리로 노출 여부를 검증하겠습니다.

명령 · cd /c/Users/user/LAX-site; echo "=== 773/774 승격 확인 ==="; npx wrangler d1 execute lax-prod …
cd /c/Users/user/LAX-site; echo "=== 773/774 승격 확인 ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT id,doc_name,in_scope,mvp_built FROM legal_doc_catalog WHERE id IN (773,774)" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);console.log(JSON.stringify(j[0].results,null,0))})"; echo; echo "=== nav 폴백 쿼리(가사 노출 확인) ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT tab,feature_group,doc_name,mvp_built FROM legal_doc_catalog WHERE in_scope='core' AND tab='가사' ORDER BY sort_order,id" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);console.log(JSON.stringify(j[0].results,null,0))})"

완료. prod에 라이브 반영됐습니다.

처리 결과

항목 상태
원인 핀(user_doc_selections)이 비어 메뉴가 코어 9종 폴백 상태였고, 상속포기/상속한정승인은 in_scope='out'이라 폴백에 미포함
조치 마이그레이션 0064 — 773·774를 in_scope='core'로 승격 (prod 적용·검증 완료)
반영 위치 lax-prod D1, legal_doc_catalog id 773/774 → in_scope=core 확인됨
코드/배포 불필요buildDocNav가 매 요청마다 DB를 읽는 데이터 구동 방식. 페이지 새로고침만 하면 즉시 메뉴에 뜸

이제 사이드바 가사 → 라류 가사비송사건 아래에 두 항목이 표시됩니다. 단, 작성기가 아직 없으므로 "준비중" 배지로 뜨고, 클릭하면 안내 페이지가 나옵니다(요청대로 "보이기만" 충족).

왜 핀 방식을 안 썼나 (중요)

핀은 계정(이메일)별이고, 핀을 하나라도 걸면 코어 9종 폴백이 꺼져 나머지가 사라지는 함정이 있습니다. "모든 화면에 안정적으로 보이게"가 목적이라 폴백 집합(core) 자체에 편입하는 정공법을 택했습니다 — 핀 불필요, 기존 9종도 그대로.

참고: 나중에 누군가 기능탭에서 서류를 핀하기 시작하면 그 계정은 폴백이 꺼지므로, 그때는 상속 항목도 함께 핀해야 유지됩니다. 지금은 핀이 전무해 영향 없습니다.

사이드바에서는 보이는데, 설정의 기능 창에서 현재 메뉴 보이게 했을때 안떠.

사이드바엔 떴는데, 설정 기능창의 "현재 메뉴 보이게" 필터에 안 나오는군요. 그 필터가 무엇을 기준으로 거르는지 코드를 정확히 봐야 합니다.

📖 읽기 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

필터 로직이 확인됐습니다. "현재 메뉴" 필터(data-filter="pinned")는 체크박스가 체크된 행만 보여줍니다. 그런데 체크 여부는 checked={!!sel} — 즉 핀(user_doc_selections) 기준입니다. 핀이 0개라 어떤 것도 체크돼 있지 않아 "현재 메뉴" 필터엔 아무것도 안 나옵니다.

실제 사이드바는 in_scope='core' 폴백으로 그려지는데, 설정 편집기는 "현재 메뉴 = 핀"으로 보고 있어 둘이 어긋나는 것입니다. 데이터 전달부를 확인해 정확히 고치겠습니다.

📖 읽기 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

전체 구조가 명확합니다. DocsEditor는 이미 in_scopeusingFallback를 받습니다. 체크 표시를 핀뿐 아니라 "폴백 중인 core 항목"도 체크되도록 고치면, "현재 메뉴" 필터가 실제 사이드바와 일치합니다(저장하면 그 상태가 내 핀으로 굳음 — 안내문 그대로). 외과적으로 수정합니다.

✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

수정 완료. 이제 빌드 후 배포해야 반영됩니다(서버 렌더 컴포넌트). 빌드·배포 절차를 확인해 실행합니다.

명령 · cd /c/Users/user/LAX-site; node -e "const p=require('./package.json').scripts; for(const k…
cd /c/Users/user/LAX-site; node -e "const p=require('./package.json').scripts; for(const k of ['build','deploy','deploy:prod','check:client','check']) if(p[k]) console.log(k.padEnd(14),'=',p[k])"
명령 · cd /c/Users/user/LAX-site; npm run deploy 2>&1 | tail -25

배포 완료(prod, branch=main).

정리

항목 내용
증상 사이드바엔 상속포기/상속한정승인이 뜨는데, 설정 기능창의 "현재 메뉴" 필터엔 안 뜸
원인 사이드바는 in_scope='core' 폴백으로 그려지는데, 설정 편집기는 "현재 메뉴 = 핀된 것(체크된 체크박스)"으로만 판단. 핀이 0개라 어떤 항목도 체크 안 돼 "현재 메뉴" 필터가 빔 → 편집기와 실제 메뉴가 어긋남
조치 DocsEditor.tsx — 폴백 상태(usingFallback)일 때 in_scope='core' 항목도 체크된 것으로 표시하도록 수정. 이제 편집기 체크 상태 = 실제 사이드바 메뉴
반영 빌드+wrangler pages deploy prod 배포 완료

이제 설정 → 기능 화면을 새로고침하면, "현재 메뉴" 필터에 코어 9종 + 상속포기/상속한정승인이 체크된 상태로 함께 보입니다. (이 상태에서 저장을 누르면 안내문대로 그 구성이 내 핀으로 굳습니다.)

참고: 이건 "현재 메뉴"의 정의가 편집기에선 , 실제론 폴백이라 갈라져 있던 표시 불일치였습니다. 데이터(773·774 core 승격)는 이미 맞았고, 이번엔 편집기 표시 로직만 실제 메뉴에 맞췄습니다.

여전히 안뜨는데?
image.png

첨부 이미지를 먼저 확인하겠습니다.

📖 읽기 · 0-image.png
C:/Users/user/AppData/Local/Temp/wikicomu-att/294/0-image.png

화면을 보니 상황이 처음과 달라졌습니다. 지금은 핀이 실제로 저장돼 있고(소장·반소장·준비서면·가압류·가처분·지급명령 등 체크됨), 좌측 사이드바엔 상속포기/상속한정승인이 떠 있습니다. 그런데 지금 보고 계신 탭은 민사서류 탭이라, 가사 항목이 안 보이는 것일 수 있습니다. prod 핀 상태를 직접 확인해 확정하겠습니다.

명령 · cd /c/Users/user/LAX-site; npx wrangler d1 execute lax-prod --remote --config wrangler.pro…
cd /c/Users/user/LAX-site; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT s.email, s.doc_id, c.tab, c.doc_name, s.pinned FROM user_doc_selections s JOIN legal_doc_catalog c ON c.id=s.doc_id WHERE s.pinned=1 ORDER BY s.email, c.tab, s.sort_order" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);const r=j[0].results;console.log('총',r.length,'핀');console.log(JSON.stringify(r,null,1))})"

0 핀입니다. 그렇다면 폴백 상태(usingFallback=true)인데, 화면의 민사 항목들(반소장·가압류·가처분)은 제가 본 core 9종과 안 맞습니다. 뭔가 어긋나 있습니다. 현재 core 집합 전체와 화면 항목들의 실제 in_scope를 확인하겠습니다.

명령 · cd /c/Users/user/LAX-site; echo "=== 현재 core 전체 (탭별) ==="; npx wrangler d1 execute lax-pro…
cd /c/Users/user/LAX-site; echo "=== 현재 core 전체 (탭별) ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT tab, feature_group, doc_name FROM legal_doc_catalog WHERE in_scope='core' ORDER BY tab, sort_order, id" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);console.log(JSON.stringify(j[0].results))})"; echo; echo "=== 화면에 체크된 민사 항목들 in_scope ==="; npx wrangler d1 execute lax-prod --remote --config wrangler.prod.toml --command "SELECT doc_name, in_scope, mvp_built FROM legal_doc_catalog WHERE doc_name IN ('반소장','민사 가압류신청서','민사 가처분신청서','소장','준비서면','지급명령신청서')" --json 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{const j=JSON.parse(d);console.log(JSON.stringify(j[0].results))})"

핵심을 찾았습니다. 모순이 풀렸습니다.

화면의 "현재 메뉴" 필터는 현재 활성 탭(민사서류)에 한정됩니다. 필터 JS(DocsEditor.tsx:226)가 okTab = searching || rowTab===active — 즉 검색 중이 아니면 활성 탭 행만 보여줍니다. 상속포기/상속한정승인은 가사 탭에 있는데 지금 화면은 민사서류 탭이라, "현재 메뉴"를 눌러도 가사 항목은 절대 안 뜹니다.

즉 데이터·체크는 정상이고(좌측 사이드바엔 이미 보임), 설정창의 필터가 탭에 갇혀 있는 게 문제입니다. 필터 스크립트 전체를 보고 "현재 메뉴/메뉴 없음" 필터는 탭 무관 전체를 보이도록 고치겠습니다.

📖 읽기 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

필터 스크립트를 수정합니다. "현재 메뉴"·"메뉴 없음" 필터는 검색처럼 탭 무관 전체를 보이고, 탭 버튼을 누르면 다시 그 탭의 "전체"로 돌아가도록 합니다.

✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx
✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

Now build and deploy.

명령 · cd /c/Users/user/LAX-site; npm run deploy 2>&1 | tail -8

배포 완료(prod).

원인과 조치

화면을 보니 데이터·표시는 정상이었습니다 — 좌측 사이드바엔 상속포기/상속한정승인이 이미 떠 있죠. 문제는 설정창의 "현재 메뉴" 필터가 활성 탭(민사서류)에만 갇혀 있던 것입니다.

구분 내용
왜 안 떴나 "현재 메뉴" 필터(DocsEditor.tsx)가 okTab = 검색중 || 활성탭 조건이라, 검색 안 하면 활성 탭 행만 보임. 상속포기/상속한정승인은 가사 탭, 화면은 민사서류 탭 → 안 보임
조치 "현재 메뉴"·"메뉴 없음" 필터는 검색처럼 모든 탭을 가로질러 표시하도록 수정. 탭 버튼을 누르면 다시 그 탭의 "전체"로 복귀
반영 빌드+prod 배포 완료, 카운트에 통합 N건 표기

확인 방법: 설정 → 기능 페이지를 새로고침한 뒤 상단 **"현재 메뉴"**를 누르면, 이제 탭과 무관하게 현재 메뉴 전체(민사 + 가사의 상속포기·상속한정승인 + 민사집행 등)가 한 화면에 뜹니다. (가사만 따로 보려면 상단 가사서류 탭 버튼을 눌러도 됩니다.)

참고: 직전까지는 ① 데이터(773·774 core 승격) ② 편집기 체크 표시 동기화까지 맞췄지만, 필터의 탭 스코프라는 세 번째 층이 남아 있었습니다. 이번에 그걸 풀었습니다.

잘 돼 이제. 그리고 오른쪽에 순서 바꾸기 위해서 숫자로 쓰게 하지말고 드래그 앤 드랍으로 순서 바꿀 수 있게 해줄래.

잘 됐다니 좋습니다. 이제 우측 숫자 입력을 빼고 드래그 핸들로 순서를 바꾸도록 바꾸겠습니다. 행 구조(숨김 sort 값 유지)와 드래그 스크립트를 수정합니다.

✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx
✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

핸들 추가·드래그 스크립트 완료. 빌드(클라이언트 가드 포함)와 배포를 실행합니다.

명령 · cd /c/Users/user/LAX-site; npm run deploy 2>&1 | tail -12

배포 완료(prod).

변경 내용

항목 내용
제거 우측 숫자 입력칸sort 값은 숨김 필드로 내부 유지(저장 로직 그대로)
추가 행 우측에 드래그 핸들(⠿) — 잡고 끌어 순서 변경
동작 같은 그룹(예: 소제기, 보전처분) 안에서 행을 끌어 재배치. 놓으면 DOM 순서대로 정렬값이 자동 재부여됨
반영 DocsEditor.tsx 수정, 빌드(클라이언트 가드 통과)+prod 배포 완료

사용법

설정 → 기능 새로고침 → 행 오른쪽 ⠿ 핸들을 잡고 위아래로 끌면 순서가 바뀝니다. 끌리는 행은 반투명으로 표시됩니다. 원하는 순서로 맞춘 뒤 하단 저장을 누르면 사이드바에 그 순서로 반영됩니다.

참고: 드래그 재배치는 같은 그룹 내에서 동작합니다(그룹 자체 순서는 카탈로그 구조 기준 고정). 그룹을 가로지르는 재배치까지 필요하면 알려주세요.

대분류 중분류 소분류가 있다고 친다면 민사서류같은게 대분류고, 소제기 같은게 중분류고, 소장, 반소장 같은게 소분류잖아. 이것들 섹션 구분 확실하게 UI 개선해주고, 중분류끼리의 순서도 변경 가능하게 할까 말까? 네 추천은?

좋은 질문입니다. 먼저 현재 섹션 마크업을 정확히 보고, 위계 UI를 개선하겠습니다. 그리고 중분류 순서변경은 추천을 드리겠습니다.

📖 읽기 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx

위계가 약합니다(대분류 h2, 중분류 h3가 둘 다 흐릿한 텍스트). 섹션 구분을 명확히 개선하겠습니다 — 대분류는 좌측 컬러바+배경, 중분류는 카드+액센트+개수, 소분류는 그 안의 리스트로 들여쓰기.

✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx
명령 · cd /c/Users/user/LAX-site; npm run deploy 2>&1 | tail -6

UI 개선 배포 완료. 새로고침하면 대분류(좌측 인디고 바+배경+"대분류" 태그) / 중분류(카드+액센트 점+항목 개수) / 소분류(카드 안 리스트)로 위계가 또렷해집니다.

중분류 순서변경 — 내 추천: 하자 (YES)

근거를 정리하면:

관점 판단
구현 비용 낮음. 정렬값을 이미 "DOM 순서대로 전역 재부여"하는 구조라, 중분류 블록을 통째로 끌어 옮기면 그대로 반영됨. 중분류 헤더에 핸들 추가 + 같은 대분류 내 재배치 로직만 더하면 됨
사용자 가치 있음. 자주 쓰는 그룹(예: 지급명령신청·소제기)을 위로 올리는 건 실제로 유용. "내 메뉴를 완전히 내 손으로 정렬" 모델이 완성됨
UX 리스크 드래그가 2층(중분류/소분류)이 되어 헷갈릴 수 있음 → 중분류는 헤더(카드 상단)의 핸들로, 소분류는 행 우측 핸들로 위계를 시각적으로 분리하면 해소됨
주의 대분류(민사/형사/가사…) 순서는 코드에 고정(TAB_ORDER)이라 그대로 둠 — 거긴 바꿀 일이 거의 없음

즉, **"대분류 고정 · 중분류/소분류는 드래그로 자유 정렬"**이 가장 깔끔한 완성형이라 봅니다. 비용 대비 효용이 좋아 추가를 추천합니다.

@@ASK@@eyJxIjoi7KSR67aE66WYKOq3uOujuSkg7Iic7ISc64+EIOuTnOuemOq3uOuhnCDrsJTqvrjqsowg7LaU6rCA7ZWg6rmM7JqUPyIsIm8iOlsi7LaU7LKc64yA66GcIOy2lOqwgCAo7KSR67aE66WYIO2XpOuNlCDtlbjrk6QpIiwi7KeA6riI7J2AIOyGjOu2hOulmOunjCDsnKDsp4AiLCLrjIDrtoTrpZjquYzsp4Ag7KCE67aAIOuTnOuemOq3uCDqsIDriqXtlZjqsowiXSwibSI6ZmFsc2V9@@

추천대로 추가 (중분류 헤더 핸들)

추천대로 진행합니다. 중분류 헤더에 핸들을 달고, 같은 대분류 안에서 그룹 블록을 끌어 재배치하도록 추가하겠습니다(대분류는 고정). 정렬값은 기존 전역 재부여 로직이 그대로 처리합니다.

✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx
✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx
명령 · cd /c/Users/user/LAX-site; npm run deploy 2>&1 | tail -6

배포 완료(prod).

추가된 것 — 중분류(그룹) 드래그 순서변경

레벨 핸들 위치 동작 범위
대분류(민사서류 등) 없음(고정) 코드 고정 순서
중분류(소제기 등) 그룹 헤더 우측 ⠿ 같은 대분류 안에서 그룹 블록째 이동
소분류(소장 등) 행 우측 ⠿ 같은 중분류 안에서 행 이동
  • 그룹 헤더의 ⠿를 잡고 끌면 그 중분류 카드가 통째로 위아래로 이동합니다(같은 대분류 내에서만, 끌리는 동안 반투명).
  • 소분류·중분류 어느 쪽을 옮기든 놓는 순간 정렬값이 DOM 순서대로 전역 재부여되어, 저장 시 사이드바에 그 순서로 반영됩니다.
  • 두 드래그가 서로 간섭하지 않도록 핸들·플래그를 분리했고, 그룹 이동은 같은 부모(=같은 대분류) 내로 제한했습니다.

새로고침 후 설정 → 기능에서 확인하시면 됩니다. 위계 구분(대/중/소분류) + 중분류·소분류 드래그 정렬이 모두 적용된 상태입니다.

이거 드래그할때는 스크롤이 안되서 불편하네. 그리고 드래그 하면 바로 적용되는거야?

두 가지 — 드래그 중 자동 스크롤이 없어서 긴 목록 이동이 불편한 거고, 적용 시점 질문이네요. 자동 스크롤을 추가하겠습니다.

먼저 저장 시점을 코드로 확인합니다.

✏️ 편집 · DocsEditor.tsx
C:/Users/user/LAX-site/src/app/settings/DocsEditor.tsx
📖 읽기 · routes.tsx
C:/Users/user/LAX-site/src/app/settings/routes.tsx

확인됐습니다 — 순서 변경은 POST /docs/save(저장 버튼)로만 DB에 반영됩니다. 자동 스크롤을 배포합니다.

명령 · cd /c/Users/user/LAX-site; npm run deploy 2>&1 | tail -6

배포 완료(prod). 두 가지 답변입니다.

1. 드래그 중 자동 스크롤 추가됨

이제 항목을 끌고 화면 위/아래 가장자리(약 90px)로 가져가면 그 방향으로 자동 스크롤됩니다. 가장자리에 멈춰 있어도 계속 스크롤되고(끝까지 닿을 때까지), 가장자리에서 멀어지면 멈춥니다. 새로고침 후 적용됩니다.

2. 드래그하면 바로 적용되나? → 아니요

시점 상태
드래그로 순서 바꿈 화면에서만 재배치 + 내부 정렬값 갱신 (아직 임시)
하단 저장 클릭 그때 POST /docs/save로 DB 반영 → 사이드바 메뉴에 순서 적용

즉 드래그는 미리보기이고, 저장을 눌러야 실제 메뉴에 반영됩니다. 체크박스(메뉴 추가/제거)도 동일하게 저장 시 한 번에 커밋됩니다. 그래서 마음껏 배치를 바꾼 뒤 마지막에 한 번 저장하면 됩니다.

참고: "드래그 즉시 자동저장"으로 바꾸는 것도 가능합니다(드롭할 때마다 서버 반영). 다만 체크박스 변경과 저장 시점이 갈려 헷갈릴 수 있어 지금은 단일 저장 모델을 유지했습니다. 즉시저장을 원하시면 그쪽으로 바꿀게요.