Files
AriWeb-Suite/portal/mail/model.mjs
T

41 lines
3.8 KiB
JavaScript

/**
* portal/mail/model.mjs — 메일 영역 세부 표(§15~§18, §23.2). 중심 표(mail_services·mailboxes·domains)는 portal/core/model.mjs 에 있다.
*
* mail_servers 운영자가 등록한 AriMail 서버(공개 주소·내부 주소·전체 설정 주소·메일 프로그램 접속 호스트). 전체 설정 주소(setup_url)는 AriMail 이 설정 API 를 기본 도메인 호스트에서만 응답하므로
* 기본 도메인 이름(예: https://mail.arihakdang.com:8791)이어야 한다 — Node fetch 는 Host 헤더를 바꿀 수 없어 이름이 그 서버의 설정 포트로 풀려야 한다(같은 호스트면 /etc/hosts). 비밀(설정 토큰·사용량 키·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);
` }];