Files
eomsangdonandClaude Opus 5 eb30b774f8 chore(docs): docs 폴더 git 추적 전환 · PLAN·OWNERS 최상위 이관
- `docs/` 를 .gitignore 에서 빼 git 추적 대상으로 전환 (위키·완료 이력·검증 기록)
- `docs/raw/PLAN.md` · `docs/raw/OWNERS.md` 를 저장소 최상위로 이동 후 .gitignore 에 등록
  — 창끼리 공유하되 저장소에는 안 올리는 장부
- 살아 있는 경로 참조 7개 파일 정정 (아카이브 107건은 그때 사실이라 그대로 둠)
- graphify 날짜별 산출물(`docs/wiki/graphify-out/20*/`) 제외 — `graphify update` 가 다시 만듦

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 18:19:07 +09:00

93 lines
4.3 KiB
Markdown

---
type: concept
status: stable
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[auth_rbac]]", "[[architecture/shared_resources]]"]
last_updated: 2026-07-17
source: docs/raw/verification/2026-07-17_verify_auth_reverify.md
---
# DB: 사용자/인증/조직 테이블
Links: ← [[db_schema/overview]]
## users (사용자)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `int(11)` | NO | PRI | `auto_increment` |
| `email` | `varchar(255)` | NO | UNI | |
| `password_hash` | `varchar(255)` | NO | | |
| `name` | `varchar(255)` | NO | | |
| `position` / `department` | `varchar(100)` | YES | | 직위 / 부서 |
| `phone` | `varchar(20)` | YES | | |
| `company_id` | `int(11)` | YES | MUL | FK→companies.id |
| `role` | `enum('SYSTEM_ADMIN','ADMIN','USER')` | NO | MUL | `USER` |
| `is_master` | `tinyint(1)` | NO | | `0` (마스터 여부) |
| `status` | `enum('PENDING_EMAIL','NO_COMPANY','PENDING','ACTIVE','INACTIVE','REJECTED')` | NO | MUL | `PENDING_EMAIL` |
| `last_login` | `datetime` | YES | | 최종 로그인 일시 |
| `login_failures` | `int(11)` | NO | | `0` (실패 횟수) |
| `created_at` / `updated_at` / `deleted_at` | `timestamp` | - | | 생성 / 수정 / soft-delete |
* **사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (사용자 관리), 전 페이지 공통 인증 (`auth_expires_at` 컬럼 삭제 완료)
## companies (회사)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `int(11)` | NO | PRI | `auto_increment` |
| `name` | `varchar(255)` | NO | UNI | 회사명 |
| `business_registration_number` | `varchar(20)` | YES | UNI | 사업자번호 |
| `status` | `enum('ACTIVE','INACTIVE','SUSPENDED')` | NO | | `ACTIVE` |
| `subscription_status` | `enum('FREE','TRIAL','PAID','EXPIRED')` | NO | | `FREE` |
| `created_by` | `int(11)` | YES | MUL | FK→users.id (생성자) |
| `company_code` | `varchar(20)` | YES | | 참여용 코드 |
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]]
## sessions (세션)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `varchar(255)` | NO | PRI | 세션 ID (쿠키 값) |
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
| `user_agent_hash` | `char(64)` | NO | | |
| `expires_at` | `timestamp` | NO | MUL | 만료일시 |
| `last_activity_at` | `timestamp` | NO | | 최종 활동일시 |
**사용처:** 전 페이지 공통 (세션 인증) — 상세 → [[auth_rbac]]
## email_otps (이메일 OTP)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
| `purpose` | `enum('REGISTER','LOGIN','REVERIFY','PASSWORD_CHANGE')` | NO | | 용도 |
| `otp_hash` | `varchar(255)` | NO | | OTP 해시값 |
| `expires_at` / `consumed_at` | `timestamp` | - | | 만료일시 / 사용일시 |
## trusted_devices (신뢰 기기)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
| `token_hash` | `varchar(255)` | NO | UNI | 디바이스 토큰 해시 (2026-07-17 추가) |
| `verified_at` / `last_used_at` | `timestamp` | NO | | 검증 / 최종 사용 일시 |
## join_requests (회사 가입 신청)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `int(11)` | NO | PRI | `auto_increment` |
| `user_id` / `company_id` | `int(11)` | NO | MUL | FK→users/companies |
| `status` | `enum('PENDING','APPROVED','REJECTED')` | NO | | `PENDING` |
| `requested_at` / `reviewed_at` | `timestamp` | - | | 신청 / 검토 일시 |
| `reviewed_by` | `int(11)` | YES | MUL | FK→users.id (검토자) |
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (`B01_Dashboard_Repository.py:378` 가입 신청·처리)
## user_consents (약관 동의)
| 컬럼 | 타입 | Null | Key | Default / Extra |
|---|---|---|---|---|
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
| `terms_version` | `varchar(20)` | NO | | 동의한 약관 버전 |
| `terms_agreed` / `privacy_agreed` | `tinyint(1)` | NO | | 필수 동의여부 (1=동의) |
| `marketing_agreed` | `tinyint(1)` | NO | | `0` (선택 마케팅동의) |
| `agreed_at` | `timestamp` | NO | | 동의 일시 |