--- type: concept status: stable related_pages: ["[[B01_Dashboard/B01_backend]]"] last_updated: 2026-07-12 source: raw/guidelines/db_schema.md --- # DB: 사용자/인증/조직 테이블 ← [[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` | | `auth_expires_at` / `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]] (사용자 관리), 전 페이지 공통 인증 ## 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 | | `user_agent_hash` | `char(64)` | NO | | 브라우저 지문 해시 | | `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 | | 동의 일시 |