mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 21:56:24 +00:00
전체 5개 마이크로서비스의 내부 처리 흐름을 상세히 설계 [추가된 파일] - Meeting Service: 6개 시나리오 (검증완료, 실시간수정동기화, 최종회의록확정, 충돌해결, 템플릿선택, 회의록목록조회) - STT Service: 2개 시나리오 (음성녹음인식, 텍스트변환) - User Service: 2개 시나리오 (사용자인증, 대시보드조회) - Notification Service: 1개 시나리오 (알림발송) [주요 설계 내용] - Clean Architecture 적용 (Controller → Service → Domain → Repository) - Cache-Aside 패턴 (Redis 기반 성능 최적화) - Event-Driven Architecture (Azure Event Hub) - Real-time Collaboration (WebSocket + OT 알고리즘) - RAG 기능 (맥락 기반 AI) [검증 결과] - PlantUML 문법 검증: 모든 파일 통과 ✅ - 유저스토리 매칭: 100% 일치 ✅ - 아키텍처 패턴 준수: 완료 ✅ [병렬 처리] - 서브 에이전트 3개로 병렬 작업 수행 - Meeting Service, AI Service, STT/User/Notification 동시 설계 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
151 lines
3.9 KiB
Plaintext
151 lines
3.9 KiB
Plaintext
@startuml
|
|
!theme mono
|
|
|
|
title 사용자 인증 내부 시퀀스 (AFR-USER-010)
|
|
|
|
participant "API Gateway<<E>>" as Gateway
|
|
participant "UserController" as Controller
|
|
participant "AuthService" as Service
|
|
participant "LdapAuthenticator" as LdapAuth
|
|
participant "LDAP<<E>>" as LDAP
|
|
participant "JwtTokenProvider" as TokenProvider
|
|
participant "UserRepository" as Repository
|
|
database "PostgreSQL<<E>>" as DB
|
|
database "Redis Cache<<E>>" as Cache
|
|
|
|
Gateway -> Controller: POST /api/v1/auth/login\n{username, password}
|
|
activate Controller
|
|
|
|
Controller -> Service: authenticate(username, password)
|
|
activate Service
|
|
|
|
Service -> LdapAuth: validateCredentials(username, password)
|
|
activate LdapAuth
|
|
|
|
LdapAuth -> LDAP: bind(dn, password)
|
|
note right
|
|
LDAP 인증:
|
|
- DN: cn={username},ou=users,dc=company,dc=com
|
|
- Protocol: LDAPS (636)
|
|
- Timeout: 5s
|
|
end note
|
|
|
|
alt 인증 성공
|
|
LDAP --> LdapAuth: authentication success
|
|
|
|
LdapAuth -> LDAP: searchUser(username)
|
|
note right
|
|
사용자 정보 조회:
|
|
- cn (이름)
|
|
- mail (이메일)
|
|
- department (부서)
|
|
- title (직급)
|
|
end note
|
|
|
|
LDAP --> LdapAuth: user attributes
|
|
|
|
LdapAuth --> Service: UserDetails
|
|
deactivate LdapAuth
|
|
|
|
Service -> Repository: findByUsername(username)
|
|
activate Repository
|
|
Repository -> DB: SELECT * FROM users\nWHERE username = ?
|
|
|
|
alt 사용자 존재
|
|
DB --> Repository: user data
|
|
else 신규 사용자
|
|
Repository -> DB: INSERT INTO users\n(username, email, department)
|
|
DB --> Repository: user created
|
|
note right
|
|
LDAP 정보 동기화:
|
|
- 자동 사용자 등록
|
|
- 프로필 정보 저장
|
|
end note
|
|
end
|
|
|
|
Repository --> Service: User entity
|
|
deactivate Repository
|
|
|
|
Service -> TokenProvider: generateAccessToken(user)
|
|
activate TokenProvider
|
|
|
|
TokenProvider -> TokenProvider: createClaims(user)
|
|
note right
|
|
JWT Claims:
|
|
- sub: userId
|
|
- username
|
|
- roles
|
|
- exp: 1h
|
|
end note
|
|
|
|
TokenProvider -> TokenProvider: signToken(claims, secretKey)
|
|
TokenProvider --> Service: access token
|
|
deactivate TokenProvider
|
|
|
|
Service -> TokenProvider: generateRefreshToken(user)
|
|
activate TokenProvider
|
|
|
|
TokenProvider -> TokenProvider: createRefreshClaims(user)
|
|
note right
|
|
Refresh Token:
|
|
- sub: userId
|
|
- type: refresh
|
|
- exp: 7d
|
|
end note
|
|
|
|
TokenProvider --> Service: refresh token
|
|
deactivate TokenProvider
|
|
|
|
Service -> Cache: storeRefreshToken(userId, refreshToken)
|
|
note right
|
|
Redis 저장:
|
|
- Key: refresh:{userId}
|
|
- Value: refreshToken
|
|
- TTL: 7d
|
|
end note
|
|
Cache --> Service: stored
|
|
|
|
Service -> Repository: updateLastLogin(userId)
|
|
activate Repository
|
|
Repository -> DB: UPDATE users\nSET last_login_at = NOW()
|
|
DB --> Repository: updated
|
|
Repository --> Service: updated
|
|
deactivate Repository
|
|
|
|
Service --> Controller: AuthResponse\n{accessToken, refreshToken, user}
|
|
deactivate Service
|
|
|
|
Controller --> Gateway: 200 OK\n{tokens, userInfo}
|
|
deactivate Controller
|
|
|
|
else 인증 실패
|
|
LDAP --> LdapAuth: authentication failed
|
|
LdapAuth --> Service: AuthenticationException
|
|
deactivate LdapAuth
|
|
|
|
Service -> Repository: incrementFailedAttempts(username)
|
|
activate Repository
|
|
Repository -> DB: UPDATE users\nSET failed_attempts = failed_attempts + 1
|
|
|
|
alt 실패 횟수 초과 (5회)
|
|
Repository -> DB: UPDATE users\nSET locked_until = NOW() + INTERVAL '30 minutes'
|
|
note right
|
|
계정 잠금:
|
|
- 5회 실패 시
|
|
- 30분 잠금
|
|
end note
|
|
end
|
|
|
|
DB --> Repository: updated
|
|
Repository --> Service: updated
|
|
deactivate Repository
|
|
|
|
Service --> Controller: AuthenticationException
|
|
deactivate Service
|
|
|
|
Controller --> Gateway: 401 Unauthorized\n{error: "Invalid credentials"}
|
|
deactivate Controller
|
|
end
|
|
|
|
@enduml
|