Files
dbx-main/scripts/sql/project_db_002_attachments_notifications.sql
T
king 776f655db4 feat(project): 댓글·첨부·단계편집·알림센터 + 라이브러리 self-host
아사나식 기능 4종 추가:
- 댓글: 업무 모달에서 등록/삭제, 관련자 인앱 알림(task_comments)
- 첨부: 업로드(20MB)/다운로드/삭제, 파일은 DATA_DIR/project/<task_id>/,
  DB엔 메타만(task_attachments)
- 단계 편집: 보드 칸반에서 이름변경/완료토글/순서이동/삭제/추가
- 알림센터(인앱): 배정·완료·댓글 시 수신자별 알림, 벨 미읽음 배지,
  /project/inbox 페이지, 읽음/모두읽음(project_notifications)

라이브러리 self-host: vis-timeline + Material Symbols 를 static/vendor/ 로
내려받아 CDN 의존 제거.

DB: scripts/sql/project_db_002_attachments_notifications.sql (서버서 적용 필요).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 12:32:00 +09:00

58 lines
3.6 KiB
SQL

-- =====================================================================
-- project_db 마이그레이션 002 — 첨부파일 + 알림센터
-- =====================================================================
-- 멱등(idempotent). DROP/TRUNCATE 없음.
--
-- 실행:
-- docker exec -i postgres-db psql -U postgres -d project_db \
-- < scripts/sql/project_db_002_attachments_notifications.sql
--
-- (task_comments 는 init 스크립트에 이미 있음 — 여기서 다루지 않음)
-- =====================================================================
\set ON_ERROR_STOP on
\connect project_db
-- ════════════════════════════════════════════════════════════
-- 업무 첨부파일 — 실제 파일은 DATA_DIR/project/<task_id>/ 에 저장.
-- 여기엔 메타데이터만(원본명/저장명/크기/타입/업로더).
-- ════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS task_attachments (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
filename TEXT NOT NULL, -- 사용자에게 보일 원본 파일명
stored_name TEXT NOT NULL, -- 디스크 저장명(UUID.ext)
content_type TEXT NOT NULL DEFAULT '',
size_bytes BIGINT NOT NULL DEFAULT 0,
uploaded_by TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_task_attachments_task ON task_attachments (task_id, created_at);
-- ════════════════════════════════════════════════════════════
-- 알림센터 — 사용자별 인앱 알림(아사나 Inbox).
-- 업무 배정/완료/댓글/단계변경 시 관련자에게 1행씩 생성.
-- ════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS project_notifications (
id BIGSERIAL PRIMARY KEY,
recipient_email TEXT NOT NULL,
actor_email TEXT NOT NULL DEFAULT '',
project_id BIGINT REFERENCES projects(id) ON DELETE CASCADE,
task_id BIGINT REFERENCES tasks(id) ON DELETE CASCADE,
type TEXT NOT NULL, -- assigned | completed | comment | stage_changed
title TEXT NOT NULL DEFAULT '',
body TEXT NOT NULL DEFAULT '',
is_read BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_project_notif_recipient
ON project_notifications (recipient_email, is_read, created_at DESC);
-- ════════════════════════════════════════════════════════════
-- 권한 (project_app: CRUD only)
-- ════════════════════════════════════════════════════════════
GRANT SELECT, INSERT, UPDATE, DELETE ON task_attachments, project_notifications TO project_app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO project_app;
SELECT 'project_db 002 ready' AS status;