Crowny INT 트리맵(/map) + 오버레이 편집 API
개요
crowny-int2에 기관 레지스트리 트리맵 페이지(/map)와 개발자(dev) 계정용 기관 필드 편집 API(POST /api/orgs/edit)를 신설. 기존 data/기관.psv(v2, 104기관, 11필드)는 무수정 유지하고, data/기관수정.psv(append-only latest-wins 오버레이)로 구축/동/웹사이트/확인일자 필드만 실시간 수정 가능하게 함.무엇을 했는지
서버 (INT서버.한선, 1922→2092줄)
- asof 추출: top-level 기관 파싱 블록에서 헤더 주석
# 행정동 기준일: 2026-07-23을 파싱해 전역_기준일에 저장./api/orgs/summary응답에"asof"필드 추가. - 오버레이 적용(
_오버레이적용()):data/기관수정.psv(ts|by|아이디|필드|값,_PSV이스케이프됨)를 top-level에서 읽어 순서대로 적용(append 순서 = latest-wins, 별도 맵 불필요). 구축 필드는 플래그 갱신 +_기관구축합계증분. /api/orgs확장: 각 기관 객체에dong/web/asof필드 추가.POST /api/orgs/edit신설(_처리기관수정): 세션 401 → role≠dev 403 → scope(전체/용인시/고양시, 도청·시청급 si="-"는 전체만) 403 → 필드 화이트리스트(구축/동/웹사이트/확인일자) 400 → 대상 미존재 404 → 통과 시 오버레이 append + 즉시 in-memory 반영(설정()) + 해시체인 감사(_블록추가("orgedit",...)).- 라우트:
/map→public/트리맵.html,/api/orgs/edit→ 신설 핸들러. - 부수 추가:
/api/auth/login·/api/auth/check응답에scope필드 추가(클라이언트가 편집 모드 게이팅에 필요, 기존 소비자와 호환 유지하는 additive 필드).
⚠ 신규 VM 함정 발견 (2026-07-23, 이 작업 중 실측)
INT서버.한선 메인루프는 요청마다문자열마크()→처리→문자열되감기(마크)로 문자열풀을 되감아 요청 임시문자열을 일괄 폐기한다(str_pool_ptr 요청 시작점 복귀). 요청 처리 중 전역 배열(예: _기관웹)에 설정()으로 새로 써넣은 문자열도 "요청 임시문자열"로 취급되어 요청 종료 시 되감긴다 — 이후 요청들이 같은 풀 오프셋에 새 문자열을 할당하면서 해당 값이 조용히 다른 문자열로 뒤바뀐다(컴파일/런타임 에러 없음, 응답마다 값이 계속 달라짐). 최초 라이브 편집 테스트에서 영덕1동.web이 "경" → "\n" → "도"로 요청마다 드리프트하는 것으로 발견.수정: 전역 배열에 문자열을 설정()한 직후 문자열보호()를 호출해 보호경계(str_protect_count)를 현재 지점까지 전진시키면 문자열되감기의 하한선이 그 이후로는 못 내려가 값이 영속화된다. _처리기관수정에 반영 완료, 10회 연속 조회로 드리프트 없음 재검증. 이 패턴은 런타임에 전역 배열/구조에 새 문자열을 쓰는 모든 요청-루프 서버에 재발 가능 — 다른 crownyc 서버(요청당 문자열되감기 쓰는 서버 전반)도 동일 패턴 점검 필요. ~/.claude/templates/한선씨-가드레일.md에 반영 권장(별도 조치 필요).
클라이언트 (public/트리맵.html, 신규)
경기도청(루트, 클릭 로그인 가능) → 시(용인시/고양시, 시청 노드 포함) → 구 → 유형 그룹 → 기관(leaf) 트리. 브라운 다크 팔레트, 인라인 스타일만. asof 배너, 그룹별 "구축 n/총 m" 배지, leaf 구축/미구축 배지 + 웹링크(↗) + 동 표기. 노드 클릭 → 로그인 모달 → 성공 시 role별 상세 패널(leaf=사용자 탭, admin=관리자 탭 하위집계, dev=편집모드 배너). 개발자 계정 로그인 시 scope 내 기관에만 ✎ 인라인 편집 폼 노출 →POST /api/orgs/edit. 세션은 sessionStorage 유지, 헤더 로그인 버튼으로 dev 로그인도 가능(트리 클릭 없이).판정 파일 (public/트리맵-판정.한선, 신규)
서버 무접촉 순수 미러: ① scope×기관시 편집허용 판정(9케이스 셀프테스트) ② 기관.psv 로드 + 시별 구축/총계 집계 ③ 오버레이 latest-wins 적용 미러. 셀프테스트 21건 전체 PASS.관련 파일
/Users/ef/crowny-int2/INT서버.한선(수정, 2092줄) / 백업INT서버.한선.bak-트리맵전(1922줄, 원본)/Users/ef/crowny-int2/public/트리맵.html(신규)/Users/ef/crowny-int2/public/트리맵-판정.한선(신규)/Users/ef/crowny-int2/data/기관수정.psv(신규, append-only 오버레이 — 시험 이력 6줄 포함, latest-wins으로 원본값 복원됨)/Users/ef/crowny-int2/data/기관.psv(무수정 확인, md5 5a0dbe394d629d3e3cc3acda6c9cc790)
검증
hanseonc_highSTRICT(CROWNY_STRICT=1) 컴파일 경고 0건 (서버·판정 파일 모두)- 판정 파일 셀프테스트 21/21 PASS
- 로컬 서브(9500) 재기동 후 종단 curl:
/map200,/api/orgs(dong/web/asof 포함),/api/orgs/summary(asof 포함), 로그인(scope 필드 포함), scope 게이트(403/403 role/400 field/404 not_found), 라이브 편집 반영 + 재기동 후 persist 확인, 기존 회귀(/health,/,/orgs,/tablet,/mobile,/bar,/guide,/module,/api/status,/api/chain/*) 전부 200/정상 - 시험 편집값은 append-only 유지, 원복 커밋 3건 추가로 원본값(built=12/104) 복원 확인
잔여 이슈
/api/orgs/summary의byCity/byType집계는 여전히awk로 원본기관.psv를 직접 읽음(오버레이 미반영) — top-leveltotal/built/unbuilt는 오버레이 반영(정확), byCity의 시별 built 세부값은 오버레이로 구축 플립된 기관을 반영하지 못함. 재구현하려면 awk 대신 in-memory 배열 순회로 교체 필요(향후 작업).- VPS 배포 미실행(지시에 따라 메인 세션 독립 검증 후 수행 예정).
- 발견한 "요청당 문자열되감기 + 전역배열 설정() 드리프트" VM 함정을
~/.claude/templates/한선씨-가드레일.md에 아직 반영 안 함 — 다음 세션에서 추가 권장.