# Kratos 사용자 traits 필드 인벤토리

작성일: 2026-05-13

## 확인 대상

- 설정 파일: `docker/ory/kratos/identity.schema.json`
- 로컬 Kratos DB: `ory_postgres` / `ory_kratos.identities.traits`
- 전역 Personal 테넌트: `9607eb7b-04d2-42ab-80fe-780fe21c7e8f` / `personal`

## Kratos schema에 설정된 traits 필드

| 필드 | 타입 | 용도 |
| --- | --- | --- |
| `custom_login_ids` | string array | password identifier |
| `email` | string | password/code identifier, recovery, verification, required |
| `name` | string | 사용자 이름 |
| `phone_number` | string | password/code SMS identifier |
| `department` | string | 부서 |
| `affiliationType` | string | 소속 유형 |
| `companyCode` | string | 대표 테넌트 slug |
| `role` | string | 권한 역할 |
| `tenant_id` | string | 대표 테넌트 UUID |
| `displayname` | string | 레거시 표시 이름 후보 |
| `completeForm` | boolean | 레거시 가입 폼 완료 여부 후보 |
| `team` | string | 레거시 팀 후보 |
| `taxCode` | string | 레거시 세무 코드 후보 |
| `familyCompany` | string | 레거시 가족사 후보 |
| `familyUniqueKey` | string | 레거시 가족사 고유키 후보 |
| `personal` | boolean | 레거시 Personal 여부 후보 |
| `grade` | string | 직급 |

현재 schema는 `additionalProperties: true`라서 위 목록에 없는 traits도 저장 가능합니다.

## 로컬 Kratos DB에 실제 저장된 traits 필드

| 필드 | identity 수 |
| --- | ---: |
| `affiliationType` | 3 |
| `companyCode` | 3 |
| `companyCodes` | 1 |
| `department` | 3 |
| `email` | 3 |
| `grade` | 3 |
| `name` | 3 |
| `phone_number` | 1 |
| `role` | 3 |
| `tenant_id` | 1 |

## 정리 후보

유지 후보:

- 인증 식별자: `email`, `phone_number`, `custom_login_ids`
- 사용자 기본 프로필: `name`
- 권한/대표 소속: `role`, `tenant_id`, `companyCode`
- 조직 표시/연동: `department`, `grade`
- 다중 소속이 필요한 동안 유지: `companyCodes`

schema 추가 검토 후보:

- Backend read model에서 읽는 `position`, `jobTitle`
- 한맥가족 다중 소속을 metadata로 유지할 경우 `additionalAppointments`
- 대표 테넌트 표시값을 traits로 계속 줄 경우 `primaryTenantId`, `primaryTenantSlug`, `primaryTenantName`, `primaryTenantIsOwner`

제거 후보:

- `displayname`
- `completeForm`
- `team`
- `taxCode`
- `familyCompany`
- `familyUniqueKey`
- `personal`
- `hanmacFamily`는 이미 `test/kratos_identity_schema_policy_test.sh`에서 금지 필드로 검사 중입니다.

## 제안 정책

1. Personal 사용자는 사용자별 Personal 테넌트를 생성하지 않고 전역 `personal` 테넌트만 사용합니다.
2. Kratos traits는 인증/클레임에 필요한 최소 필드만 유지합니다.
3. 조직도나 연동 전용 확장 데이터는 traits 최상위에 흩뿌리지 않고 Ory에 저장되지 않거나 조회가 불가능한 Backend read model 또는 명시된 metadata 구조로 모읍니다.
4. `additionalProperties: true`를 바로 `false`로 바꾸면 기존 identity 갱신이 실패할 수 있으므로, 먼저 backend sanitizer와 마이그레이션으로 제거 후보를 정리한 뒤 schema를 닫습니다.
