9.5 KiB
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.pyB01_Dashboard/B01_Dashboard_Repository.pyB01_Dashboard/B01_Dashboard_Schema.py
구현된 API 범위:
- 공통 사용자 정보 조회/수정
- USER 프로젝트/회사 조회, 회사 검색, 회사 생성, 회사 가입 신청
- ADMIN 팀원 조회/추가/제거, 가입 요청 승인/거절, 회사 프로젝트 조회
- SYSTEM_ADMIN 회사/사용자/가입 요청/감사 로그/리소스 조회
라우터 등록:
main.py에B01_Dashboard_Router를 등록했다.
3. 프론트엔드
신규/수정 파일:
B01_Dashboard/B01_Dashboard_UI_Page.tsB01_Dashboard/B01_Dashboard_Api_Fetch.tsB01_Dashboard/B01_Dashboard_UI_Style.cssA00_Common/router.tsui_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.pycommon_util/common_util_auth_repository.pyA06_Login/A06_Login_Router.pyA07_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.role을SYSTEM_ADMIN,ADMIN,USER기준으로 정규화- 기존
MASTER -> ADMIN,MEMBER -> USER데이터 변환 users.status에NO_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_atsystem_audit_logs,system_resourcesjoin_requests.review_comment
검증
실행한 검증:
npx.cmd tsc --noEmitruff check --fix --no-cache ...- venv 기준 Python import 확인
- DB information_schema 확인
결과:
- TypeScript 검사 통과
- Ruff 검사 통과
- DB 마이그레이션 적용 확인
참고:
- 서버 실행은 프로젝트 지침에 따라 수행하지 않았다.
- 의존성은 venv에서
pymysql,aiomysql,fastapiimport가 정상이라 추가 설치하지 않았다.
후속 수정 (리소스 현황 실측)
get_system_resources에서None으로 하드코딩되어 화면에-로만 표시되던 CPU/메모리 값을psutil로 실측하도록 변경했다.- CPU:
psutil.cpu_percent(interval=0.1) - 메모리:
psutil.virtual_memory().percent - 디스크: 기존
shutil.disk_usage()유지
- CPU:
- 이력 조회 기간을 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.history를unknown[]→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일 경과 줄 제거(오래된 줄 삭제 + 신규 줄 추가).
- DB
main.pylifespan에sample_resources_loop태스크 등록/취소 (기존 cleanup 태스크 패턴).config_system.py에LOG_BASE_DIR,RESOURCE_LOG_PATH,RESOURCE_SAMPLE_INTERVAL_SEC=120,RESOURCE_LOG_RETENTION_DAYS=30추가..gitignore에log/추가.
검증
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__plotposition:relative +.ui-chart__legendabsolute, 반투명 배경). - X축 라벨 지원:
opts.xLabels, 양끝 포함 5개 균등 표기 (.ui-chart__tick--x). B01_Dashboard_UI_Page.ts에formatChartTime(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 구현에서 발생한 경고는 아니다.