현재 조직현황 화면에는 헤더에 월 선택 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
이번 작업에서 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 추가
- 헤더 날짜 제어와 조직도/자리배치도 연동
순으로 가는 것이 맞다.
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, 변경 이벤트 정교화 쪽이다.
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, 변경 이벤트 정교화 쪽이다.
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
배경
현재 조직현황 화면에는 헤더에 월 선택 UI가 이미 존재한다.
이 이슈의 핵심 목적은 별도 월간 스냅샷 파일을 만드는 것이 아니라, 헤더에서 특정 월을 선택했을 때 그 달의 마지막 날 기준 조직현황을 확인할 수 있게 하는 것이다.
즉 화면 기능 기준으로 보면 아래가 목표다.
이를 위해 필요한 이력 데이터는 DB 내부 버전 구조로 처리하고, 파일 생성/다운로드 방식은 개발 목표에서 제외한다.
목표
member_versions,seat_assignment_versions,history_revisions기반으로 월말 상태를 재구성한다.범위 포함
members/member_versions기반 월말 조회 정리seat_assignment_versions와 함께 조직현황 seat preview 기준일 정리/api/members?as_of=...흐름 정합화범위 제외
현재 상태
member_versions,seat_assignment_versions,history_revisions기본 구조는 이미 반영됨/api/members?as_of=...와 조직현황 비교 UI도 최소 동작 범위는 있음완료 조건
구현 방향
as_of와 revision/version 누적 로직을 보강해 월말 조회를 신뢰 가능하게 만드는 방향 우선참고
docs/HISTORY_ASOF_DB_PLAN.md[P1] [이력관리] 조직도·자리배치도 변경 이력 버전 누적 저장to [P1] [이력관리] 조직도·자리배치도 시점 조회(as-of date) 및 버전 누적 저장2026-03-30 phase 1 진행 메모
이번 작업에서 as-of history 구조를 문서 단계에서 실제 DB 단계로 한 단계 옮겼습니다.
반영 내용:
backend/app/db.pyhistory_revisionsmember_versionsseat_assignment_versionsentity_change_events테이블 및 인덱스 추가
members상태를member_versions로 적재seat_positions상태를seat_assignment_versions로 적재initial-backfill생성scripts/sync_prod_db_to_dev.sh실제 확인:
history_revisions=1member_versions=227seat_positions=0상태라seat_assignment_versions=0entity_change_events=0(아직 이벤트 write 는 미도입)현재 판단:
as_of조회 API 추가순으로 가는 것이 맞다.
2026-03-30 phase 2 진행 메모
phase 1 테이블/초기 backfill 이후, 이번에 실제 write/read 경로를 최소 범위로 연결했습니다.
추가 반영 내용:
backend/app/main.pycreate_member,update_member,delete_member,bulk-sync시member_versions/seat_assignment_versionsappend 경로 추가save_seat_layout시 변경된 구성원 기준으로seat_assignment_versionsappend 경로 추가GET /api/members?as_of=YYYY-MM-DD지원GET /api/seat-maps/{id}/layout?as_of=YYYY-MM-DD지원parse_as_ofcreate_history_revisionsync_member_versionssync_seat_assignment_versionsfetch_members_as_of확인:
members_as_of=227seat_map 19 layout_members=227seat_map 19 layout_placements=0현재 판단:
까지는 들어간 상태다.
phase 3 진행 메모:
endDate를 organization/seatmapas_of조회에 연결했습니다./api/seat-maps/{id}/viewer도as_of를 지원하도록 확장했습니다.legacy/organizationiframe이date-rangepostMessage를 받아/api/members와/api/seat-maps/{id}/layout를as_of기준으로 다시 조회합니다.as_of기준으로 다시 로드합니다.valid_from을1970-01-01 UTC로 보정해서 과거as_of로도 빈 결과가 나오지 않도록 수정했습니다.검증:
python3 -m py_compile backend/app/db.py backend/app/main.pynode --check frontend/public/app.jsnode --check legacy/static/organization.jsmembers?as_of=2026-01-31= 227,seat-maps/19/layout?as_of=2026-01-31= members 227 / placements 0 확인phase 4 진행 메모:
리스트모달에현재 명단 / 기준일 조회 / 변경 비교흐름을 추가했습니다./api/members?as_of=...를 재사용하고, 변경 비교는/api/history/members/compare?from_date=...&to_date=...API를 추가해 리스트형 diff를 반환합니다.검증:
python3 -m py_compile backend/app/main.pynode --check legacy/static/organization.jsnode --check frontend/public/app.js/api/history/members/compare?from_date=2026-01-31&to_date=2026-01-31응답 확인 (items=0)이력관리 기능 진행 현황 업데이트입니다.
member_versions,seat_assignment_versions,history_revisions,entity_change_events기반 구조 반영기준일 조회,변경 비교UI 추가현재 기준:
[P1] [이력관리] 조직도·자리배치도 시점 조회(as-of date) 및 버전 누적 저장to [P1] [이력관리] 헤더 월 선택 기준 월말 조직현황 조회 및 버전 누적 저장