Files
sam-manage/docs/01_PHASE1_MASTER_DATA.md
hskwon 76c8a94e4f docs: MNG 프로젝트 문서 정비
- 개발 단계별 문서 추가 (00_OVERVIEW ~ 06_PHASE)
- 기술 표준 문서 추가 (99_TECHNICAL_STANDARDS)
- 개발 프로세스 및 패턴 문서 추가
  - API_FLOW_TESTER_DESIGN, DEV_PROCESS
  - HTMX_API_PATTERN, LAYOUT_PATTERN
  - SETUP_GUIDE, MNG_PROJECT_PLAN
- 프로젝트 관리 문서 추가 (project-management/)
- INDEX.md, MNG_CRITICAL_RULES.md 업데이트
2025-11-30 21:04:19 +09:00

16 KiB
Raw Blame History

Phase 1: 기반 마스터 데이터

기간: 1-2주 우선순위: 최고 (모든 기능의 선행 조건)

📋 Phase 개요

모든 비즈니스 기능의 기반이 되는 핵심 마스터 데이터를 구축합니다.

포함 기능:

  1. 회원관리 (User Management)
  2. 테넌트관리 (Tenant Management)
  3. 거래처관리 (Client Management)

1 회원관리 (User Management)

기능 목록

1.1 회원 목록 조회

  • 경로: /mng/users
  • 기능:
    • 페이지네이션 (기본 20개/페이지)
    • 검색 (이름, 이메일, 부서, 역할)
    • 필터 (활성/비활성, 역할별, 부서별)
    • 정렬 (가입일, 이름, 이메일)
  • 권한: users.index

1.2 회원 상세 조회

  • 경로: /mng/users/{id}
  • 기능:
    • 기본 정보 표시
    • 소속 테넌트 정보
    • 역할/부서 정보
    • 최근 활동 로그
  • 권한: users.show

1.3 회원 생성

  • 경로: /mng/users/create
  • 기능:
    • 기본 정보 입력 (이름, 이메일, 비밀번호)
    • 역할 할당 (다중 선택 가능)
    • 부서 할당
    • 활성/비활성 설정
  • 권한: users.create
  • 검증:
    • 이메일 중복 체크
    • 비밀번호 강도 검증 (8자 이상, 영문+숫자)
    • 필수 필드 검증

1.4 회원 수정

  • 경로: /mng/users/{id}/edit
  • 기능:
    • 기본 정보 수정
    • 역할/부서 변경
    • 비밀번호 재설정
    • 활성/비활성 전환
  • 권한: users.update

1.5 회원 삭제

  • 경로: /mng/users/{id}
  • 기능:
    • Soft Delete (복구 가능)
    • 삭제 확인 모달
    • 연관 데이터 처리 (담당 영업 등)
  • 권한: users.delete

1.6 비밀번호 관리

  • 경로: /mng/users/{id}/password
  • 기능:
    • 관리자 비밀번호 재설정
    • 임시 비밀번호 발급 (이메일 전송)
    • 비밀번호 변경 이력 기록
  • 권한: users.password.reset

DB 스키마

-- users 테이블 (Laravel 기본 + 확장)
CREATE TABLE users (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    tenant_id BIGINT UNSIGNED NULL COMMENT '소속 테넌트 ID',
    name VARCHAR(255) NOT NULL COMMENT '사용자 이름',
    email VARCHAR(255) UNIQUE NOT NULL COMMENT '이메일 (로그인 ID)',
    email_verified_at TIMESTAMP NULL COMMENT '이메일 인증 시각',
    password VARCHAR(255) NOT NULL COMMENT '비밀번호 (해시)',
    phone VARCHAR(20) NULL COMMENT '연락처',
    department_id BIGINT UNSIGNED NULL COMMENT '부서 ID',
    is_active BOOLEAN DEFAULT TRUE COMMENT '활성 여부',
    last_login_at TIMESTAMP NULL COMMENT '마지막 로그인',
    remember_token VARCHAR(100) NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL COMMENT 'Soft Delete',

    INDEX idx_tenant_id (tenant_id),
    INDEX idx_email (email),
    INDEX idx_department_id (department_id),
    FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
    FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- model_has_roles 테이블 (Spatie Permission)
-- 이미 존재하는 테이블 활용

API 엔드포인트

Method Endpoint Description FormRequest
GET /mng/users 회원 목록 -
GET /mng/users/{id} 회원 상세 -
GET /mng/users/create 회원 생성 폼 -
POST /mng/users 회원 생성 StoreUserRequest
GET /mng/users/{id}/edit 회원 수정 폼 -
PUT /mng/users/{id} 회원 수정 UpdateUserRequest
DELETE /mng/users/{id} 회원 삭제 -
POST /mng/users/{id}/password/reset 비밀번호 재설정 ResetPasswordRequest

Service 클래스

// app/Services/UserService.php
class UserService
{
    public function list(array $filters): LengthAwarePaginator;
    public function find(int $id): User;
    public function create(array $data): User;
    public function update(User $user, array $data): User;
    public function delete(User $user): bool;
    public function resetPassword(User $user, string $newPassword): bool;
    public function assignRoles(User $user, array $roleIds): void;
}

UI/UX 와이어프레임 (텍스트)

┌─────────────────────────────────────────────────────────┐
│ 회원 관리                                    [+ 새 회원]  │
├─────────────────────────────────────────────────────────┤
│ 🔍 [검색: 이름, 이메일] [부서▼] [역할▼] [상태▼] [검색]│
├─────────────────────────────────────────────────────────┤
│ ☑ | 이름    | 이메일          | 부서   | 역할  | 상태 | 작업 │
│ ☐ | 홍길동  | hong@ex.com    | 개발팀 | Admin | 활성 | [수정][삭제] │
│ ☐ | 김철수  | kim@ex.com     | 영업팀 | User  | 활성 | [수정][삭제] │
├─────────────────────────────────────────────────────────┤
│ « 1 2 3 ... 10 »                                        │
└─────────────────────────────────────────────────────────┘

개발 체크리스트

  • User 모델에 BelongsToTenant trait 추가
  • UserService 클래스 작성 (비즈니스 로직)
  • StoreUserRequest, UpdateUserRequest 작성 (검증)
  • UserController 작성 (라우팅 처리)
  • Blade 템플릿 작성 (users/index.blade.php 등)
  • Alpine.js 인터랙션 추가 (모달, 검색 필터)
  • 권한 체크 미들웨어 적용 (can:users.index)
  • Audit Log 자동 기록 (UserObserver)
  • i18n 키 작성 (lang/ko/users.php)
  • Pint 포맷팅 및 PHPStan 검사 통과
  • 테스트 작성 (UserServiceTest, UserControllerTest)

2 테넌트관리 (Tenant Management)

기능 목록

2.1 테넌트 목록 조회

  • 경로: /mng/tenants
  • 기능:
    • 페이지네이션
    • 검색 (회사명, 도메인)
    • 필터 (구독 상태, 플랜)
    • 정렬 (생성일, 회사명)
  • 권한: tenants.index

2.2 테넌트 상세 조회

  • 경로: /mng/tenants/{id}
  • 기능:
    • 기본 정보 (회사명, 도메인, 연락처)
    • 구독 정보 (플랜, 만료일)
    • 사용 통계 (회원 수, 저장 용량)
    • 최근 결제 내역
  • 권한: tenants.show

2.3 테넌트 생성

  • 경로: /mng/tenants/create
  • 기능:
    • 회사 정보 입력
    • 도메인 설정 (예: company.sam.kr)
    • 초기 구독 플랜 선택
    • 관리자 계정 생성
  • 권한: tenants.create

2.4 테넌트 수정

  • 경로: /mng/tenants/{id}/edit
  • 기능:
    • 회사 정보 수정
    • 구독 플랜 변경
    • 활성/비활성 전환
  • 권한: tenants.update

2.5 테넌트 삭제

  • 경로: /mng/tenants/{id}
  • 기능:
    • Soft Delete
    • 연관 데이터 처리 (사용자, 게시물 등)
    • 삭제 전 데이터 백업 권장
  • 권한: tenants.delete

DB 스키마

CREATE TABLE tenants (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL COMMENT '회사명',
    domain VARCHAR(100) UNIQUE NOT NULL COMMENT '도메인 (예: company)',
    email VARCHAR(255) NOT NULL COMMENT '대표 이메일',
    phone VARCHAR(20) NULL COMMENT '대표 전화',
    address TEXT NULL COMMENT '주소',
    business_number VARCHAR(50) NULL COMMENT '사업자번호',
    subscription_plan ENUM('free', 'basic', 'pro', 'enterprise') DEFAULT 'free' COMMENT '구독 플랜',
    subscription_expires_at TIMESTAMP NULL COMMENT '구독 만료일',
    is_active BOOLEAN DEFAULT TRUE COMMENT '활성 여부',
    max_users INT DEFAULT 10 COMMENT '최대 사용자 수',
    storage_limit BIGINT DEFAULT 1073741824 COMMENT '저장 용량 제한 (바이트, 기본 1GB)',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL,

    INDEX idx_domain (domain),
    INDEX idx_subscription_plan (subscription_plan),
    INDEX idx_is_active (is_active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

API 엔드포인트

Method Endpoint Description FormRequest
GET /mng/tenants 테넌트 목록 -
GET /mng/tenants/{id} 테넌트 상세 -
GET /mng/tenants/create 테넌트 생성 폼 -
POST /mng/tenants 테넌트 생성 StoreTenantRequest
GET /mng/tenants/{id}/edit 테넌트 수정 폼 -
PUT /mng/tenants/{id} 테넌트 수정 UpdateTenantRequest
DELETE /mng/tenants/{id} 테넌트 삭제 -

Service 클래스

// app/Services/TenantService.php
class TenantService
{
    public function list(array $filters): LengthAwarePaginator;
    public function find(int $id): Tenant;
    public function create(array $data): Tenant;
    public function update(Tenant $tenant, array $data): Tenant;
    public function delete(Tenant $tenant): bool;
    public function changePlan(Tenant $tenant, string $plan): bool;
    public function getUsageStats(Tenant $tenant): array;
}

개발 체크리스트

  • Tenant 모델 작성 (BelongsToTenant 제외 - 최상위)
  • TenantService 클래스 작성
  • StoreTenantRequest, UpdateTenantRequest 작성
  • TenantController 작성
  • Blade 템플릿 작성
  • 구독 플랜 변경 로직 구현
  • 사용량 통계 계산 로직 (회원 수, 저장 용량)
  • i18n 키 작성
  • 테스트 작성

3 거래처관리 (Client Management)

기능 목록

3.1 거래처 목록 조회

  • 경로: /mng/clients
  • 기능:
    • 페이지네이션
    • 검색 (회사명, 담당자명)
    • 필터 (거래 상태, 업종)
    • 정렬 (생성일, 회사명)
  • 권한: clients.index

3.2 거래처 상세 조회

  • 경로: /mng/clients/{id}
  • 기능:
    • 기본 정보 (회사명, 연락처, 주소)
    • 담당자 정보 (이름, 직책, 연락처)
    • 거래 이력 (견적서, 계약)
    • 메모/코멘트
  • 권한: clients.show

3.3 거래처 생성

  • 경로: /mng/clients/create
  • 기능:
    • 회사 정보 입력
    • 담당자 정보 입력 (다중 가능)
    • 업종/분류 선택
    • 메모 작성
  • 권한: clients.create

3.4 거래처 수정

  • 경로: /mng/clients/{id}/edit
  • 기능:
    • 기본 정보 수정
    • 담당자 추가/수정/삭제
    • 거래 상태 변경
  • 권한: clients.update

3.5 거래처 삭제

  • 경로: /mng/clients/{id}
  • 기능:
    • Soft Delete
    • 연관 데이터 체크 (진행 중인 견적서 등)
  • 권한: clients.delete

DB 스키마

CREATE TABLE clients (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    tenant_id BIGINT UNSIGNED NOT NULL COMMENT '소속 테넌트',
    name VARCHAR(255) NOT NULL COMMENT '회사명',
    business_number VARCHAR(50) NULL COMMENT '사업자번호',
    industry VARCHAR(100) NULL COMMENT '업종',
    phone VARCHAR(20) NULL COMMENT '대표 전화',
    email VARCHAR(255) NULL COMMENT '대표 이메일',
    address TEXT NULL COMMENT '주소',
    status ENUM('active', 'inactive', 'potential') DEFAULT 'potential' COMMENT '거래 상태',
    notes TEXT NULL COMMENT '메모',
    assigned_user_id BIGINT UNSIGNED NULL COMMENT '담당 영업 사원',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL,

    INDEX idx_tenant_id (tenant_id),
    INDEX idx_status (status),
    INDEX idx_assigned_user_id (assigned_user_id),
    FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE,
    FOREIGN KEY (assigned_user_id) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE client_contacts (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    client_id BIGINT UNSIGNED NOT NULL COMMENT '거래처 ID',
    name VARCHAR(255) NOT NULL COMMENT '담당자 이름',
    position VARCHAR(100) NULL COMMENT '직책',
    phone VARCHAR(20) NULL COMMENT '연락처',
    email VARCHAR(255) NULL COMMENT '이메일',
    is_primary BOOLEAN DEFAULT FALSE COMMENT '주 담당자 여부',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    INDEX idx_client_id (client_id),
    FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

API 엔드포인트

Method Endpoint Description FormRequest
GET /mng/clients 거래처 목록 -
GET /mng/clients/{id} 거래처 상세 -
GET /mng/clients/create 거래처 생성 폼 -
POST /mng/clients 거래처 생성 StoreClientRequest
GET /mng/clients/{id}/edit 거래처 수정 폼 -
PUT /mng/clients/{id} 거래처 수정 UpdateClientRequest
DELETE /mng/clients/{id} 거래처 삭제 -
POST /mng/clients/{id}/contacts 담당자 추가 StoreContactRequest

Service 클래스

// app/Services/ClientService.php
class ClientService
{
    public function list(array $filters): LengthAwarePaginator;
    public function find(int $id): Client;
    public function create(array $data): Client;
    public function update(Client $client, array $data): Client;
    public function delete(Client $client): bool;
    public function addContact(Client $client, array $contactData): ClientContact;
    public function getTransactionHistory(Client $client): Collection;
}

개발 체크리스트

  • Client, ClientContact 모델 작성 (BelongsToTenant)
  • ClientService 클래스 작성
  • FormRequest 작성
  • ClientController 작성
  • Blade 템플릿 작성 (담당자 다중 입력 UI)
  • 거래 이력 연동 (견적서, 계약)
  • 담당 영업 사원 할당 기능
  • i18n 키 작성
  • 테스트 작성

🎯 Phase 1 완료 조건

기능 완성도

  • 3개 모듈 모두 CRUD 완성
  • 각 모듈별 검색/필터/정렬 동작
  • 권한 체크 정상 작동

코드 품질

  • Service-First 패턴 준수
  • FormRequest 검증 구현
  • BelongsToTenant trait 적용
  • i18n 키 사용 (한글 직접 사용 금지)
  • Pint 포맷팅 통과
  • PHPStan Level 5+ 통과

데이터 무결성

  • Multi-tenant 격리 확인
  • Soft Delete 동작 확인
  • Audit Log 자동 기록 확인
  • Foreign Key 제약 조건 정상 작동

테스트

  • Service 계층 유닛 테스트
  • Controller 계층 Feature 테스트
  • 권한 체크 테스트
  • 검증 로직 테스트

📚 참고 자료

  • SAM API Rules: API_RULES.md
  • 개발 명령어: DEV_COMMANDS.md
  • 품질 체크리스트: QUALITY_CHECKLIST.md

최종 업데이트: 2025-11-21 작성자: Claude Code 버전: 1.0.0