- GlobalMenuTemplateSeeder 추가: 60개 메뉴 템플릿 생성 (tenant_id=NULL)
- MenuBootstrapService.cloneGlobalMenusForTenant() 추가
- parent_id 매핑으로 계층 구조 유지
- DB 트랜잭션으로 원자성 보장
- RegisterService 업데이트: 신규 회원가입 시 메뉴 템플릿 복제
- 기존 225개 테넌트에 메뉴 일괄 복제 완료
- 테스트 완료: 회원가입 + 로그인 시 60개 메뉴 정상 반환
- MemberService::getUserInfoForLogin(): 사용자 역할 조회 로직 추가
- ApiController::login(): 응답에 roles 포함
- AuthApi (Swagger): roles 응답 스키마 추가
- 로그인 시 해당 회원의 역할 목록 반환 (id, name, description)
fix: 회원가입 시 UserTenant 생성 누락으로 인한 로그인 실패 수정
근본 원인:
- RegisterService는 TenantUserProfile만 생성
- MemberService::getUserInfoForLogin()은 UserTenant 조회
- 회원가입 직후 로그인 시 테넌트 조회 실패 (userTenants->isEmpty() = true)
해결 방안:
- RegisterService에 UserTenant::create() 추가
- TenantUserProfile: 프로필 정보 (부서, 직급 등)
- UserTenant: 접근 권한 관리 (is_active, is_default, joined_at)
영향도:
- 신규 사용자: 로그인 가능하게 수정
- 기존 사용자: 영향 없음 (user_tenants 데이터 이미 존재)
fix: 로그인 시 테넌트 없는 경우 roles 누락 오류 수정
- MemberService::getUserInfoForLogin(): 테넌트가 없는 경우에도 roles 빈 배열 반환
- Undefined array key 'roles' 에러 해결
MemberService.php 권한 조회 로직 수정 - 역할 기반 권한 지원
[문제]
- 회원가입 후 로그인 시 메뉴 리스트가 표시되지 않음
- RegisterService에서 역할에 권한 할당(role_has_permissions)하고
사용자에게 역할 부여(model_has_roles)
- 하지만 MemberService는 model_has_permissions(직접 사용자 권한)만 조회
[원인]
- Spatie Permission 아키텍처 불일치
- 권한이 역할에 저장되었으나 직접 사용자 권한 테이블만 조회
[해결]
- model_has_roles → role_has_permissions → permissions 조인 쿼리로 변경
- UNION으로 직접 권한(model_has_permissions)도 지원하는 하이브리드 방식
- 역할 기반 권한과 직접 권한 모두 조회 가능
[변경 파일]
- app/Services/MemberService.php (getUserInfoForLogin 메서드, 239-259줄)
주요 변경사항:
- RegisterService.php: 생성된 메뉴 정보를 조회해서 응답에 포함
- RegisterApi.php: Swagger 문서에 menus 배열 스키마 추가
응답 구조:
{
user: {...},
tenant: {...},
menus: [
{id, parent_id, name, url, icon, sort_order, is_external, external_url}
]
}
기술 세부사항:
- 생성된 메뉴 ID 배열을 사용해 Menu::whereIn() 조회
- parent_id, sort_order 순서로 정렬
- 로그인 API와 동일한 메뉴 정보 구조 제공
- MenuBootstrapService 생성: 새 테넌트를 위한 기본 메뉴 9개 자동 생성
- 대시보드
- 기초정보관리 (제품/거래처/BOM 관리)
- 시스템 관리 (사용자/권한/부서 관리)
- RegisterService 수정: 메뉴 생성 후 권한 자동 설정
- 생성된 메뉴에 대한 권한(menu.{id}) 자동 생성
- system_manager 역할에 모든 메뉴 권한 할당
- 기존 테이블 구조에 맞게 구현 (code, route_name, depth, description 컬럼 미사용)
- message.registered 수정: '회원가입 처리'로 변경 (에러 메시지 개선)
- RecipeRegistry 호출 제거 (클래스 존재하지 않음)
- 메뉴 기반 권한 생성 로직 제거
- system_manager 역할만 생성하고 사용자에게 부여
- 메뉴 테이블 컬럼 불일치 오류 해결
현재는 기본 회원가입 기능만 제공:
- 테넌트 생성 (코드 자동 생성)
- 사용자 생성
- 테넌트-사용자 프로필 연결
- system_manager 역할 부여
향후 메뉴 시스템이 완성되면 RecipeRegistry를 다시 활성화할 예정
- TenantCodeGenerator 헬퍼 클래스 생성
- 한글 초성 추출 및 영문 변환
- Base-36 순번 생성 (최대 1,679,616 코드)
- 순환형 코드 생성 (초성+순번 조합)
- RegisterService에서 테넌트 생성 시 코드 자동 생성
- 회원가입 시 'code' 필드 누락 오류 해결
- 사용자 등록 + 테넌트 생성 + 시스템 관리자 권한 자동 부여
- 사업자번호 조건부 검증 (active 테넌트만 unique)
- 글로벌 메뉴 자동 복제 (parent_id 매핑 알고리즘)
- DB 트랜잭션으로 전체 프로세스 원자성 보장
추가:
- RegisterRequest: FormRequest 검증 (conditional unique)
- RegisterService: 9-step 통합 비즈니스 로직
- RegisterController: ApiResponse::handle() 패턴
- RegisterApi: 완전한 Swagger 문서
수정:
- MenusStep: 글로벌 메뉴 복제 로직 구현
- message.php: 'registered' 키 추가
- error.php: 4개 에러 메시지 추가
- routes/api.php: POST /api/v1/register 라우트
SAM API Rules 준수:
- Service-First, FormRequest, i18n, Swagger, DB Transaction