Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
40 lines
3.7 KiB
JavaScript
40 lines
3.7 KiB
JavaScript
/**
|
|
* portal/mail/model.mjs — 메일 영역 세부 표(§15~§18, §23.2). 중심 표(mail_services·mailboxes·domains)는 portal/core/model.mjs 에 있다.
|
|
*
|
|
* mail_servers 운영자가 등록한 AriMail 서버(공개 주소·내부 주소·전체 설정 주소·설정 API Host(setup_host: AriMail 전체 설정 API 는 기본 도메인 호스트에서만 응답한다 — 실제 환경 결함 수정)·메일 프로그램 접속 호스트). 비밀(설정 토큰·사용량 키·SSO 비밀)은 보관소 'arimail:<id>:*'.
|
|
* mail_tests 실제 외부 송신·수신·회신 확인 기록(활성화·전환 전후·수동). 단계와 결과만, 메일 내용은 없음.
|
|
* mail_invites 메일함 초대(초기 비밀번호 대신 링크로 비밀번호를 정함): 토큰 해시·만료·사용 완료·재발송 횟수.
|
|
* mail_aliases 별칭·전달 전용 주소 기록(정책 미확정이면 생성 불가, §16.2).
|
|
* mail_exports 해지 뒤 30일 읽기·내보내기(.eml 묶음) 요청 기록(§23.2).
|
|
* mail_conversions 사이트 대표 메일 → 독립 메일 서비스 전환 점검표와 전후 확인(§14).
|
|
* mail_usage_log 서비스·메일함 사용량 계측 이력(화면 "마지막 계측 시각"·추이).
|
|
*/
|
|
export const MIGRATIONS = [{ id: 'mail_0001', sql: `
|
|
CREATE TABLE IF NOT EXISTS mail_servers (
|
|
id TEXT PRIMARY KEY, name TEXT NOT NULL, base_url TEXT NOT NULL, internal_url TEXT, setup_url TEXT, mail_host TEXT, is_default INTEGER NOT NULL DEFAULT 0,
|
|
status TEXT NOT NULL DEFAULT 'active', last_health_at TEXT, last_health_json TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL
|
|
);
|
|
CREATE TABLE IF NOT EXISTS mail_tests (
|
|
id TEXT PRIMARY KEY, mail_service_id TEXT NOT NULL, group_id TEXT NOT NULL, kind TEXT NOT NULL, status TEXT NOT NULL, verifier TEXT, job_id TEXT, steps_json TEXT, result_json TEXT,
|
|
created_by TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, ended_at TEXT
|
|
);
|
|
CREATE INDEX IF NOT EXISTS mail_tests_service ON mail_tests(mail_service_id, created_at);
|
|
CREATE TABLE IF NOT EXISTS mail_invites (
|
|
id TEXT PRIMARY KEY, mailbox_id TEXT NOT NULL, group_id TEXT NOT NULL, email TEXT, token_hash TEXT NOT NULL UNIQUE, expires_at TEXT NOT NULL, used_at TEXT, resent_count INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL
|
|
);
|
|
CREATE TABLE IF NOT EXISTS mail_aliases (
|
|
id TEXT PRIMARY KEY, mail_service_id TEXT NOT NULL, group_id TEXT NOT NULL, address TEXT NOT NULL UNIQUE, target TEXT NOT NULL, kind TEXT NOT NULL DEFAULT 'alias', status TEXT NOT NULL DEFAULT 'active', created_at TEXT NOT NULL
|
|
);
|
|
CREATE TABLE IF NOT EXISTS mail_exports (
|
|
id TEXT PRIMARY KEY, mail_service_id TEXT NOT NULL, group_id TEXT NOT NULL, status TEXT NOT NULL, location TEXT, size_bytes INTEGER, created_by TEXT, created_at TEXT NOT NULL, expires_at TEXT, ended_at TEXT, error TEXT
|
|
);
|
|
CREATE TABLE IF NOT EXISTS mail_conversions (
|
|
id TEXT PRIMARY KEY, mail_service_id TEXT NOT NULL, group_id TEXT NOT NULL, site_id TEXT NOT NULL, status TEXT NOT NULL, checklist_json TEXT NOT NULL, before_test_id TEXT, after_test_id TEXT, job_id TEXT,
|
|
created_by TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, ended_at TEXT, error TEXT
|
|
);
|
|
CREATE TABLE IF NOT EXISTS mail_usage_log (
|
|
id TEXT PRIMARY KEY, mail_service_id TEXT NOT NULL, group_id TEXT NOT NULL, subject_type TEXT NOT NULL, subject_id TEXT NOT NULL, storage_bytes INTEGER, monthly_messages INTEGER, mailboxes INTEGER, warn_level INTEGER, limited_json TEXT, measured_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS mail_usage_log_subject ON mail_usage_log(subject_type, subject_id, measured_at);
|
|
` }, { id: 'mail_0002_setup_host', sql: `ALTER TABLE mail_servers ADD COLUMN setup_host TEXT;` }];
|