# 083 마이그레이션 — 회사 관리 감사 로그 테이블

작성일: 2026-04-24
작성자: gbpark
관련: 회사 관리 화면 (`/admin/sysMng/subdomainList`) 라이프사이클 액션 감사 로그

## 목적

회사 관리 화면에서 수행되는 SUPER_ADMIN 레벨 액션을 메타 DB 에 추적 가능하게 기록.

### 기록 대상 액션

| action | 기록 지점 |
|---|---|
| `COMPANY_CREATE` | 프로비저닝 성공 시 (FINALIZE) |
| `COMPANY_CREATE_FAILED` | 프로비저닝 실패 시 (자동 롤백 후) |
| `COMPANY_DEACTIVATE` | `DB_STATUS=suspended` 변경 시 |
| `COMPANY_REACTIVATE` | `suspended → active` 복귀 시 |
| `COMPANY_DELETE` | 영구 삭제 (DROP DATABASE + row DELETE) 시 |
| `ADMIN_PASSWORD_RESET` | 관리자 계정 비번 재설정 시 |
| `TEMPLATES_RECOPY` | 템플릿 재복제 시 |

## 추가 테이블

```sql
CREATE TABLE IF NOT EXISTS COMPANY_AUDIT_LOG (
    ID             BIGSERIAL    PRIMARY KEY,
    COMPANY_CODE   VARCHAR(30)  NOT NULL,
    ACTOR_USER_ID  VARCHAR(50),                  -- 수행자 (JWT 에서 뽑아낸 user_id). 개발모드는 NULL 가능
    ACTION         VARCHAR(40)  NOT NULL,        -- 위 표의 action 값
    TARGET         VARCHAR(100),                 -- 영향받은 대상 (db_name, admin user_id 등)
    DETAILS        JSONB,                        -- 추가 컨텍스트 (reason, before/after 값 등)
    SUCCESS        BOOLEAN      DEFAULT TRUE,
    ERROR_MESSAGE  TEXT,                         -- 실패 시 에러 메시지
    CREATED_AT     TIMESTAMP    DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS IDX_AUDIT_COMPANY_CODE
    ON COMPANY_AUDIT_LOG (COMPANY_CODE, CREATED_AT DESC);

CREATE INDEX IF NOT EXISTS IDX_AUDIT_CREATED
    ON COMPANY_AUDIT_LOG (CREATED_AT DESC);

CREATE INDEX IF NOT EXISTS IDX_AUDIT_ACTION
    ON COMPANY_AUDIT_LOG (ACTION, CREATED_AT DESC);
```

## 실행 (메타 DB 만)

이 테이블은 **메타 DB (`invyone`) 에만** 존재해야 한다. 테넌트 DB 는 복제 대상 아님.
`SchemaCopier` 는 메타 DB 를 `pg_dump --schema-only` 로 복제하므로, 새 테넌트 DB 에 이 테이블이
딸려가는 걸 막으려면 이 테이블은 `COMPANY_MNG` 와 같이 "메타 전용" 취급.

### SchemaCopier 의 `--exclude-table` 처리 확인 필요
현재 구현은 public 스키마 전체를 복제. `COMPANY_AUDIT_LOG` 가 테넌트 DB 에도 생성되지만
**어차피 쓰지 않으므로 빈 채로 남는다.** 용량 문제 없음 → MVP 로는 허용. 추후 정리.

```bash
psql -h 183.99.177.40 -U postgres -d invyone <<'SQL'
CREATE TABLE IF NOT EXISTS COMPANY_AUDIT_LOG (
    ID             BIGSERIAL    PRIMARY KEY,
    COMPANY_CODE   VARCHAR(30)  NOT NULL,
    ACTOR_USER_ID  VARCHAR(50),
    ACTION         VARCHAR(40)  NOT NULL,
    TARGET         VARCHAR(100),
    DETAILS        JSONB,
    SUCCESS        BOOLEAN      DEFAULT TRUE,
    ERROR_MESSAGE  TEXT,
    CREATED_AT     TIMESTAMP    DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS IDX_AUDIT_COMPANY_CODE ON COMPANY_AUDIT_LOG (COMPANY_CODE, CREATED_AT DESC);
CREATE INDEX IF NOT EXISTS IDX_AUDIT_CREATED      ON COMPANY_AUDIT_LOG (CREATED_AT DESC);
CREATE INDEX IF NOT EXISTS IDX_AUDIT_ACTION       ON COMPANY_AUDIT_LOG (ACTION, CREATED_AT DESC);
SQL
```

## 롤백

```sql
DROP TABLE IF EXISTS COMPANY_AUDIT_LOG;
```
