- 데이터베이스 스키마 및 변경 로그 문서화 - 신규 페이지 개발 가이드 작성 - 모듈 아키텍처 설계 문서 추가 - 성능 최적화 전략 문서화 - 리팩토링 계획 및 진행 상황 정리 Documentation: - DATABASE_SCHEMA.md: 전체 DB 스키마 구조 - DB_CHANGE_LOG.md: 마이그레이션 변경 이력 - DEVELOPMENT_GUIDE.md: 신규 기능 개발 표준 - MODULE_ARCHITECTURE.md: 프론트엔드 모듈 구조 - PERFORMANCE_OPTIMIZATION.md: 성능 최적화 가이드 - REFACTORING_PLAN.md: 리팩토링 진행 상황 Test Files: - app.html, app.js: SPA 테스트 파일 - test_api.html: API 테스트 페이지
11 KiB
11 KiB
M-Project 데이터베이스 스키마 문서
개요
작업보고서 시스템의 PostgreSQL 데이터베이스 스키마 정의
최종 업데이트: 2025-10-25
데이터베이스 버전: PostgreSQL 15
스키마 버전: 1.4 (마이그레이션 009까지 적용)
테이블 구조
1. users (사용자)
사용자 계정 정보를 저장하는 테이블
| 컬럼명 | 타입 | 제약조건 | 설명 |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTO_INCREMENT | 사용자 고유 ID |
| username | VARCHAR(50) | UNIQUE, NOT NULL | 로그인 아이디 |
| hashed_password | VARCHAR(255) | NOT NULL | 암호화된 비밀번호 (bcrypt) |
| full_name | VARCHAR(100) | NULL | 사용자 실명 |
| role | userrole | DEFAULT 'user' | 사용자 권한 |
| is_active | BOOLEAN | DEFAULT TRUE | 계정 활성화 상태 |
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 계정 생성일시 |
인덱스:
users_pkeyPRIMARY KEY (id)users_username_keyUNIQUE (username)
참조되는 테이블:
- daily_works.created_by_id
- issues.reporter_id
- project_daily_works.created_by_id
- projects.created_by_id
2. projects (프로젝트)
프로젝트 정보를 저장하는 테이블
| 컬럼명 | 타입 | 제약조건 | 설명 |
|---|---|---|---|
| id | BIGINT | PRIMARY KEY, AUTO_INCREMENT | 프로젝트 고유 ID |
| job_no | VARCHAR(50) | UNIQUE, NOT NULL | Job 번호 |
| project_name | VARCHAR(200) | NOT NULL | 프로젝트 이름 |
| created_by_id | INTEGER | FOREIGN KEY → users(id) | 생성자 ID |
| created_at | TIMESTAMP WITH TIME ZONE | DEFAULT NOW() | 생성일시 |
| is_active | BOOLEAN | DEFAULT TRUE | 활성 상태 |
인덱스:
projects_pkeyPRIMARY KEY (id)projects_job_no_keyUNIQUE (job_no)idx_projects_job_no(job_no)idx_projects_created_by_id(created_by_id)idx_projects_is_active(is_active)
외래키:
projects_created_by_id_fkeycreated_by_id → users(id)
참조되는 테이블:
- issues.project_id
- project_daily_works.project_id
3. issues (부적합 사항)
부적합 사항 정보를 저장하는 테이블
| 컬럼명 | 타입 | 제약조건 | 설명 |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTO_INCREMENT | 부적합 사항 고유 ID |
| photo_path | VARCHAR(500) | NULL | 첫 번째 사진 경로 |
| photo_path2 | VARCHAR(500) | NULL | 두 번째 사진 경로 |
| category | issuecategory | NOT NULL | 부적합 카테고리 |
| description | TEXT | NOT NULL | 부적합 사항 설명 |
| status | issuestatus | DEFAULT 'new' | 처리 상태 |
| reporter_id | INTEGER | FOREIGN KEY → users(id) | 보고자 ID |
| report_date | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 보고일시 |
| work_hours | DOUBLE PRECISION | DEFAULT 0 | 작업 시간 |
| detail_notes | TEXT | NULL | 상세 메모 |
| project_id | BIGINT | FOREIGN KEY → projects(id) | 프로젝트 ID |
인덱스:
issues_pkeyPRIMARY KEY (id)idx_issues_category(category)idx_issues_photo_path2(photo_path2)idx_issues_project_id(project_id)idx_issues_reporter_id(reporter_id)idx_issues_status(status)
외래키:
fk_issues_project_idproject_id → projects(id)issues_reporter_id_fkeyreporter_id → users(id)
4. daily_works (일일 공수)
전체 일일 작업 공수 정보를 저장하는 테이블 (레거시)
| 컬럼명 | 타입 | 제약조건 | 설명 |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTO_INCREMENT | 일일 공수 고유 ID |
| date | DATE | NOT NULL, UNIQUE | 작업 날짜 |
| worker_count | INTEGER | NOT NULL | 작업자 수 |
| regular_hours | DOUBLE PRECISION | NOT NULL | 정규 시간 |
| overtime_workers | INTEGER | DEFAULT 0 | 야근 작업자 수 |
| overtime_hours | DOUBLE PRECISION | DEFAULT 0 | 야근 시간 |
| overtime_total | DOUBLE PRECISION | DEFAULT 0 | 야근 총 시간 |
| total_hours | DOUBLE PRECISION | NOT NULL | 총 작업 시간 |
| created_by_id | INTEGER | FOREIGN KEY → users(id) | 생성자 ID |
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 생성일시 |
인덱스:
daily_works_pkeyPRIMARY KEY (id)daily_works_date_keyUNIQUE (date)idx_daily_works_date(date)idx_daily_works_created_by_id(created_by_id)
외래키:
daily_works_created_by_id_fkeycreated_by_id → users(id)
5. project_daily_works (프로젝트별 일일공수)
프로젝트별 일일 작업 공수 정보를 저장하는 테이블
| 컬럼명 | 타입 | 제약조건 | 설명 |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTO_INCREMENT | 프로젝트 일일공수 고유 ID |
| date | DATE | NOT NULL | 작업 날짜 |
| project_id | BIGINT | NOT NULL, FOREIGN KEY → projects(id) | 프로젝트 ID |
| hours | DOUBLE PRECISION | NOT NULL | 작업 시간 |
| created_by_id | INTEGER | NOT NULL, FOREIGN KEY → users(id) | 생성자 ID |
| created_at | TIMESTAMP WITH TIME ZONE | DEFAULT CURRENT_TIMESTAMP | 생성일시 |
인덱스:
project_daily_works_pkeyPRIMARY KEY (id)idx_project_daily_works_date(date)idx_project_daily_works_project_id(project_id)idx_project_daily_works_date_project(date, project_id)
외래키:
project_daily_works_created_by_id_fkeycreated_by_id → users(id)project_daily_works_project_id_fkeyproject_id → projects(id) ON DELETE CASCADE
ENUM 타입 정의
userrole
사용자 권한 타입
admin: 관리자 (모든 권한)user: 일반 사용자 (제한된 권한)
issuestatus
부적합 사항 처리 상태
new: 신규 (미처리)progress: 진행중complete: 완료
issuecategory
부적합 사항 카테고리
material_missing: 자재누락design_error: 설계미스incoming_defect: 입고자재 불량inspection_miss: 검사미스etc: 기타
관계도 (Entity Relationship)
users (1) ←→ (N) projects
↓ ↓
users (1) ←→ (N) issues ←→ (1) projects
↓ ↓
users (1) ←→ (N) daily_works
↓
users (1) ←→ (N) project_daily_works ←→ (1) projects
주요 관계:
- users → projects: 사용자가 프로젝트를 생성
- users → issues: 사용자가 부적합 사항을 보고
- projects → issues: 프로젝트에 부적합 사항이 속함
- users → daily_works: 사용자가 전체 일일공수를 입력 (레거시)
- users → project_daily_works: 사용자가 프로젝트별 일일공수를 입력
- projects → project_daily_works: 프로젝트에 일일공수가 속함
마이그레이션 히스토리
| 파일명 | 설명 | 적용일 |
|---|---|---|
001_init.sql |
초기 테이블 생성 (users, issues, daily_works) | 초기 |
002_add_second_photo.sql |
issues 테이블에 두 번째 사진 필드 추가 | 초기 |
003_update_categories.sql |
카테고리 업데이트 (dimension_defect → design_error) | 초기 |
004_fix_category_values.sql |
카테고리 값 정규화 (대소문자 통일) | 초기 |
005_recreate_enum_type.sql |
issuecategory ENUM 타입 재생성 | 초기 |
006_add_projects_table.sql |
projects 테이블 추가 | 2025-10-25 |
007_add_project_id_to_issues.sql |
issues 테이블에 project_id 컬럼 추가 | 2025-10-25 |
008_fix_project_id_bigint.sql |
project_id를 BIGINT로 변경 | 2025-10-25 |
009_add_project_daily_works_table.sql |
project_daily_works 테이블 추가 | 2025-10-25 |
010_add_etc_category.sql |
issuecategory에 'etc' 값 추가 | 2025-10-25 |
데이터베이스 연결 정보
Docker 환경
- Host: db (컨테이너 내부), localhost (외부)
- Port: 5432 (내부), 16432 (외부)
- Database: mproject
- Username: mproject
- Password: mproject2024
- Timezone: Asia/Seoul
환경변수
DATABASE_URL=postgresql://mproject:mproject2024@db:5432/mproject
POSTGRES_USER=mproject
POSTGRES_PASSWORD=mproject2024
POSTGRES_DB=mproject
TZ=Asia/Seoul
PGTZ=Asia/Seoul
기본 데이터
관리자 계정
- Username: hyungi
- Password: 123456
- Role: admin
- Full Name: 관리자
데이터베이스 관리
백업
# 전체 백업
docker exec m-project-db pg_dump -U mproject mproject > backup_$(date +%Y%m%d_%H%M%S).sql
# 스키마만 백업
docker exec m-project-db pg_dump -U mproject -s mproject > schema_backup.sql
# 데이터만 백업
docker exec m-project-db pg_dump -U mproject -a mproject > data_backup.sql
복구
# 전체 복구
docker exec -i m-project-db psql -U mproject mproject < backup.sql
# 스키마 복구
docker exec -i m-project-db psql -U mproject mproject < schema_backup.sql
테이블 상태 확인
# 모든 테이블 목록
docker exec m-project-db psql -U mproject -d mproject -c "\dt"
# 특정 테이블 구조
docker exec m-project-db psql -U mproject -d mproject -c "\d table_name"
# ENUM 타입 확인
docker exec m-project-db psql -U mproject -d mproject -c "\dT+"
# 인덱스 확인
docker exec m-project-db psql -U mproject -d mproject -c "\di"
성능 최적화
인덱스 전략
- Primary Keys: 모든 테이블에 자동 생성
- Foreign Keys: 모든 외래키에 인덱스 생성
- 검색 필드: 자주 검색되는 컬럼 (date, status, category 등)
- 복합 인덱스: 날짜+프로젝트 조합 검색 최적화
쿼리 최적화 권장사항
- 날짜 범위 검색: date 컬럼 인덱스 활용
- 프로젝트별 필터링: project_id 인덱스 활용
- 상태별 필터링: status, is_active 인덱스 활용
- JOIN 최적화: 외래키 인덱스 활용
보안 고려사항
- 비밀번호 암호화: bcrypt 해시 사용 (최소 12 rounds)
- SQL 인젝션 방지: 파라미터화된 쿼리 사용
- 접근 제어: 역할 기반 권한 관리
- 데이터 검증: 애플리케이션 레벨에서 입력값 검증
- 백업 암호화: 민감한 데이터 백업 시 암호화 권장
향후 확장 계획
예정된 변경사항
- 부적합 사항에 우선순위 필드 추가
- 프로젝트 상태 관리 (진행중, 완료, 보류 등)
- 파일 첨부 기능 확장 (문서, 도면 등)
- 알림 시스템을 위한 notifications 테이블
- 감사 로그를 위한 audit_logs 테이블
성능 개선 계획
- 파티셔닝: 대용량 데이터 처리를 위한 날짜별 파티셔닝
- 아카이빙: 오래된 데이터 아카이브 전략
- 캐싱: Redis를 활용한 자주 조회되는 데이터 캐싱
문서 작성자: AI Assistant
검토자: -
승인자: -
이 문서는 데이터베이스 스키마 변경 시마다 업데이트되어야 합니다.