feat(coord): DB migration — project-scoped missions, multi-tenant RBAC (#149)
Some checks failed
ci/woodpecker/push/ci Pipeline failed
Some checks failed
ci/woodpecker/push/ci Pipeline failed
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #149.
This commit is contained in:
@@ -25,6 +25,9 @@ export const users = pgTable('users', {
|
||||
emailVerified: boolean('email_verified').notNull().default(false),
|
||||
image: text('image'),
|
||||
role: text('role').notNull().default('member'),
|
||||
banned: boolean('banned').default(false),
|
||||
banReason: text('ban_reason'),
|
||||
banExpires: timestamp('ban_expires', { withTimezone: true }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
@@ -95,11 +98,18 @@ export const missions = pgTable(
|
||||
.notNull()
|
||||
.default('planning'),
|
||||
projectId: uuid('project_id').references(() => projects.id, { onDelete: 'set null' }),
|
||||
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
||||
phase: text('phase'),
|
||||
milestones: jsonb('milestones').$type<Record<string, unknown>[]>(),
|
||||
config: jsonb('config'),
|
||||
metadata: jsonb('metadata'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
},
|
||||
(t) => [index('missions_project_id_idx').on(t.projectId)],
|
||||
(t) => [
|
||||
index('missions_project_id_idx').on(t.projectId),
|
||||
index('missions_user_id_idx').on(t.userId),
|
||||
],
|
||||
);
|
||||
|
||||
export const tasks = pgTable(
|
||||
@@ -132,6 +142,40 @@ export const tasks = pgTable(
|
||||
],
|
||||
);
|
||||
|
||||
// ─── Coord Mission Tasks ─────────────────────────────────────────────────────
|
||||
// Join table tracking coord-managed tasks within a mission.
|
||||
// Scoped to userId for multi-tenant RBAC isolation.
|
||||
|
||||
export const missionTasks = pgTable(
|
||||
'mission_tasks',
|
||||
{
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
missionId: uuid('mission_id')
|
||||
.notNull()
|
||||
.references(() => missions.id, { onDelete: 'cascade' }),
|
||||
taskId: uuid('task_id').references(() => tasks.id, { onDelete: 'set null' }),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
status: text('status', {
|
||||
enum: ['not-started', 'in-progress', 'blocked', 'done', 'cancelled'],
|
||||
})
|
||||
.notNull()
|
||||
.default('not-started'),
|
||||
description: text('description'),
|
||||
notes: text('notes'),
|
||||
pr: text('pr'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
},
|
||||
(t) => [
|
||||
index('mission_tasks_mission_id_idx').on(t.missionId),
|
||||
index('mission_tasks_task_id_idx').on(t.taskId),
|
||||
index('mission_tasks_user_id_idx').on(t.userId),
|
||||
index('mission_tasks_status_idx').on(t.status),
|
||||
],
|
||||
);
|
||||
|
||||
export const events = pgTable(
|
||||
'events',
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user