-- 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, -- 아바타 색/이니셜용 created_at timestamptz NOT NULL DEFAULT now(), last_login 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 '', -- 콤마 구분 created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_projects_created ON projects(created_at DESC); -- 코멘트 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), body text NOT NULL, created_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_comments_project ON comments(project_id, created_at); -- 스타(좋아요) 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) );