Skip to content

Commit 50f844f

Browse files
[INTS25] user admin role models (#53)
* dummy commit * Create/update schemas for admin, position, user * Add types for department/position * Create migration file * Make linter happy * dummy commit * Create/update schemas for admin, position, user * Add types for department/position * Create migration file * Make linter happy * Linter? * fix lint --------- Co-authored-by: mxc-maggiechen <mxc.maggiechen@gmail.com>
1 parent 9b83478 commit 50f844f

File tree

5 files changed

+181
-2
lines changed

5 files changed

+181
-2
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { DataType } from "sequelize-typescript";
2+
3+
import { Migration } from "../umzug";
4+
import {
5+
CommunityPositionTitles,
6+
Department,
7+
DesignPositionTitles,
8+
EngineeringPositionTitles,
9+
PositionTitles,
10+
ProductPositionTitles,
11+
} from "../types";
12+
13+
const ADMIN_TABLE_NAME = "admins";
14+
const POSITION_TABLE_NAME = "positions";
15+
const USER_TABLE_NAME = "users";
16+
17+
const ADMIN_SEEDED_DATA = [
18+
{
19+
userId: "1",
20+
authorizedDepartments: [Department.Engineering, Department.Product],
21+
},
22+
{
23+
userId: "2",
24+
authorizedDepartments: [Department.Design, Department.Community],
25+
},
26+
];
27+
const POSITION_SEEDED_DATA = [
28+
...EngineeringPositionTitles.map((title) => ({
29+
title,
30+
department: Department.Engineering,
31+
})),
32+
...DesignPositionTitles.map((title) => ({
33+
title,
34+
department: Department.Design,
35+
})),
36+
...ProductPositionTitles.map((title) => ({
37+
title,
38+
department: Department.Product,
39+
})),
40+
...CommunityPositionTitles.map((title) => ({
41+
title,
42+
department: Department.Community,
43+
})),
44+
];
45+
46+
export const up: Migration = async ({ context: sequelize }) => {
47+
await sequelize.getQueryInterface().createTable(POSITION_TABLE_NAME, {
48+
title: {
49+
type: DataType.ENUM(...PositionTitles),
50+
allowNull: false,
51+
primaryKey: true,
52+
},
53+
department: {
54+
type: DataType.ENUM(...Object.values(Department)),
55+
allowNull: false,
56+
},
57+
});
58+
await sequelize
59+
.getQueryInterface()
60+
.bulkInsert(POSITION_TABLE_NAME, POSITION_SEEDED_DATA);
61+
62+
await sequelize.getQueryInterface().addColumn(USER_TABLE_NAME, "position", {
63+
type: "enum_positions_title",
64+
references: {
65+
model: POSITION_TABLE_NAME,
66+
key: "title",
67+
},
68+
});
69+
70+
await sequelize.getQueryInterface().createTable(ADMIN_TABLE_NAME, {
71+
userId: {
72+
type: DataType.INTEGER,
73+
allowNull: false,
74+
primaryKey: true,
75+
references: {
76+
model: USER_TABLE_NAME,
77+
key: "id",
78+
},
79+
},
80+
authorizedDepartments: {
81+
type: DataType.ARRAY(DataType.STRING),
82+
allowNull: false,
83+
},
84+
});
85+
await sequelize
86+
.getQueryInterface()
87+
.bulkInsert(ADMIN_TABLE_NAME, ADMIN_SEEDED_DATA);
88+
};
89+
90+
export const down: Migration = async ({ context: sequelize }) => {
91+
await sequelize.getQueryInterface().removeColumn(USER_TABLE_NAME, "position");
92+
await sequelize.getQueryInterface().dropTable(ADMIN_TABLE_NAME);
93+
await sequelize.getQueryInterface().dropTable(POSITION_TABLE_NAME);
94+
await sequelize.query('DROP TYPE IF EXISTS "enum_positions_title";');
95+
await sequelize.query('DROP TYPE IF EXISTS "enum_positions_department";');
96+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
Column,
3+
DataType,
4+
ForeignKey,
5+
Model,
6+
Table,
7+
} from "sequelize-typescript";
8+
import User from "./user.model";
9+
import { Department } from "../types";
10+
11+
@Table({ tableName: "admins" })
12+
export default class Admin extends Model {
13+
@ForeignKey(() => User)
14+
@Column({ type: DataType.INTEGER, primaryKey: true })
15+
userId!: number;
16+
17+
@Column({ type: DataType.ARRAY(DataType.ENUM(...Object.values(Department))) })
18+
authorizedDepartments!: Department[];
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Column, DataType, Model, Table } from "sequelize-typescript";
2+
import { Department, PositionTitle, PositionTitles } from "../types";
3+
4+
@Table({ tableName: "positions" })
5+
export default class Position extends Model {
6+
@Column({ type: DataType.ENUM(...PositionTitles), primaryKey: true })
7+
title!: PositionTitle;
8+
9+
@Column({ type: DataType.ENUM(...Object.values(Department)) })
10+
department!: Department;
11+
}

backend/typescript/models/user.model.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
/* eslint import/no-cycle: 0 */
22

3-
import { Column, DataType, HasMany, Model, Table } from "sequelize-typescript";
4-
import { Role } from "../types";
3+
import {
4+
Column,
5+
DataType,
6+
ForeignKey,
7+
HasMany,
8+
Model,
9+
Table,
10+
} from "sequelize-typescript";
11+
import { PositionTitle, PositionTitles, Role } from "../types";
512
import ApplicationDashboardTable from "./applicationDashboard.model";
13+
import Position from "./position.model";
614

715
@Table({ tableName: "users" })
816
export default class User extends Model {
@@ -24,6 +32,10 @@ export default class User extends Model {
2432
@Column({ type: DataType.ENUM("User", "Admin") })
2533
role!: Role;
2634

35+
@ForeignKey(() => Position)
36+
@Column({ type: DataType.ENUM(...Object.values(PositionTitles)) })
37+
position?: PositionTitle;
38+
2739
@HasMany(() => ApplicationDashboardTable)
2840
applicationDashboards?: ApplicationDashboardTable[];
2941
}

backend/typescript/types.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,44 @@ export enum ApplicantRole {
125125
uxr = "user researcher", // design tab
126126
dev = "project developer", // eng tab
127127
}
128+
129+
export enum Department {
130+
Engineering = "Engineering",
131+
Design = "Design",
132+
Product = "Product",
133+
Community = "Community",
134+
}
135+
136+
export const EngineeringPositionTitles = [
137+
"Project Lead",
138+
"Developer",
139+
"VP Engineering",
140+
] as const;
141+
export const DesignPositionTitles = ["Designer", "VP Design"] as const;
142+
export const ProductPositionTitles = ["Product Manager", "VP Product"] as const;
143+
export const CommunityPositionTitles = [
144+
"President",
145+
"VP Scoping",
146+
"VP Talent",
147+
"VP Finance",
148+
"Director Lead",
149+
"Internal Director",
150+
"External Director",
151+
"Content Strategist",
152+
"Graphic Designer",
153+
] as const;
154+
155+
export const PositionTitles = [
156+
...EngineeringPositionTitles,
157+
...DesignPositionTitles,
158+
...ProductPositionTitles,
159+
...CommunityPositionTitles,
160+
] as const;
161+
162+
// Union types
163+
export type EngineeringPositionTitle =
164+
(typeof EngineeringPositionTitles)[number];
165+
export type DesignPositionTitle = (typeof DesignPositionTitles)[number];
166+
export type ProductPositionTitle = (typeof ProductPositionTitles)[number];
167+
export type CommunityPositionTitle = (typeof CommunityPositionTitles)[number];
168+
export type PositionTitle = (typeof PositionTitles)[number];

0 commit comments

Comments
 (0)