Skip to content

Commit 7064a1e

Browse files
committed
init
1 parent ad90ff3 commit 7064a1e

39 files changed

Lines changed: 4207 additions & 128 deletions

src/backend/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import retrospectiveRouter from './src/routes/retrospective.routes.js';
2525
import partsRouter from './src/routes/parts.routes.js';
2626
import financeRouter from './src/routes/finance.routes.js';
2727
import calendarRouter from './src/routes/calendar.routes.js';
28+
import prospectiveSponsorRouter from './src/routes/prospective-sponsor.routes.js';
2829

2930
const app = express();
3031

@@ -103,6 +104,7 @@ app.use('/retrospective', retrospectiveRouter);
103104
app.use('/parts', partsRouter);
104105
app.use('/finance', financeRouter);
105106
app.use('/calendar', calendarRouter);
107+
app.use('/prospective-sponsors', prospectiveSponsorRouter);
106108
app.use('/', (_req, res) => {
107109
res.status(200).json('Welcome to FinishLine');
108110
});

src/backend/src/controllers/finance.controllers.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ export default class FinanceController {
1212
activeYears,
1313
sponsorTierId,
1414
taxExempt,
15-
sponsorContact,
15+
contactName,
16+
contactEmail,
17+
contactPhone,
18+
contactPosition,
1619
sponsorTasks,
1720
discountCode,
1821
sponsorNotes
@@ -27,11 +30,14 @@ export default class FinanceController {
2730
activeYears,
2831
sponsorTierId,
2932
taxExempt,
30-
sponsorContact,
33+
contactName,
3134
sponsorTasks,
3235
req.organization,
3336
discountCode,
34-
sponsorNotes
37+
sponsorNotes,
38+
contactEmail,
39+
contactPhone,
40+
contactPosition
3541
);
3642
res.status(200).json(sponsor);
3743
} catch (error: unknown) {
@@ -327,7 +333,10 @@ export default class FinanceController {
327333
joinDate,
328334
activeYears,
329335
sponsorTierId,
330-
sponsorContact,
336+
contactName,
337+
contactEmail,
338+
contactPhone,
339+
contactPosition,
331340
taxExempt,
332341
sponsorTasks,
333342
discountCode,
@@ -344,11 +353,14 @@ export default class FinanceController {
344353
joinDate,
345354
activeYears,
346355
sponsorTierId,
347-
sponsorContact,
356+
contactName,
348357
taxExempt,
349358
sponsorTasks,
350359
discountCode,
351-
sponsorNotes
360+
sponsorNotes,
361+
contactEmail,
362+
contactPhone,
363+
contactPosition
352364
);
353365

354366
res.status(200).json(updatedSponsor);
@@ -385,4 +397,18 @@ export default class FinanceController {
385397
next(error);
386398
}
387399
}
400+
401+
static async toggleSponsorTaskDone(req: Request, res: Response, next: NextFunction) {
402+
try {
403+
const { sponsorTaskId } = req.params as Record<string, string>;
404+
const updatedTask = await FinanceServices.toggleSponsorTaskDone(
405+
req.currentUser,
406+
req.organization,
407+
sponsorTaskId
408+
);
409+
res.status(200).json(updatedTask);
410+
} catch (error: unknown) {
411+
next(error);
412+
}
413+
}
388414
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { NextFunction, Request, Response } from 'express';
2+
import ProspectiveSponsorServices from '../services/prospective-sponsor.services.js';
3+
4+
export default class ProspectiveSponsorController {
5+
static async createProspectiveSponsor(req: Request, res: Response, next: NextFunction) {
6+
try {
7+
const {
8+
organizationName,
9+
lastContactDate,
10+
firstContactMethod,
11+
contactName,
12+
contactorUserId,
13+
highlightThresholdDays,
14+
contactEmail,
15+
contactPhone,
16+
contactPosition
17+
} = req.body;
18+
19+
const prospectiveSponsor = await ProspectiveSponsorServices.createProspectiveSponsor(
20+
req.currentUser,
21+
req.organization,
22+
organizationName,
23+
lastContactDate,
24+
firstContactMethod,
25+
contactName,
26+
contactorUserId,
27+
highlightThresholdDays,
28+
contactEmail,
29+
contactPhone,
30+
contactPosition
31+
);
32+
res.status(200).json(prospectiveSponsor);
33+
} catch (error: unknown) {
34+
next(error);
35+
}
36+
}
37+
38+
static async getAllProspectiveSponsors(req: Request, res: Response, next: NextFunction) {
39+
try {
40+
const prospectiveSponsors = await ProspectiveSponsorServices.getAllProspectiveSponsors(req.organization);
41+
res.status(200).json(prospectiveSponsors);
42+
} catch (error: unknown) {
43+
next(error);
44+
}
45+
}
46+
47+
static async editProspectiveSponsor(req: Request, res: Response, next: NextFunction) {
48+
try {
49+
const { prospectiveSponsorId } = req.params as Record<string, string>;
50+
const {
51+
organizationName,
52+
lastContactDate,
53+
status,
54+
firstContactMethod,
55+
contactName,
56+
contactorUserId,
57+
highlightThresholdDays,
58+
contactEmail,
59+
contactPhone,
60+
contactPosition
61+
} = req.body;
62+
63+
const updatedProspectiveSponsor = await ProspectiveSponsorServices.editProspectiveSponsor(
64+
req.currentUser,
65+
req.organization,
66+
prospectiveSponsorId,
67+
organizationName,
68+
lastContactDate,
69+
status,
70+
firstContactMethod,
71+
contactName,
72+
contactorUserId,
73+
highlightThresholdDays,
74+
contactEmail,
75+
contactPhone,
76+
contactPosition
77+
);
78+
res.status(200).json(updatedProspectiveSponsor);
79+
} catch (error: unknown) {
80+
next(error);
81+
}
82+
}
83+
84+
static async deleteProspectiveSponsor(req: Request, res: Response, next: NextFunction) {
85+
try {
86+
const { prospectiveSponsorId } = req.params as Record<string, string>;
87+
const deletedProspectiveSponsor = await ProspectiveSponsorServices.deleteProspectiveSponsor(
88+
prospectiveSponsorId,
89+
req.currentUser,
90+
req.organization
91+
);
92+
res.status(200).json(deletedProspectiveSponsor);
93+
} catch (error: unknown) {
94+
next(error);
95+
}
96+
}
97+
98+
static async getProspectiveSponsorTasks(req: Request, res: Response, next: NextFunction) {
99+
try {
100+
const { prospectiveSponsorId } = req.params as Record<string, string>;
101+
const tasks = await ProspectiveSponsorServices.getProspectiveSponsorTasks(
102+
prospectiveSponsorId,
103+
req.organization.organizationId
104+
);
105+
res.status(200).json(tasks);
106+
} catch (error: unknown) {
107+
next(error);
108+
}
109+
}
110+
111+
static async createProspectiveSponsorTask(req: Request, res: Response, next: NextFunction) {
112+
try {
113+
const { prospectiveSponsorId } = req.params as Record<string, string>;
114+
const { dueDate, notes, notifyDate, assigneeUserId } = req.body;
115+
116+
const task = await ProspectiveSponsorServices.createProspectiveSponsorTask(
117+
req.currentUser,
118+
req.organization,
119+
prospectiveSponsorId,
120+
dueDate,
121+
notes,
122+
notifyDate,
123+
assigneeUserId
124+
);
125+
res.status(200).json(task);
126+
} catch (error: unknown) {
127+
next(error);
128+
}
129+
}
130+
131+
static async acceptProspectiveSponsor(req: Request, res: Response, next: NextFunction) {
132+
try {
133+
const { prospectiveSponsorId } = req.params as Record<string, string>;
134+
const { sponsorTierId, sponsorValue, joinDate, activeYears, taxExempt, discountCode, sponsorNotes } = req.body;
135+
136+
const acceptedProspectiveSponsor = await ProspectiveSponsorServices.acceptProspectiveSponsor(
137+
req.currentUser,
138+
req.organization,
139+
prospectiveSponsorId,
140+
sponsorTierId,
141+
sponsorValue,
142+
joinDate,
143+
activeYears,
144+
taxExempt,
145+
discountCode,
146+
sponsorNotes
147+
);
148+
res.status(200).json(acceptedProspectiveSponsor);
149+
} catch (error: unknown) {
150+
next(error);
151+
}
152+
}
153+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Prisma } from '@prisma/client';
2+
import { getUserQueryArgs } from './user.query-args.js';
3+
import { getSponsorTaskQueryArgs } from './sponsor.query.args.js';
4+
5+
export type ProspectiveSponsorQueryArgs = ReturnType<typeof getProspectiveSponsorQueryArgs>;
6+
7+
export const getProspectiveSponsorQueryArgs = (organizationId: string) =>
8+
Prisma.validator<Prisma.Prospective_SponsorDefaultArgs>()({
9+
include: {
10+
contactor: getUserQueryArgs(organizationId),
11+
tasks: getSponsorTaskQueryArgs(organizationId)
12+
}
13+
});
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `vendorContact` on the `Sponsor` table. All the data in the column will be lost.
5+
- Added the required column `contactName` to the `Sponsor` table without a default value. This is not possible if the table is not empty.
6+
7+
*/
8+
-- CreateEnum
9+
CREATE TYPE "Prospective_Sponsor_Status" AS ENUM ('IN_PROGRESS', 'DECLINED', 'NOT_IN_CONTACT', 'NO_RESPONSE', 'ACCEPTED');
10+
11+
-- CreateEnum
12+
CREATE TYPE "First_Contact_Method" AS ENUM ('INBOUND_FORM', 'INBOUND_EMAIL', 'OUTBOUND_EMAIL', 'OTHER');
13+
14+
-- DropForeignKey
15+
ALTER TABLE "Sponsor_Task" DROP CONSTRAINT "Sponsor_Task_sponsorId_fkey";
16+
17+
-- AlterTable
18+
ALTER TABLE "Sponsor" DROP COLUMN "vendorContact",
19+
ADD COLUMN "contactEmail" TEXT,
20+
ADD COLUMN "contactName" TEXT NOT NULL,
21+
ADD COLUMN "contactPhone" TEXT,
22+
ADD COLUMN "contactPosition" TEXT;
23+
24+
-- AlterTable
25+
ALTER TABLE "Sponsor_Task" ADD COLUMN "done" BOOLEAN NOT NULL DEFAULT false,
26+
ADD COLUMN "prospectiveSponsorId" TEXT,
27+
ALTER COLUMN "sponsorId" DROP NOT NULL;
28+
29+
-- CreateTable
30+
CREATE TABLE "Prospective_Sponsor" (
31+
"prospectiveSponsorId" TEXT NOT NULL,
32+
"organizationId" TEXT NOT NULL,
33+
"organizationName" TEXT NOT NULL,
34+
"dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
35+
"lastContactDate" TIMESTAMP(3) NOT NULL,
36+
"highlightThresholdDays" INTEGER NOT NULL DEFAULT 10,
37+
"status" "Prospective_Sponsor_Status" NOT NULL DEFAULT 'IN_PROGRESS',
38+
"firstContactMethod" "First_Contact_Method" NOT NULL,
39+
"contactorUserId" TEXT NOT NULL,
40+
"contactName" TEXT NOT NULL,
41+
"contactEmail" TEXT,
42+
"contactPhone" TEXT,
43+
"contactPosition" TEXT,
44+
"dateDeleted" TIMESTAMP(3),
45+
46+
CONSTRAINT "Prospective_Sponsor_pkey" PRIMARY KEY ("prospectiveSponsorId")
47+
);
48+
49+
-- CreateIndex
50+
CREATE INDEX "Prospective_Sponsor_organizationId_idx" ON "Prospective_Sponsor"("organizationId");
51+
52+
-- CreateIndex
53+
CREATE INDEX "Prospective_Sponsor_contactorUserId_idx" ON "Prospective_Sponsor"("contactorUserId");
54+
55+
-- CreateIndex
56+
CREATE UNIQUE INDEX "Prospective_Sponsor_organizationName_organizationId_key" ON "Prospective_Sponsor"("organizationName", "organizationId");
57+
58+
-- CreateIndex
59+
CREATE INDEX "Sponsor_Task_prospectiveSponsorId_idx" ON "Sponsor_Task"("prospectiveSponsorId");
60+
61+
-- AddForeignKey
62+
ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_sponsorId_fkey" FOREIGN KEY ("sponsorId") REFERENCES "Sponsor"("sponsorId") ON DELETE SET NULL ON UPDATE CASCADE;
63+
64+
-- AddForeignKey
65+
ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_prospectiveSponsorId_fkey" FOREIGN KEY ("prospectiveSponsorId") REFERENCES "Prospective_Sponsor"("prospectiveSponsorId") ON DELETE SET NULL ON UPDATE CASCADE;
66+
67+
-- AddForeignKey
68+
ALTER TABLE "Prospective_Sponsor" ADD CONSTRAINT "Prospective_Sponsor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE;
69+
70+
-- AddForeignKey
71+
ALTER TABLE "Prospective_Sponsor" ADD CONSTRAINT "Prospective_Sponsor_contactorUserId_fkey" FOREIGN KEY ("contactorUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;

0 commit comments

Comments
 (0)