Files
ai-dev-portal/schema.sql
2620227 6c2bb888b4 feat: 프로필 사진 업로드·프로필 페이지 + 모달/이름 개선
- 프로필 페이지 /u/:sabun 신설 (본인=비공개 포함, 타인=공개만).
  헤더 "내 프로필", 카드·모달·댓글 작성자 클릭 시 프로필로 이동.
- 프로필 사진 업로드: users.avatar(bytea) 저장, GET /avatar/:sabun
  (업로드본 없으면 identicon SVG 폴백), POST /profile/avatar(express.raw).
  브라우저 canvas 크롭(256px webp) — 서버 이미지 라이브러리/멀터 불필요.
  identicon 6개 렌더 지점을 avatar() 헬퍼로 통일.
- 상세 모달 폭 640→760px, 소유자 액션(비공개 전환·삭제)을 우측 그룹으로
  묶어 한 줄 정렬.
- 표시 이름을 한국식 성+이름(family_name+given_name)으로 교정.
- .project-env.example ADMIN_ROLE→ADMIN_GROUP 정리.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:45:47 +09:00

63 lines
3.1 KiB
SQL

-- AI DEV portal 스키마 (search_path=portal). 멱등.
-- 직원 식별자는 사번(Keycloak preferred_username). 표시 이름은 name.
CREATE TABLE IF NOT EXISTS users (
sabun text PRIMARY KEY, -- 사번 (Keycloak preferred_username)
name text NOT NULL,
email text,
avatar_seed text, -- 아바타 색/이니셜용(미업로드 시 identicon 시드)
created_at timestamptz NOT NULL DEFAULT now(),
last_login timestamptz
);
-- 업로드한 프로필 사진(1:1 크롭·256px webp 등, 브라우저에서 축소). 없으면 identicon 폴백.
ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar bytea;
ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar_mime text;
ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar_updated_at timestamptz;
-- 공유 프로젝트 (직원이 만든 앱/repo 를 포털에 공유)
CREATE TABLE IF NOT EXISTS projects (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
owner_sabun text NOT NULL REFERENCES users(sabun),
title text NOT NULL,
description text DEFAULT '',
repo_url text DEFAULT '', -- Gitea repo
app_url text DEFAULT '', -- 배포된 앱 (*.apps.bokdev.in)
tags text DEFAULT '', -- 콤마 구분
is_public boolean NOT NULL DEFAULT true, -- 공개(피드 노출) / 비공개(나만)
lang text DEFAULT '', -- 대표 언어(태그에서 추론, 카드 언어 점)
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
-- 기존 배포 DB 대비 멱등 컬럼 추가
ALTER TABLE projects ADD COLUMN IF NOT EXISTS is_public boolean NOT NULL DEFAULT true;
ALTER TABLE projects ADD COLUMN IF NOT EXISTS lang text DEFAULT '';
CREATE INDEX IF NOT EXISTS idx_projects_created ON projects(created_at DESC);
-- 코멘트 (parent_id 가 null 이면 최상위, 있으면 대댓글 — 1뎁스만 허용: 앱에서 검증)
CREATE TABLE IF NOT EXISTS comments (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
project_id bigint NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
author_sabun text NOT NULL REFERENCES users(sabun),
parent_id bigint REFERENCES comments(id) ON DELETE CASCADE,
body text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
ALTER TABLE comments ADD COLUMN IF NOT EXISTS parent_id bigint REFERENCES comments(id) ON DELETE CASCADE;
CREATE INDEX IF NOT EXISTS idx_comments_project ON comments(project_id, created_at);
-- 좋아요(❤️) — 1인 1좋아요
CREATE TABLE IF NOT EXISTS hearts (
project_id bigint NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
sabun text NOT NULL REFERENCES users(sabun),
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (project_id, sabun)
);
-- 즐겨찾기(⭐ Star) — 1인 1즐겨찾기
CREATE TABLE IF NOT EXISTS stars (
project_id bigint NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
sabun text NOT NULL REFERENCES users(sabun),
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (project_id, sabun)
);