-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschema.sql
More file actions
174 lines (156 loc) · 7.64 KB
/
Copy pathschema.sql
File metadata and controls
174 lines (156 loc) · 7.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
-- =====================================================================
-- The Fin AI Community — Phase 1 schema (Supabase / PostgreSQL)
-- Audience: researchers. Focus: member system + projects + collaboration matching.
-- Principles: invite-only; nothing about identity is hard-coded —
-- Position (community-level) and Role (project-level) are data, not enums;
-- permissions derive from capabilities mapped onto positions.
-- =====================================================================
-- ---------- MEMBERS (decoupled from auth so people can be imported pre-login) ----------
-- A member row can exist before the person ever logs in (status='invited',
-- auth_user_id null). When they accept an invite and authenticate, their
-- Supabase auth user binds to the existing row (matched by email).
create table member (
id uuid primary key default gen_random_uuid(),
auth_user_id uuid unique references auth.users (id) on delete set null,
full_name text not null,
email text unique not null,
affiliation text,
avatar_url text,
bio text,
links jsonb not null default '{}', -- {scholar, hf, github, homepage}
availability text not null default 'looking', -- 'looking' | 'limited' | 'full'
status text not null default 'invited', -- 'invited' (imported, not yet logged in) | 'active'
created_at timestamptz not null default now()
);
-- ---------- COMMUNITY POSITION (configurable, NOT an enum) ----------
create table position (
id uuid primary key default gen_random_uuid(),
name text unique not null, -- President, Board, Steering, Executive Chair, Executive, Researcher
rank int not null default 100,
description text
);
create table member_position (
member_id uuid references member (id) on delete cascade,
position_id uuid references position (id) on delete cascade,
started_on date,
ended_on date,
primary key (member_id, position_id)
);
-- ---------- PERMISSIONS (derive from data, not code) ----------
create table capability (
key text primary key, -- invite_members, manage_members, manage_taxonomy, edit_any_project
description text
);
create table position_capability (
position_id uuid references position (id) on delete cascade,
capability_key text references capability (key) on delete cascade,
primary key (position_id, capability_key)
);
-- ---------- PROJECT LOOKUPS (configurable) ----------
create table project_type ( -- Dataset & Benchmark, Model, Agent, Application, Trustworthy
id uuid primary key default gen_random_uuid(),
name text unique not null,
rank int not null default 100
);
create table project_status ( -- Proposal, Data Collecting, Work in progress, Under review, Finished, Hold
id uuid primary key default gen_random_uuid(),
name text unique not null,
rank int not null default 100,
is_active boolean not null default true -- Hold/Finished can be flagged inactive
);
-- ---------- PROJECTS ----------
create table project (
id uuid primary key default gen_random_uuid(),
name text not null,
type_id uuid references project_type (id),
status_id uuid references project_status (id),
target_venue text, -- NeurIPS, EMNLP, ACL, COLM, IPM, ...
deadline date,
summary text,
links jsonb not null default '{}', -- {openreview, hf, repo, paper}
created_at timestamptz not null default now()
);
-- ---------- PROJECT ROLE (per-project, configurable) ----------
create table project_role (
id uuid primary key default gen_random_uuid(),
name text unique not null, -- Leader, Co-lead, Contributor, Annotator, Financial Expert, Advisor
can_manage boolean not null default false -- Leader/Co-lead => edit this project, post needs, accept applications
);
create table project_member (
project_id uuid references project (id) on delete cascade,
member_id uuid references member (id) on delete cascade,
project_role_id uuid references project_role (id),
joined_at timestamptz not null default now(),
primary key (project_id, member_id, project_role_id)
);
-- ---------- SKILL TREE + 4-LEVEL RATING ----------
create type skill_level as enum ('Beginner', 'Intermediate', 'Advanced', 'Expert');
create table skill (
id uuid primary key default gen_random_uuid(),
parent_id uuid references skill (id) on delete cascade, -- self-referencing tree
name text not null,
unique (parent_id, name)
);
-- self-assessed level
create table member_skill (
member_id uuid references member (id) on delete cascade,
skill_id uuid references skill (id) on delete cascade,
self_level skill_level not null,
primary key (member_id, skill_id)
);
-- endorsements from collaborators add credibility to a self-rated skill
create table skill_endorsement (
id uuid primary key default gen_random_uuid(),
member_id uuid references member (id) on delete cascade, -- who is endorsed
skill_id uuid references skill (id) on delete cascade,
endorser_id uuid references member (id) on delete cascade, -- who endorses
level skill_level, -- optional: level the endorser attests to
note text,
created_at timestamptz not null default now(),
unique (member_id, skill_id, endorser_id),
check (member_id <> endorser_id)
);
-- ---------- COLLABORATION MATCHING ----------
create table open_need (
id uuid primary key default gen_random_uuid(),
project_id uuid references project (id) on delete cascade,
project_role_id uuid references project_role (id), -- the role being recruited
skill_id uuid references skill (id), -- optional required skill
min_level skill_level, -- optional minimum level
headcount int not null default 1,
description text,
status text not null default 'open', -- open | filled | closed
created_at timestamptz not null default now()
);
create table need_application (
id uuid primary key default gen_random_uuid(),
open_need_id uuid references open_need (id) on delete cascade,
member_id uuid references member (id) on delete cascade,
message text,
status text not null default 'pending', -- pending | accepted | declined
created_at timestamptz not null default now(),
unique (open_need_id, member_id)
);
-- ---------- INVITES (invite-only registration) ----------
create table invite (
id uuid primary key default gen_random_uuid(),
email text not null,
invited_by uuid references member (id),
token text unique not null,
position_id uuid references position (id), -- optional pre-assigned community position
accepted_at timestamptz,
created_at timestamptz not null default now()
);
-- =====================================================================
-- NOTES
-- * Enable Row-Level Security on every table, then derive policies:
-- - read: any authenticated member;
-- - edit project: project_member with a can_manage role, OR a position
-- holding the 'edit_any_project' capability;
-- - invite/manage: positions holding 'invite_members'/'manage_members'.
-- * Recommended helper: a SQL function has_capability(key) that resolves
-- auth.uid() -> member.auth_user_id -> member_position -> position_capability,
-- used inside RLS policies. (See policies.sql.)
-- * Status/type kept as lookup tables (not enums) to stay configurable,
-- matching the "nothing hard-coded" principle for identity.
-- =====================================================================