Skip to content

Commit b295edd

Browse files
authored
Merge pull request #622 from nancysangani/feat/workspace-permissions-schema
feat(db): workspace and permissions schema
2 parents 0592283 + 39af6f9 commit b295edd

3 files changed

Lines changed: 497 additions & 6 deletions

File tree

backend/app/database.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,85 @@ def _migrate_schema():
230230
)
231231

232232

233+
# ── Workspace tables ──────────────────────────────────────────────────
234+
existing_tables = set(inspector.get_table_names())
235+
236+
if "workspaces" not in existing_tables:
237+
try:
238+
with engine.begin() as conn:
239+
conn.execute(text("""
240+
CREATE TABLE workspaces (
241+
id CHAR(36) PRIMARY KEY,
242+
name VARCHAR(255) NOT NULL,
243+
created_by CHAR(36) NOT NULL REFERENCES users(id),
244+
created_at TIMESTAMP
245+
)
246+
"""))
247+
conn.execute(text(
248+
"CREATE INDEX IF NOT EXISTS ix_workspaces_created_by "
249+
"ON workspaces (created_by)"
250+
))
251+
logger.info("Migration: created table workspaces")
252+
except Exception:
253+
logger.warning("Migration skipped (may already exist): workspaces")
254+
255+
if "workspace_members" not in existing_tables:
256+
try:
257+
with engine.begin() as conn:
258+
conn.execute(text("""
259+
CREATE TABLE workspace_members (
260+
id CHAR(36) PRIMARY KEY,
261+
workspace_id CHAR(36) NOT NULL REFERENCES workspaces(id),
262+
user_id CHAR(36) NOT NULL REFERENCES users(id),
263+
role VARCHAR(20) NOT NULL DEFAULT 'viewer',
264+
joined_at TIMESTAMP,
265+
CONSTRAINT uq_workspace_member UNIQUE (workspace_id, user_id)
266+
)
267+
"""))
268+
conn.execute(text(
269+
"CREATE INDEX IF NOT EXISTS ix_workspace_members_workspace_id "
270+
"ON workspace_members (workspace_id)"
271+
))
272+
conn.execute(text(
273+
"CREATE INDEX IF NOT EXISTS ix_workspace_members_user_id "
274+
"ON workspace_members (user_id)"
275+
))
276+
logger.info("Migration: created table workspace_members")
277+
except Exception:
278+
logger.warning("Migration skipped (may already exist): workspace_members")
279+
280+
if "workspace_invitations" not in existing_tables:
281+
try:
282+
with engine.begin() as conn:
283+
conn.execute(text("""
284+
CREATE TABLE workspace_invitations (
285+
id CHAR(36) PRIMARY KEY,
286+
email VARCHAR(120) NOT NULL,
287+
token_hash VARCHAR(255) NOT NULL UNIQUE,
288+
inviter_id CHAR(36) NOT NULL REFERENCES users(id),
289+
workspace_name VARCHAR(255) NOT NULL,
290+
created_at TIMESTAMP,
291+
expires_at TIMESTAMP NOT NULL,
292+
accepted_at TIMESTAMP
293+
)
294+
"""))
295+
conn.execute(text(
296+
"CREATE INDEX IF NOT EXISTS ix_workspace_invitations_email "
297+
"ON workspace_invitations (email)"
298+
))
299+
conn.execute(text(
300+
"CREATE INDEX IF NOT EXISTS ix_workspace_invitations_token_hash "
301+
"ON workspace_invitations (token_hash)"
302+
))
303+
conn.execute(text(
304+
"CREATE INDEX IF NOT EXISTS ix_workspace_invitations_inviter_id "
305+
"ON workspace_invitations (inviter_id)"
306+
))
307+
logger.info("Migration: created table workspace_invitations")
308+
except Exception:
309+
logger.warning("Migration skipped (may already exist): workspace_invitations")
310+
311+
233312
def advisory_lock(lock_id: int):
234313
"""Context manager that acquires a PostgreSQL advisory lock (xact scope).
235314

0 commit comments

Comments
 (0)