Files
Aislo/.agent/complete_and_old/code_20260708_b01_dashboard.md
T
2026-07-08 19:59:25 +09:00

9.5 KiB

code_20260708_b01_dashboard.md

목적

이번 대화 세션에서는 .agent/plan_register_split.md.agent/plan_register_split_validation.md 기준으로 B01 페이지를 역할별 대시보드와 계정관리 기능을 함께 포함하는 단일 페이지로 구현했다.

주요 구현

1. B01 단일 폴더 정리

  • B01_Dashboard/를 B01의 단일 구현 폴더로 사용한다.
  • 기존 B01_AccountDetail/의 계정관리 성격은 B01_Dashboard 안으로 흡수했다.
  • 기존 B01_AccountDetail_UI_Page.ts, B01_AccountDetail_UI_Style.css는 삭제했다.
  • B01_AccountDetail 문자열 참조는 주석까지 정리했다.

2. 백엔드 API

신규 파일:

  • B01_Dashboard/B01_Dashboard_Router.py
  • B01_Dashboard/B01_Dashboard_Repository.py
  • B01_Dashboard/B01_Dashboard_Schema.py

구현된 API 범위:

  • 공통 사용자 정보 조회/수정
  • USER 프로젝트/회사 조회, 회사 검색, 회사 생성, 회사 가입 신청
  • ADMIN 팀원 조회/추가/제거, 가입 요청 승인/거절, 회사 프로젝트 조회
  • SYSTEM_ADMIN 회사/사용자/가입 요청/감사 로그/리소스 조회

라우터 등록:

  • main.pyB01_Dashboard_Router를 등록했다.

3. 프론트엔드

신규/수정 파일:

  • B01_Dashboard/B01_Dashboard_UI_Page.ts
  • B01_Dashboard/B01_Dashboard_Api_Fetch.ts
  • B01_Dashboard/B01_Dashboard_UI_Style.css
  • A00_Common/router.ts
  • ui_template/ui_template_locale.ts

구현된 UI 범위:

  • 역할별 대시보드 섹션 조건부 렌더링
  • 프로젝트 테이블 및 B03~B09 워크플로우 단계 버튼
  • 회사 미연결/가입 대기/활성 상태 표시
  • 회사 생성 및 회사 검색/가입 신청 모달
  • ADMIN 팀원 관리 및 가입 요청 처리
  • SYSTEM_ADMIN 리소스/회사/사용자/가입 요청/로그 섹션
  • 기본정보 수정
  • 비밀번호 변경

주의:

  • 색상은 직접 하드코딩하지 않고 ui_template_theme.css 변수 기반 CSS를 사용했다.
  • UI 문구는 ui_template_locale.ts에 등록해 참조했다.

4. 인증/세션 관련 최소 수정

로그인 인증 이슈 재발을 피하기 위해 수정 범위를 좁혔다.

수정 파일:

  • common_util/common_util_auth.py
  • common_util/common_util_auth_repository.py
  • A06_Login/A06_Login_Router.py
  • A07_Register/A07_Register_Router.py

변경 내용:

  • PENDING 상태 사용자도 B01 대시보드에 접근할 수 있도록 세션 검증 허용 상태에 포함했다.
  • 신규 가입 기본 역할을 기존 MEMBER가 아니라 계획 기준인 USER로 맞췄다.
  • 이메일 인증 완료 시 auth_expires_at을 3개월 뒤로 설정했다.
  • 로그인 완료 시 last_login, auth_expires_at을 갱신한다.
  • 회사 생성/연결 안내 주석을 B01_Dashboard 기준으로 갱신했다.

5. DB 마이그레이션

신규 파일:

  • db_management/004_dashboard.sql

적용 내용:

  • users.roleSYSTEM_ADMIN, ADMIN, USER 기준으로 정규화
  • 기존 MASTER -> ADMIN, MEMBER -> USER 데이터 변환
  • users.statusNO_COMPANY 포함
  • users.department, last_login, auth_expires_at 추가
  • system_audit_logs, system_resources 생성
  • join_requests.review_comment 추가

실행 결과:

  • 원격 MariaDB에 004_dashboard.sql 실행 완료
  • 10개 SQL statement 실행 및 커밋 완료
  • information_schema 조회로 다음 항목 확인 완료:
    • users.role = enum('SYSTEM_ADMIN','ADMIN','USER')
    • users.status = enum('PENDING_EMAIL','NO_COMPANY','PENDING','ACTIVE','INACTIVE','REJECTED')
    • department, last_login, auth_expires_at
    • system_audit_logs, system_resources
    • join_requests.review_comment

검증

실행한 검증:

  • npx.cmd tsc --noEmit
  • ruff check --fix --no-cache ...
  • venv 기준 Python import 확인
  • DB information_schema 확인

결과:

  • TypeScript 검사 통과
  • Ruff 검사 통과
  • DB 마이그레이션 적용 확인

참고:

  • 서버 실행은 프로젝트 지침에 따라 수행하지 않았다.
  • 의존성은 venv에서 pymysql, aiomysql, fastapi import가 정상이라 추가 설치하지 않았다.

후속 수정 (리소스 현황 실측)

  • get_system_resources에서 None으로 하드코딩되어 화면에 -로만 표시되던 CPU/메모리 값을 psutil로 실측하도록 변경했다.
    • CPU: psutil.cpu_percent(interval=0.1)
    • 메모리: psutil.virtual_memory().percent
    • 디스크: 기존 shutil.disk_usage() 유지
  • 이력 조회 기간을 24시간 → 기본 30일로 변경했다. (days 파라미터, 1~90일)
  • API 파라미터 불일치 수정: 프론트가 보내던 period=24h(문자열)를 백엔드 days(정수)와 일치하도록 fetchSystemResources(days = 30)로 변경했다.
  • psutil은 이미 requirements.txt(psutil>=6.1,<7) 및 venv에 존재하여 추가 설치 불필요.

후속 수정 (리소스 그래프 + 계측 로그)

프론트엔드 그래프

  • ui_template_elements.ts에 공통 라인 차트 컴포넌트 createLineChart 추가 (외부 라이브러리 없이 인라인 SVG).
    • null 값 구간은 선을 끊고 다음 유효점에서 재시작.
    • 색상은 ui_template_theme.css에 추가한 --color-chart-0~3 변수 참조 (하드코딩 없음).
  • B01_Dashboard_UI_Page.ts의 리소스 섹션을 buildResourcePanel로 교체하여 지표(metrics) + 30일 추이 그래프(CPU/메모리/디스크)를 함께 표시.
  • ResourceData.historyunknown[]ResourceHistoryPoint[]로 타입 구체화.
  • locale에 B01_Dashboard_Resources_ChartCaption, B01_Dashboard_Resources_ChartAria 추가.

계측 백그라운드 태스크 + 로그 파일

  • common_util/common_util_resource_monitor.py 신규: 2분 주기로 CPU/메모리/디스크 계측.
    • DB system_resources 테이블 INSERT (그래프 조회 소스) + 30일 경과 행 DELETE.
    • 루트 log/system_resources.log 단일 파일에 탭 구분 1줄 append, 30일 경과 줄 제거(오래된 줄 삭제 + 신규 줄 추가).
  • main.py lifespan에 sample_resources_loop 태스크 등록/취소 (기존 cleanup 태스크 패턴).
  • config_system.pyLOG_BASE_DIR, RESOURCE_LOG_PATH, RESOURCE_SAMPLE_INTERVAL_SEC=120, RESOURCE_LOG_RETENTION_DAYS=30 추가.
  • .gitignorelog/ 추가.

검증

  • npx tsc --noEmit 통과, ruff format/ruff check 통과, prettier --write 변경 없음.
  • 계측/로그 트림 로직은 스크립트로 실측 확인 (샘플 기록·30일 경과 줄 제거 동작 확인 후 테스트 로그 삭제).

후속 수정 (그래프 다운샘플링 + 스플라인 + 범례/X축)

조회 다운샘플링 (백엔드)

  • get_system_resources의 history 조회를 시간버킷 평균으로 축소.
    • bucket = max(120초, days*86400 / 300) → 최대 약 300점.
    • GROUP BY FLOOR(UNIX_TIMESTAMP(timestamp)/bucket) + AVG(...).
    • 30일 조회 페이로드 ~4MB → ~55KB 수준으로 감소. 하루 이하 조회 시 원본 해상도 유지.
  • DB 실측: 5행 → 1버킷 평균 집계 확인 후 테스트 데이터 삭제.

차트 컴포넌트 개선 (ui_template_elements.ts)

  • 직선 → 스플라인(Catmull-Rom → 3차 베지어). null 구간은 세그먼트로 분리해 각각 곡선 처리.
  • 범례를 그래프 우상단 오버레이로 이동 (.ui-chart__plot position:relative + .ui-chart__legend absolute, 반투명 배경).
  • X축 라벨 지원: opts.xLabels, 양끝 포함 5개 균등 표기 (.ui-chart__tick--x).
  • B01_Dashboard_UI_Page.tsformatChartTime(MM/DD HH:mm) 추가 후 xLabels 전달.

리소스 지표 레이아웃 (B01_Dashboard_UI_Style.css)

  • metric-grid를 5열 1행, 각 항목은 라벨·값 가로 1줄(space-between)로 컴팩트화. 값 폰트 축소.

검증

  • npx tsc --noEmit 통과 (el() children 타입 이슈는 svg를 append로 분리해 해결).
  • ruff format/check 통과, prettier 변경 없음.

후속 수정 (그래프 X축 레이블 - 데이터 기반 고정)

백엔드 timestamp 직렬화 (B01_Dashboard_Repository.py)

  • 기존: FROM_UNIXTIME() → Python datetime 객체로 JSON 직렬화 불가
  • 변경: DATE_FORMAT(..., '%%Y-%%m-%%dT%%H:%%i:%%s') → ISO 문자열로 명시적 변환
  • SQL에 date_fmt 변수 도입해 ruff 100자 줄 제한 준수

프론트엔드 X축 라벨 고정 (ui_template_elements.ts, B01_Dashboard_UI_Page.ts)

  • 기존: X_TICK_COUNT=5 고정으로 균등 선택 (데이터 개수와 무관)
  • 변경: X_TICK_STEP=3 — 데이터 포인트마다 3개씩 건너뛰며 표시 (실제 데이터량 기반)
  • X축 라벨 루프를 for (let idx = 0; idx < pointCount; idx += X_TICK_STEP) 로 변경
  • formatChartTime에 try-catch 추가로 예외 안전성 강화

검증

  • npx tsc --noEmit 통과
  • ruff format/check 통과 (100자 줄 제한 준수)
  • prettier 변경 없음

남은 주의점

  • B01 화면은 구현됐지만 실제 브라우저 검증은 수행하지 않았다.
  • 그래프는 system_resources 이력이 쌓여야 선이 그려진다 (앱 최초 구동 직후에는 데이터 2점 미만이면 빈 상태 표시, 2분 주기로 누적).
  • 그래프 갱신은 페이지 로드/새로고침 시점 1회 (자동 폴링 없음).
  • 로그인/회사 상태별 실제 시나리오 검증은 별도 검증 AI 또는 사용자가 수행해야 한다.
  • B01_Dashboard_UI_Page.ts는 645줄로 700줄 제한 이내지만, 향후 기능 추가 시 컴포넌트 분리를 고려해야 한다.
  • 이전 import 검증 중 기존 B04 계열 Pydantic model_* 필드 경고가 출력됐으나, 이번 B01 구현에서 발생한 경고는 아니다.