┌──────────────────────────┐
│ ontology_entities │ ◀── 모든 것의 중심
│ 1,597 rows │
└─────┬──────────┬──────────┘
│ │
┌───────────▼──┐ ┌───▼────────────┐
│ontology_links│ │ ontology_events │
│ 8,417 rows │ │ 950 rows │
└──────────────┘ └─────────────────┘
│ │
┌───────────▼──────────▼──────────┐
│ ontology_entity_activity_summary │ ◀── Materialized View
└─────────────────────────────────┘
┌──────────────┐ ┌───────────────────────────┐
│ slack_channels│────▶│ channel_activity_profiles │
│ 349 rows │ │ 181 rows │
└──────┬───────┘ └───────────────────────────┘
│
┌──────▼────────┐
│ slack_messages │
│ ~27,000 rows │
└───────────────┘
| 컬럼 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
id | UUID | NO | gen_random_uuid() | Primary Key |
entity_type | TEXT | NO | 엔티티 유형 | |
source | TEXT | NO | 데이터 출처 | |
external_id | TEXT | NO | 출처 시스템 내 고유 ID | |
canonical_email | TEXT | YES | 사람 엔티티의 크로스시스템 식별자 | |
display_name | TEXT | NO | '' | 표시 이름 |
properties | JSONB | NO | '{}' | 유형별 상세 속성 |
status | TEXT | NO | 'active' | active / archived / deleted |
created_at | TIMESTAMPTZ | NO | now() | |
updated_at | TIMESTAMPTZ | NO | now() | 트리거로 자동 갱신 |
space — Slack 채널349issue — Jira 이슈265absence — 부재/연차263message — Slack 메시지239meeting — 회의실 예약158person — 조직 구성원133document — Confluence 문서84department — 부서51announcement — 공지사항50room — 회의실5build — 빌드 배포0workflow — KissFlow0project — 프로젝트0slack588synapse476jira265naver_works184confluence84github0kissflow0{
"name_ko": "김윤지",
"name_en": null,
"department_id": "...",
"department_name": "아트팀",
"position": "팀원",
"level_name": "매니저",
"is_manager": false,
"slack_id": "U02M3U2E0BG",
"profile_image_url": "https://...",
"hired_date": "2021-03-02",
"cell_phone": "010-xxxx-xxxx"
}{
"key": "ER-1234",
"summary": "시즌12 밸런스 조정",
"status_name": "In Progress",
"status_category": "indeterminate",
"priority": "High",
"issue_type": "Task",
"url": "https://nimbleneuron.atlassian.net/browse/ER-1234"
}{
"channel_id": "C04L93F9EG6",
"is_private": false,
"is_archived": false,
"topic": "QA 관련 논의",
"member_count": 45,
"channel_type": "deep_discussion",
"activity_level": "high",
"weekly_human_messages": 93,
"thread_rate": 0.517,
"peak_hour": 14,
"top_keywords": ["시즌", "테스트", "QA"]
}{
"room_name": "씽크룸 3",
"room_id": "62576/219964@r_62576_...",
"summary": "시즌12 킥오프",
"start_at": "2026-04-10T02:00:00Z",
"end_at": "2026-04-10T03:00:00Z",
"attendee_emails": ["a@nn.com", "b@nn.com"],
"event_id": "...",
"source": "naver_works"
}// document (Confluence)
{ "title": "시즌12 기획안", "space_key": "ER", "space_name": "이터널 리턴",
"status": "current", "url": "https://...", "last_updated": "2026-04-10T05:30:00Z" }
// absence
{ "date": "2026-04-10", "type": "연차", "description": "개인 사유",
"slack_message_ts": "1744..." }
// announcement
{ "summary": "시즌12 패치 안내", "original_text": "...",
"user_name": "김지훈", "slack_ts": "1744..." }
// message
{ "channel_id": "C01B6EQ32L8", "channel_name": "deploy-dev",
"text_preview": "빌드 v1.2.3 배포 완료", "thread_ts": null,
"reply_count": 5, "is_thread_reply": false, "slack_ts": "1744..." }
// room
{ "room_id": "62576/219964@r_62576_...", "room_name": "씽크룸 3" }
// department
{ "parent_id": "...", "display_order": 3 }| 컬럼 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
id | UUID | NO | gen_random_uuid() | PK |
link_type | TEXT | NO | 관계 유형 | |
source_entity_id | UUID | NO | 출발 엔티티 | |
target_entity_id | UUID | NO | 도착 엔티티 | |
properties | JSONB | NO | '{}' | 관계 부가 속성 |
confidence | REAL | NO | 1.0 | 1.0=확정, <1.0=AI 추론 |
valid_from | TIMESTAMPTZ | NO | now() | 관계 시작 시점 |
valid_until | TIMESTAMPTZ | YES | NULL = 현재 유효 | |
created_at | TIMESTAMPTZ | NO | now() |
attends — person → meeting3,258belongs_to — person → dept, msg → space1,569assigned_to — issue → person967reported_by — issue → person815organizes — person → meeting761parent_of — dept → dept500relates_to — issue → issue466authored — person → message56mentions — message → person25blocks / manages / reviews / deployed_by / contributed_to / works_on / member_of0| 컬럼 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
id | UUID | NO | gen_random_uuid() | PK |
action | TEXT | NO | 행위 유형 | |
actor_entity_id | UUID | YES | 행위자 | |
actor_email | TEXT | YES | 행위자 이메일 (비정규화) | |
subject_entity_id | UUID | YES | 대상 엔티티 | |
subject_type | TEXT | YES | 대상 entity_type (비정규화) | |
target_entity_id | UUID | YES | 간접 대상 | |
properties | JSONB | NO | '{}' | 이벤트 부가 정보 |
occurred_at | TIMESTAMPTZ | NO | now() | 실제 발생 시각 |
idempotency_key | TEXT | YES | 중복 방지 키 | |
created_at | TIMESTAMPTZ | NO | now() |
status_changed — Jira 이슈 상태 변경324scheduled — 부재/연차 등록263created — Slack 메시지 작성239updated — Confluence 문서 수정99mentioned — Slack 멘션25completed / commented / assigned / merged / deployed / attended / approved / rejected / published / reviewed / cancelled0REFRESH MATERIALIZED VIEW로 갱신.| 컬럼 | 타입 | 설명 |
|---|---|---|
actor_entity_id | UUID | 행위자 |
actor_email | TEXT | 행위자 이메일 |
activity_date | TIMESTAMPTZ | 일자 (KST date_trunc) |
event_count | BIGINT | 총 이벤트 수 |
distinct_actions | BIGINT | 고유 행위 유형 수 |
distinct_subjects | BIGINT | 고유 대상 수 |
actions | TEXT[] | 행위 유형 배열 |
| 컬럼 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
id | TEXT | NO | Slack 채널 ID | |
name | TEXT | NO | 채널명 | |
is_private | BOOLEAN | NO | false | |
is_archived | BOOLEAN | NO | false | |
topic | TEXT | YES | '' | |
purpose | TEXT | YES | '' | |
member_count | INTEGER | YES | 0 | |
last_synced_ts | TEXT | YES | 마지막 동기화 메시지 ts (커서) | |
synced_at | TIMESTAMPTZ | YES | ||
created_at | TIMESTAMPTZ | NO | now() |
| 컬럼 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
channel_id | TEXT | NO | FK → slack_channels | |
ts | TEXT | NO | Slack 메시지 타임스탬프 | |
user_id | TEXT | YES | Slack 유저 ID | |
text | TEXT | NO | '' | 메시지 본문 |
thread_ts | TEXT | YES | 스레드 부모 ts (NULL=최상위) | |
reply_count | INTEGER | NO | 0 | |
subtype | TEXT | YES | 메시지 서브타입 | |
is_bot | BOOLEAN | NO | false | |
reactions | JSONB | YES | '[]' | |
files | JSONB | YES | '[]' | |
edited_at | TIMESTAMPTZ | YES | ||
message_at | TIMESTAMPTZ | NO | 실제 메시지 시각 | |
synced_at | TIMESTAMPTZ | NO | now() |
| 컬럼 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
channel_id | TEXT | NO | PK, FK | |
period_start | TIMESTAMPTZ | NO | 분석 기간 시작 | |
period_end | TIMESTAMPTZ | NO | 분석 기간 종료 | |
total_messages | INTEGER | 0 | 전체 메시지 | |
human_messages | INTEGER | 0 | 사람 메시지 | |
bot_messages | INTEGER | 0 | 봇 메시지 | |
thread_replies | INTEGER | 0 | 스레드 답글 | |
unique_users | INTEGER | 0 | 고유 참여자 | |
thread_rate | REAL | 0 | 스레드 비율 (0~1) | |
msgs_per_user | REAL | 0 | 인당 메시지 | |
channel_type | TEXT | YES | 채널 유형 분류 | |
activity_level | TEXT | YES | 활동 수준 | |
peak_hour | INTEGER | YES | 피크 시간 (0~23 KST) | |
weekend_ratio | REAL | 0 | 주말 메시지 비율 | |
hourly_distribution | JSONB | '{}' | 시간대별 분포 | |
daily_distribution | JSONB | '{}' | 요일별 분포 | |
top_keywords | JSONB | '[]' | 상위 키워드 | |
user_overlap | JSONB | '[]' | 채널 간 사용자 교차 (미구현) | |
computed_at | TIMESTAMPTZ | now() | 계산 시각 |
deep_discussionthread_rate > 0.4broadcastthread_rate < 0.2 & users > 10small_groupunique_users ≤ 3mixed그 외high (6)human_messages ≥ 50medium (13)20 ~ 49low (161)1 ~ 19dormant (1)0| 원본 | 행수 | → entity_type | 동기화 함수 |
|---|---|---|---|
org_members | 133 | person | syncOrgMembers() |
org_departments | 51 | department | syncOrgDepartments() |
room_reservations | 282 | meeting, room | syncMeetings(), syncRooms() |
absent_records | 931 | absence | syncAbsences() |
announcements_cache | 55 | announcement | syncAnnouncements() |
slack_channels | 349 | space | syncSlackChannelsToOntology() |
slack_messages | ~27K | message | syncSlackMessagesToOntology() |
| Jira Cloud API | — | issue | syncJiraIssues() |
| Confluence Cloud API | — | document | syncConfluencePages() |
| Slack build 채널 | — | build | syncBuilds() |
(entity_type, source, external_id) 기준, Event는 idempotency_key 기준, Link는 기존 active soft-delete 후 재생성.