Skip to content

Commit e7204e5

Browse files
committed
Merge branch 'main' of https://github.com/HackGT/api
2 parents 96bde78 + c3521d9 commit e7204e5

6 files changed

Lines changed: 479 additions & 1 deletion

File tree

‎common/src/types.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,11 @@ export type AutoPopulatedDoc<PopulatedType> = PopulatedType & { _id: mongoose.Re
8989
* All the types of actions that can be performed on the system. Used for @casl/ability
9090
* for managing permissions.
9191
*/
92-
export type AbilityAction = "read" | "create" | "update" | "delete" | "manage" | "aggregate";
92+
export type AbilityAction =
93+
| "read"
94+
| "create"
95+
| "update"
96+
| "delete"
97+
| "manage"
98+
| "aggregate"
99+
| "refer";

‎services/registration/src/common/util.ts‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,73 @@ export const validateApplicationData = async (data: any, branchId: any, branchFo
4040
throw new BadRequestError(JSON.stringify(validate.errors, null, 4));
4141
};
4242

43+
const referralJsonSchema = {
44+
type: "object",
45+
required: [
46+
"firstName",
47+
"lastName",
48+
"email",
49+
"school",
50+
"referForReimbursement",
51+
"referForEarlyApplication",
52+
"resume",
53+
"essay",
54+
],
55+
properties: {
56+
firstName: {
57+
type: "string",
58+
minLength: 1,
59+
},
60+
lastName: {
61+
type: "string",
62+
minLength: 1,
63+
},
64+
email: {
65+
type: "string",
66+
format: "email",
67+
},
68+
phoneNumber: {
69+
type: "string",
70+
},
71+
school: {
72+
type: "string",
73+
minLength: 1,
74+
},
75+
schoolYear: {
76+
type: "string",
77+
},
78+
referForReimbursement: {
79+
type: "boolean",
80+
},
81+
referForEarlyApplication: {
82+
type: "boolean",
83+
},
84+
resume: {
85+
type: "object",
86+
required: ["name"],
87+
properties: {
88+
name: {
89+
type: "string",
90+
minLength: 1,
91+
},
92+
},
93+
},
94+
essay: {
95+
type: "string",
96+
minLength: 10,
97+
},
98+
},
99+
};
100+
101+
export const validateReferralData = async (data: any) => {
102+
const validate = ajv.compile(referralJsonSchema);
103+
const valid = validate(data);
104+
if (valid || validate.errors?.length === 0) {
105+
return;
106+
}
107+
throw new BadRequestError(JSON.stringify(validate.errors, null, 4));
108+
};
109+
43110
/**
44111
* Gets the correct branch (application or confirmation) based on the request body
45112
* @param existingApplication the existing application
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { AccessibleRecordModel, accessibleRecordsPlugin } from "@casl/mongoose";
2+
import mongoose, { model, Schema, Types } from "mongoose";
3+
4+
export enum ReferralStatusType {
5+
DRAFT = "DRAFT",
6+
SUBMITTED = "SUBMITTED",
7+
}
8+
9+
export interface Referral extends mongoose.Document {
10+
referrerId: string;
11+
referrerName: string;
12+
referrerEmail: string;
13+
hexathon: Types.ObjectId;
14+
referralData: {
15+
firstName?: string;
16+
lastName?: string;
17+
email?: string;
18+
phoneNumber?: string;
19+
school?: string;
20+
schoolYear?: string;
21+
referForReimbursement?: boolean;
22+
referForEarlyApplication?: boolean;
23+
resume?: Types.ObjectId;
24+
essay?: string;
25+
};
26+
referralStartTime: Date;
27+
referralSubmitTime?: Date;
28+
status: ReferralStatusType;
29+
createdAt: Date;
30+
updatedAt: Date;
31+
}
32+
33+
const referralSchema = new Schema<Referral>(
34+
{
35+
referrerId: {
36+
type: String,
37+
required: true,
38+
index: true,
39+
},
40+
referrerName: {
41+
type: String,
42+
required: true,
43+
index: true,
44+
},
45+
referrerEmail: {
46+
type: String,
47+
required: true,
48+
index: true,
49+
},
50+
hexathon: {
51+
type: Schema.Types.ObjectId,
52+
required: true,
53+
index: true,
54+
},
55+
referralData: {
56+
firstName: {
57+
type: String,
58+
},
59+
lastName: {
60+
type: String,
61+
},
62+
email: {
63+
type: String,
64+
},
65+
phoneNumber: {
66+
type: String,
67+
},
68+
school: {
69+
type: String,
70+
},
71+
schoolYear: {
72+
type: String,
73+
},
74+
referForReimbursement: {
75+
type: Boolean,
76+
},
77+
referForEarlyApplication: {
78+
type: Boolean,
79+
},
80+
resume: {
81+
type: Schema.Types.ObjectId,
82+
},
83+
essay: {
84+
type: String,
85+
},
86+
},
87+
referralStartTime: {
88+
type: Date,
89+
required: true,
90+
},
91+
referralSubmitTime: {
92+
type: Date,
93+
},
94+
status: {
95+
type: String,
96+
required: true,
97+
default: ReferralStatusType.DRAFT,
98+
enum: ReferralStatusType,
99+
index: true,
100+
},
101+
},
102+
{
103+
timestamps: true,
104+
}
105+
);
106+
107+
referralSchema.plugin(accessibleRecordsPlugin);
108+
109+
export const ReferralModel = model<Referral, AccessibleRecordModel<Referral>>(
110+
"Referral",
111+
referralSchema
112+
);

‎services/registration/src/permission.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const addAbilities = (): RequestHandler => (req, res, next) => {
1515
can("manage", "Branch");
1616
can("manage", "Grader");
1717
can("manage", "Review");
18+
can("manage", "Referral");
1819
}
1920

2021
if (req.user.roles.member) {
@@ -23,6 +24,9 @@ export const addAbilities = (): RequestHandler => (req, res, next) => {
2324
can("read", "Review");
2425
can("manage", "Review", { reviewerId: req.user.uid });
2526
can("manage", "Email");
27+
can("read", "Referral");
28+
can("create", "Referral");
29+
can("update", "Referral", { referrerId: req.user.uid });
2630
}
2731

2832
if (req.user.roles.admin || req.user.roles.member) {

‎services/registration/src/routes/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { applicationRouter } from "./application";
44
import { branchRouter } from "./branch";
55
import { emailRouter } from "./email";
66
import { gradingRouter } from "./grading";
7+
import { referralRouter } from "./referrals";
78
import { statisticsRouter } from "./statistics";
89

910
export const defaultRouter = express.Router();
@@ -13,3 +14,4 @@ defaultRouter.use("/applications", applicationRouter);
1314
defaultRouter.use("/statistics", statisticsRouter);
1415
defaultRouter.use("/grading", gradingRouter);
1516
defaultRouter.use("/email", emailRouter);
17+
defaultRouter.use("/referrals", referralRouter);

0 commit comments

Comments
 (0)