# Development History

## Purpose

이 문서는 `total` 브랜치에서 진행한 통합 작업을 기능 단위로 정리한 개발 히스토리다.
목표는 다음 두 가지다.

- 지금까지 어떤 기능을 어떤 방식으로 붙였는지 빠르게 파악
- 이후 유지보수나 추가 개발 시, 왜 그렇게 구현했는지 추적 가능하게 하기

## 1. 대시보드 허브 통합

### 작업 내용

- `조직 현황`, `프로젝트별 분석`, `팀/개인별 분석`, `자리배치도`를 하나의 메인 허브에서 오갈 수 있도록 통합
- 공통 헤더, 로그인 정보, 탭 전환, 공통 기간 캘린더 구성
- `payment.html`, `mh.html`은 초기에는 iframe 연결 방식으로 편입

### 해결 방식

- 기존 화면을 새로 재개발하지 않고, 먼저 메인 허브 안에 편입
- 이후 데이터는 공통 API/DB 기준으로 전환하는 2단계 방식 채택

## 2. 조직현황 고도화

### 작업 내용

- 조직도 레거시 화면을 메인 허브에 연결
- 관리자/비관리자 모드 정리
- 구성원 상세 프로필 개선
- 프로필 사진 업로드 연동
- `재석위치` 카드 추가

### 해결 방식

- 레거시 조직도 화면은 유지하되 API를 통해 `members`를 읽는 구조로 전환
- 상세 프로필의 `재석위치`는 문자열이 아니라 실제 자리배치도 viewer preview를 붙이는 방식으로 변경

## 3. 자리배치도 기능 재구성

### 작업 내용

- `기술개발센터` 고정 도면 기준 자리배치도 viewer 구성
- 관리자 편집 화면과 비관리자 열람 화면 분리
- 조직도에서 `+` 버튼으로 자리배치도 진입
- 배치된 좌석의 이름/직급 라벨 표시
- 좌석 hover, 클릭, 자리 비우기, 미배치 목록 복귀 흐름 구현

### 해결 방식

- DXF 업로드 기반 편집을 그대로 밀기보다, 실제 업무에 맞는 고정 도면 중심 구조로 정리
- viewer 코드는 공통으로 쓰되, 화면은
  - 관리자 편집
  - 비관리자 열람
  - 구성원 상세 preview
  로 역할 분리

## 4. 자리배치도 저장 문제 해결

### 문제

- 관리자 화면에서는 배치가 된 것처럼 보여도 저장 후 조직도 상세 프로필에서는 `미배치`
- 비관리자 자리배치도에서도 배치 결과가 보이지 않음

### 원인

- `seat_positions_map_cell_idx (seat_map_id, row_index, col_index)` 유니크 인덱스가 슬롯 기반 도면에도 그대로 적용됨
- 고정 도면 배치는 실제로 `seat_slot_id` 기준 저장인데, 모든 배치가 `(row_index=0, col_index=0)`으로 들어가 충돌
- 그 결과 두 번째 좌석부터 `500 Internal Server Error`로 저장 실패

### 해결

- 슬롯 기반 도면에서는 `(seat_map_id, row_index, col_index)` 인덱스가 적용되지 않도록 수정
- `seat_positions` 저장 후 `members.seat_label`도 같이 동기화
- 조직도 iframe은 저장 완료 후 `seatmap-layout-updated` 메시지를 받아 cache를 비우고 재조회

### 결과

- 관리자 자리배치 저장이 실제 DB까지 반영됨
- 저장된 배치는 재접속 후에도 유지
- 조직현황 상세 프로필과 비관리자 자리배치도에서도 같은 배치를 읽을 수 있는 구조가 됨

## 5. 통합 DB 구축

### 작업 내용

- `organization.xlsx`
- `MH.xlsx`
- `payment.csv`

세 원본을 하나의 PostgreSQL 기준으로 적재

### 핵심 테이블

- `members`
- `seat_maps`
- `seat_slots`
- `seat_positions`
- `integration_raw_organization_rows`
- `integration_raw_mh_rows`
- `integration_raw_payment_rows`
- `integration_work_logs`
- `integration_work_log_segments`
- `integration_vouchers`
- `integration_projects`
- `integration_project_category_mappings`

### 해결 방식

- 원본 보존용 raw 테이블과 운영용 표준 테이블을 분리
- 화면이 직접 파일을 읽지 않고, DB와 API를 통해 같은 데이터를 보도록 정리

## 6. 프로젝트별 분석 통합

### 작업 내용

- `opayment.html` 원본 기준으로 화면, 카테고리, 계산식 복원
- `payment.csv`와 `MH.xlsx`를 함께 쓰는 구조로 정리
- `payment.csv` 분류를 1순위, `ptj.csv` 프로젝트 매핑을 2순위로 적용

### 해결한 문제

- 연장근무 시간을 `실제`가 아니라 `가공` 기준으로 써야 원본과 총합이 맞음
- 프로젝트 분류는 `payment.csv`만으로 부족해 `ptj.csv` 보정이 필요

### 결과

- 총합과 대부분의 프로젝트 집계가 원본 `opayment` 기준에 가깝게 정렬됨
- 남은 차이는 소수점 또는 추가 매핑 보정 수준으로 축소

## 7. 팀/개인별 분석 통합

### 작업 내용

- `omh.html` 원본 기준으로 화면, 카테고리, 계산식 복원
- 업로드형이 아니라 통합 DB raw MH 데이터를 다시 공급하는 방식으로 전환

### 해결 방식

- 원본 `MH.xlsx` 시트 구조가 깨지지 않도록 row 배열 자체를 DB에 저장
- 팀별 진행 프로젝트 등 원본 계산식이 기대하는 입력 구조를 그대로 재현

## 8. 조직 데이터 운영 정리

### 작업 내용

- 이름 alias, 퇴사 제외, 조직 override를 코드 상수에서 제거
- DB 테이블 기반 운영으로 전환

### 운영 테이블

- `member_aliases`
- `member_retirements`
- `member_overrides`

### 결과

- 이름 치환, 퇴사 제외, 팀/직책 예외를 코드 수정 없이 DB에서 관리 가능

## 9. 외부 접속 설정

### 작업 내용

- WSL 내부 `0.0.0.0:8080` 바인딩 확인
- Windows host에서 `portproxy`와 방화벽 규칙으로 다른 PC 접속 가능하게 정리

### 유의사항

- Windows LAN IP 또는 WSL IP가 바뀌면 `portproxy`의 `connectaddress`는 다시 맞춰야 한다
- 운영 안정성을 위해 향후 자동화 스크립트화가 필요함

## 10. 인증 기본 구조 추가

### 작업 내용

- 프런트 로그인 화면을 실제 `/api/auth/login` API와 연결
- 로그인 세션 확인용 `/api/auth/me` 추가
- 로그아웃용 `/api/auth/logout` 추가
- 로그인 감사로그와 세션 저장 테이블 추가

### 해결 방식

- 업무 데이터는 기존 `members` 중심으로 유지
- 인증 데이터는 `auth.users`, `auth.sessions`, `auth.login_audit_logs` 로 분리
- 구성원 import 시 사번 기준으로 계정을 동기화하고 기본 관리자 계정을 seed

### 현재 한계

- 권한 모델은 아직 `role` 단일 컬럼 수준이다
- API별 세부 권한 검증은 아직 미완성이다
- `/api/mock-login` 은 아직 남아 있어 운영 기준으로는 정리가 필요하다

## 11. 이력형 DB 전환 방향 확정

### 배경

- 월간 스냅샷 파일보다, 사용자가 원하는 날짜 기준으로 조직도와 자리배치도를 바로 조회하는 요구가 더 중요해졌다
- 조직도 기본 정보나 자리배치 정보처럼 원래 날짜가 없는 데이터도 과거/현재 버전 차이를 추적해야 한다

### 결정

- 월간 스냅샷 기능은 범위에서 제외
- 대신 DB 자체를 `valid_from`, `valid_to` 기반 버전 구조로 전환
- 사용자 조회는 파일 스냅샷이 아니라 `as_of` 기준 조회 방식으로 설계

### 우선 적용 대상

- `members` -> `member_versions`
- `seat_positions` -> `seat_assignment_versions`

### 기대 효과

- 특정 날짜의 조직 상태 재구성 가능
- 특정 날짜의 자리배치도 재구성 가능
- 기간 비교나 변경 추적 UI로 확장 가능

### 현재 반영 상태

- `history_revisions`
- `member_versions`
- `seat_assignment_versions`
- `entity_change_events`

초기 단계로 테이블과 baseline backfill 경로를 먼저 추가했다.
아직 조직도/자리배치도 쓰기 API가 매 수정마다 version row 를 append 하도록 완전히 전환된 상태는 아니다.

### 설계 문서

- [HISTORY_ASOF_DB_PLAN.md](/home/hyunho/projects/mh-dashboard-organization/docs/HISTORY_ASOF_DB_PLAN.md)

## Next Focus

- `#2` 영속성 운영 검증과 문서 기준 정리
- 권한 제어와 mock login 정리
- `#9` as-of date 기반 history 구조 설계 및 점진적 도입
- 자리배치도 조직 트리, 나머지 사무실 도면 등 실사용 기능 고도화
- 프로젝트별 분석의 남은 소수점/분류 오차 정리
