[P1] [이력관리] 헤더 월 선택 기준 월말 조직현황 조회 및 버전 누적 저장 #9

Open
opened 2026-03-26 18:04:38 +09:00 by hyunho · 5 comments
Owner

배경

현재 조직현황 화면에는 헤더에 월 선택 UI가 이미 존재한다.
이 이슈의 핵심 목적은 별도 월간 스냅샷 파일을 만드는 것이 아니라, 헤더에서 특정 월을 선택했을 때 그 달의 마지막 날 기준 조직현황을 확인할 수 있게 하는 것이다.

즉 화면 기능 기준으로 보면 아래가 목표다.

  • 현재 월 선택 시: 실시간 조직현황 표시
  • 과거 월 선택 시: 해당 월 마지막 날 기준 조직현황 표시

이를 위해 필요한 이력 데이터는 DB 내부 버전 구조로 처리하고, 파일 생성/다운로드 방식은 개발 목표에서 제외한다.

목표

  • 헤더에서 월을 선택하면 조직현황이 그 달 마지막 날 기준으로 다시 조회된다.
  • 현재 월은 항상 실시간 조직현황을 보여준다.
  • 과거 월은 member_versions, seat_assignment_versions, history_revisions 기반으로 월말 상태를 재구성한다.
  • 조직현황 메인과 리스트/비교 흐름이 같은 기준일 해석을 사용한다.

범위 포함

  • members / member_versions 기반 월말 조회 정리
  • 필요 시 seat_assignment_versions와 함께 조직현황 seat preview 기준일 정리
  • 조직현황 관련 write 시 version row가 누적되도록 백엔드 보강
  • 헤더 월 선택 -> 조직현황 iframe -> /api/members?as_of=... 흐름 정합화
  • 현재 월은 실시간, 과거 월은 월말 기준이라는 규칙 고정

범위 제외

  • 월간 스냅샷 파일 생성
  • 월간 스냅샷 다운로드
  • 별도 파일 기반 보관 기능
  • 화면 전체를 새로운 앱 구조로 승격하는 구조 리팩터링

현재 상태

  • member_versions, seat_assignment_versions, history_revisions 기본 구조는 이미 반영됨
  • /api/members?as_of=... 와 조직현황 비교 UI도 최소 동작 범위는 있음
  • 헤더 월 선택 UI도 존재함
  • 다만 목표를 보면 중요한 것은 "월을 눌렀을 때 해당 월 말일 조직현황이 정확히 보이는가"이며, 이 관점에서 백엔드 이력 누적/해석을 더 분명히 해야 함

완료 조건

  • 헤더에서 현재 월을 선택하면 실시간 조직현황이 보인다.
  • 헤더에서 과거 월을 선택하면 그 달 마지막 날 기준 조직현황이 보인다.
  • 조직현황 메인, 리스트 기준일 조회, 변경 비교가 같은 이력 기준을 사용한다.
  • 월말 조회를 위해 별도 스냅샷 파일이나 다운로드 기능을 만들지 않는다.

구현 방향

  • 프런트는 기존 헤더 월 선택 UI를 최대한 유지
  • 백엔드에서 as_of와 revision/version 누적 로직을 보강해 월말 조회를 신뢰 가능하게 만드는 방향 우선
  • 화면 표출 변경이 필요하면 그 시점에 별도 조정

참고

  • docs/HISTORY_ASOF_DB_PLAN.md
  • 현재 기준 해석: 이 이슈는 "월간 스냅샷 기능"이 아니라 "월말 기준 조직현황 조회 기능" 이슈로 본다.
### 배경 현재 조직현황 화면에는 헤더에 월 선택 UI가 이미 존재한다. 이 이슈의 핵심 목적은 별도 월간 스냅샷 파일을 만드는 것이 아니라, **헤더에서 특정 월을 선택했을 때 그 달의 마지막 날 기준 조직현황을 확인할 수 있게 하는 것**이다. 즉 화면 기능 기준으로 보면 아래가 목표다. - 현재 월 선택 시: 실시간 조직현황 표시 - 과거 월 선택 시: 해당 월 마지막 날 기준 조직현황 표시 이를 위해 필요한 이력 데이터는 DB 내부 버전 구조로 처리하고, 파일 생성/다운로드 방식은 개발 목표에서 제외한다. ### 목표 - 헤더에서 월을 선택하면 조직현황이 그 달 마지막 날 기준으로 다시 조회된다. - 현재 월은 항상 실시간 조직현황을 보여준다. - 과거 월은 `member_versions`, `seat_assignment_versions`, `history_revisions` 기반으로 월말 상태를 재구성한다. - 조직현황 메인과 리스트/비교 흐름이 같은 기준일 해석을 사용한다. ### 범위 포함 - `members` / `member_versions` 기반 월말 조회 정리 - 필요 시 `seat_assignment_versions`와 함께 조직현황 seat preview 기준일 정리 - 조직현황 관련 write 시 version row가 누적되도록 백엔드 보강 - 헤더 월 선택 -> 조직현황 iframe -> `/api/members?as_of=...` 흐름 정합화 - 현재 월은 실시간, 과거 월은 월말 기준이라는 규칙 고정 ### 범위 제외 - 월간 스냅샷 파일 생성 - 월간 스냅샷 다운로드 - 별도 파일 기반 보관 기능 - 화면 전체를 새로운 앱 구조로 승격하는 구조 리팩터링 ### 현재 상태 - `member_versions`, `seat_assignment_versions`, `history_revisions` 기본 구조는 이미 반영됨 - `/api/members?as_of=...` 와 조직현황 비교 UI도 최소 동작 범위는 있음 - 헤더 월 선택 UI도 존재함 - 다만 목표를 보면 중요한 것은 "월을 눌렀을 때 해당 월 말일 조직현황이 정확히 보이는가"이며, 이 관점에서 백엔드 이력 누적/해석을 더 분명히 해야 함 ### 완료 조건 - 헤더에서 현재 월을 선택하면 실시간 조직현황이 보인다. - 헤더에서 과거 월을 선택하면 그 달 마지막 날 기준 조직현황이 보인다. - 조직현황 메인, 리스트 기준일 조회, 변경 비교가 같은 이력 기준을 사용한다. - 월말 조회를 위해 별도 스냅샷 파일이나 다운로드 기능을 만들지 않는다. ### 구현 방향 - 프런트는 기존 헤더 월 선택 UI를 최대한 유지 - 백엔드에서 `as_of`와 revision/version 누적 로직을 보강해 월말 조회를 신뢰 가능하게 만드는 방향 우선 - 화면 표출 변경이 필요하면 그 시점에 별도 조정 ### 참고 - `docs/HISTORY_ASOF_DB_PLAN.md` - 현재 기준 해석: 이 이슈는 "월간 스냅샷 기능"이 아니라 "월말 기준 조직현황 조회 기능" 이슈로 본다.
hyunho changed title from [P1] [이력관리] 조직도·자리배치도 변경 이력 버전 누적 저장 to [P1] [이력관리] 조직도·자리배치도 시점 조회(as-of date) 및 버전 누적 저장 2026-03-27 08:52:53 +09:00
Author
Owner

2026-03-30 phase 1 진행 메모

이번 작업에서 as-of history 구조를 문서 단계에서 실제 DB 단계로 한 단계 옮겼습니다.

반영 내용:

  • backend/app/db.py
    • history_revisions
    • member_versions
    • seat_assignment_versions
    • entity_change_events
      테이블 및 인덱스 추가
  • 초기 baseline backfill 경로 추가
    • 현재 members 상태를 member_versions 로 적재
    • 현재 seat_positions 상태를 seat_assignment_versions 로 적재
    • baseline revision initial-backfill 생성
  • scripts/sync_prod_db_to_dev.sh
    • sync 후 history backfill도 다시 맞추도록 보강

실제 확인:

  • minimal sync 이후 history_revisions=1
  • member_versions=227
  • 현재 공개용 기준 seat_positions=0 상태라 seat_assignment_versions=0
  • entity_change_events=0 (아직 이벤트 write 는 미도입)

현재 판단:

  • 이 이슈는 아직 완료가 아니다.
  • 하지만 phase 1인 "테이블/기초 backfill 도입"은 반영된 상태다.
  • 다음 단계는
    • 조직도/자리배치도 write 시 append 기반 version write 추가
    • as_of 조회 API 추가
    • 헤더 날짜 제어와 조직도/자리배치도 연동
      순으로 가는 것이 맞다.
2026-03-30 phase 1 진행 메모 이번 작업에서 as-of history 구조를 문서 단계에서 실제 DB 단계로 한 단계 옮겼습니다. 반영 내용: - `backend/app/db.py` - `history_revisions` - `member_versions` - `seat_assignment_versions` - `entity_change_events` 테이블 및 인덱스 추가 - 초기 baseline backfill 경로 추가 - 현재 `members` 상태를 `member_versions` 로 적재 - 현재 `seat_positions` 상태를 `seat_assignment_versions` 로 적재 - baseline revision `initial-backfill` 생성 - `scripts/sync_prod_db_to_dev.sh` - sync 후 history backfill도 다시 맞추도록 보강 실제 확인: - minimal sync 이후 `history_revisions=1` - `member_versions=227` - 현재 공개용 기준 `seat_positions=0` 상태라 `seat_assignment_versions=0` - `entity_change_events=0` (아직 이벤트 write 는 미도입) 현재 판단: - 이 이슈는 아직 완료가 아니다. - 하지만 phase 1인 "테이블/기초 backfill 도입"은 반영된 상태다. - 다음 단계는 - 조직도/자리배치도 write 시 append 기반 version write 추가 - `as_of` 조회 API 추가 - 헤더 날짜 제어와 조직도/자리배치도 연동 순으로 가는 것이 맞다.
Author
Owner

2026-03-30 phase 2 진행 메모

phase 1 테이블/초기 backfill 이후, 이번에 실제 write/read 경로를 최소 범위로 연결했습니다.

추가 반영 내용:

  • backend/app/main.py
    • create_member, update_member, delete_member, bulk-syncmember_versions / seat_assignment_versions append 경로 추가
    • save_seat_layout 시 변경된 구성원 기준으로 seat_assignment_versions append 경로 추가
    • GET /api/members?as_of=YYYY-MM-DD 지원
    • GET /api/seat-maps/{id}/layout?as_of=YYYY-MM-DD 지원
  • 보조 함수 추가
    • parse_as_of
    • create_history_revision
    • sync_member_versions
    • sync_seat_assignment_versions
    • fetch_members_as_of

확인:

  • backend 컨테이너 내부 함수 호출 기준
    • members_as_of=227
    • seat_map 19 layout_members=227
    • seat_map 19 layout_placements=0
  • 현재 공개용 기준 seat assignment 가 비어 있으므로 placement 0 은 정상

현재 판단:

  • 이 이슈는 아직 완료가 아니다.
  • 하지만 이제
    • history 테이블 존재
    • 초기 backfill 존재
    • write 시 append 경로 존재
    • read 시 as_of 경로 존재
      까지는 들어간 상태다.
  • 남은 범위는 날짜 헤더 연동, viewer/as_of 확장, 비교 API, 변경 이벤트 정교화 쪽이다.
2026-03-30 phase 2 진행 메모 phase 1 테이블/초기 backfill 이후, 이번에 실제 write/read 경로를 최소 범위로 연결했습니다. 추가 반영 내용: - `backend/app/main.py` - `create_member`, `update_member`, `delete_member`, `bulk-sync` 시 `member_versions` / `seat_assignment_versions` append 경로 추가 - `save_seat_layout` 시 변경된 구성원 기준으로 `seat_assignment_versions` append 경로 추가 - `GET /api/members?as_of=YYYY-MM-DD` 지원 - `GET /api/seat-maps/{id}/layout?as_of=YYYY-MM-DD` 지원 - 보조 함수 추가 - `parse_as_of` - `create_history_revision` - `sync_member_versions` - `sync_seat_assignment_versions` - `fetch_members_as_of` 확인: - backend 컨테이너 내부 함수 호출 기준 - `members_as_of=227` - `seat_map 19 layout_members=227` - `seat_map 19 layout_placements=0` - 현재 공개용 기준 seat assignment 가 비어 있으므로 placement 0 은 정상 현재 판단: - 이 이슈는 아직 완료가 아니다. - 하지만 이제 - history 테이블 존재 - 초기 backfill 존재 - write 시 append 경로 존재 - read 시 as_of 경로 존재 까지는 들어간 상태다. - 남은 범위는 날짜 헤더 연동, viewer/as_of 확장, 비교 API, 변경 이벤트 정교화 쪽이다.
Author
Owner

phase 3 진행 메모:

  • 헤더 endDate를 organization/seatmap as_of 조회에 연결했습니다.
  • /api/seat-maps/{id}/vieweras_of를 지원하도록 확장했습니다.
  • legacy/organization iframe이 date-range postMessage를 받아 /api/members/api/seat-maps/{id}/layoutas_of 기준으로 다시 조회합니다.
  • seatmap admin/readonly 화면도 헤더 기간 컨트롤을 표시하고, 날짜 변경 시 layout/viewer를 as_of 기준으로 다시 로드합니다.
  • baseline backfill의 valid_from1970-01-01 UTC로 보정해서 과거 as_of로도 빈 결과가 나오지 않도록 수정했습니다.

검증:

  • python3 -m py_compile backend/app/db.py backend/app/main.py
  • node --check frontend/public/app.js
  • node --check legacy/static/organization.js
  • 8080/8081 backend 컨테이너 내부에서 members?as_of=2026-01-31 = 227, seat-maps/19/layout?as_of=2026-01-31 = members 227 / placements 0 확인
phase 3 진행 메모: - 헤더 `endDate`를 organization/seatmap `as_of` 조회에 연결했습니다. - `/api/seat-maps/{id}/viewer`도 `as_of`를 지원하도록 확장했습니다. - `legacy/organization` iframe이 `date-range` postMessage를 받아 `/api/members`와 `/api/seat-maps/{id}/layout`를 `as_of` 기준으로 다시 조회합니다. - seatmap admin/readonly 화면도 헤더 기간 컨트롤을 표시하고, 날짜 변경 시 layout/viewer를 `as_of` 기준으로 다시 로드합니다. - baseline backfill의 `valid_from`을 `1970-01-01 UTC`로 보정해서 과거 `as_of`로도 빈 결과가 나오지 않도록 수정했습니다. 검증: - `python3 -m py_compile backend/app/db.py backend/app/main.py` - `node --check frontend/public/app.js` - `node --check legacy/static/organization.js` - 8080/8081 backend 컨테이너 내부에서 `members?as_of=2026-01-31` = 227, `seat-maps/19/layout?as_of=2026-01-31` = members 227 / placements 0 확인
Author
Owner

phase 4 진행 메모:

  • 조직현황 메인 우측 하단 리스트 모달에 현재 명단 / 기준일 조회 / 변경 비교 흐름을 추가했습니다.
  • 기준일 조회는 기존 /api/members?as_of=...를 재사용하고, 변경 비교는 /api/history/members/compare?from_date=...&to_date=... API를 추가해 리스트형 diff를 반환합니다.
  • 자리배치 전용 비교 화면은 만들지 않았고, 요청대로 인원 명단 리스트 내부 기능만 확장했습니다.

검증:

  • python3 -m py_compile backend/app/main.py
  • node --check legacy/static/organization.js
  • node --check frontend/public/app.js
  • backend 컨테이너 내부에서 /api/history/members/compare?from_date=2026-01-31&to_date=2026-01-31 응답 확인 (items=0)
phase 4 진행 메모: - 조직현황 메인 우측 하단 `리스트` 모달에 `현재 명단 / 기준일 조회 / 변경 비교` 흐름을 추가했습니다. - 기준일 조회는 기존 `/api/members?as_of=...`를 재사용하고, 변경 비교는 `/api/history/members/compare?from_date=...&to_date=...` API를 추가해 리스트형 diff를 반환합니다. - 자리배치 전용 비교 화면은 만들지 않았고, 요청대로 인원 명단 리스트 내부 기능만 확장했습니다. 검증: - `python3 -m py_compile backend/app/main.py` - `node --check legacy/static/organization.js` - `node --check frontend/public/app.js` - backend 컨테이너 내부에서 `/api/history/members/compare?from_date=2026-01-31&to_date=2026-01-31` 응답 확인 (`items=0`)
Author
Owner

이력관리 기능 진행 현황 업데이트입니다.

  • member_versions, seat_assignment_versions, history_revisions, entity_change_events 기반 구조 반영
  • 조직현황 리스트 모달에서 기준일 조회, 변경 비교 UI 추가
  • 조직현황 메인에서 월 기준 조회와 변경사항 확인 흐름 추가
  • same-day 세부 revision 비교는 아직 후속 범위로 남아 있음

현재 기준:

  • 조직현황 히스토리 UI는 동작 확인
  • 추가 고도화는 필요하지만 최소 usable 범위는 확보
  • 아직 모든 범위를 완료로 닫지는 않음
이력관리 기능 진행 현황 업데이트입니다. - `member_versions`, `seat_assignment_versions`, `history_revisions`, `entity_change_events` 기반 구조 반영 - 조직현황 리스트 모달에서 `기준일 조회`, `변경 비교` UI 추가 - 조직현황 메인에서 월 기준 조회와 변경사항 확인 흐름 추가 - same-day 세부 revision 비교는 아직 후속 범위로 남아 있음 현재 기준: - 조직현황 히스토리 UI는 동작 확인 - 추가 고도화는 필요하지만 최소 usable 범위는 확보 - 아직 모든 범위를 완료로 닫지는 않음
hyunho changed title from [P1] [이력관리] 조직도·자리배치도 시점 조회(as-of date) 및 버전 누적 저장 to [P1] [이력관리] 헤더 월 선택 기준 월말 조직현황 조회 및 버전 누적 저장 2026-04-02 08:54:24 +09:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hyunho/MH-DashBoard-organization#9