Skip to content

Commit aa5270c

Browse files
committed
prospective sponsors finishing up
1 parent 7064a1e commit aa5270c

37 files changed

Lines changed: 1607 additions & 1091 deletions

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default class FinanceController {
77
const {
88
name,
99
activeStatus,
10+
valueTypes,
1011
sponsorValue,
1112
joinDate,
1213
activeYears,
@@ -18,26 +19,31 @@ export default class FinanceController {
1819
contactPosition,
1920
sponsorTasks,
2021
discountCode,
21-
sponsorNotes
22+
sponsorNotes,
23+
stockDescription,
24+
discountDescription
2225
} = req.body;
2326

2427
const sponsor = await FinanceServices.createSponsor(
2528
req.currentUser,
2629
name,
2730
activeStatus,
28-
sponsorValue,
31+
valueTypes,
2932
joinDate,
3033
activeYears,
31-
sponsorTierId,
34+
sponsorTierId || undefined,
3235
taxExempt,
3336
contactName,
3437
sponsorTasks,
3538
req.organization,
39+
sponsorValue,
3640
discountCode,
3741
sponsorNotes,
3842
contactEmail,
3943
contactPhone,
40-
contactPosition
44+
contactPosition,
45+
stockDescription,
46+
discountDescription
4147
);
4248
res.status(200).json(sponsor);
4349
} catch (error: unknown) {
@@ -329,6 +335,7 @@ export default class FinanceController {
329335
const {
330336
name,
331337
activeStatus,
338+
valueTypes,
332339
sponsorValue,
333340
joinDate,
334341
activeYears,
@@ -340,7 +347,9 @@ export default class FinanceController {
340347
taxExempt,
341348
sponsorTasks,
342349
discountCode,
343-
sponsorNotes
350+
sponsorNotes,
351+
stockDescription,
352+
discountDescription
344353
} = req.body;
345354

346355
const updatedSponsor = await FinanceServices.editSponsor(
@@ -349,18 +358,21 @@ export default class FinanceController {
349358
sponsorId,
350359
name,
351360
activeStatus,
352-
sponsorValue,
361+
valueTypes,
353362
joinDate,
354363
activeYears,
355-
sponsorTierId,
364+
sponsorTierId || undefined,
356365
contactName,
357366
taxExempt,
358367
sponsorTasks,
368+
sponsorValue,
359369
discountCode,
360370
sponsorNotes,
361371
contactEmail,
362372
contactPhone,
363-
contactPosition
373+
contactPosition,
374+
stockDescription,
375+
discountDescription
364376
);
365377

366378
res.status(200).json(updatedSponsor);

src/backend/src/controllers/prospective-sponsor.controllers.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export default class ProspectiveSponsorController {
1313
highlightThresholdDays,
1414
contactEmail,
1515
contactPhone,
16-
contactPosition
16+
contactPosition,
17+
notes
1718
} = req.body;
1819

1920
const prospectiveSponsor = await ProspectiveSponsorServices.createProspectiveSponsor(
@@ -27,7 +28,8 @@ export default class ProspectiveSponsorController {
2728
highlightThresholdDays,
2829
contactEmail,
2930
contactPhone,
30-
contactPosition
31+
contactPosition,
32+
notes
3133
);
3234
res.status(200).json(prospectiveSponsor);
3335
} catch (error: unknown) {
@@ -57,7 +59,8 @@ export default class ProspectiveSponsorController {
5759
highlightThresholdDays,
5860
contactEmail,
5961
contactPhone,
60-
contactPosition
62+
contactPosition,
63+
notes
6164
} = req.body;
6265

6366
const updatedProspectiveSponsor = await ProspectiveSponsorServices.editProspectiveSponsor(
@@ -73,7 +76,8 @@ export default class ProspectiveSponsorController {
7376
highlightThresholdDays,
7477
contactEmail,
7578
contactPhone,
76-
contactPosition
79+
contactPosition,
80+
notes
7781
);
7882
res.status(200).json(updatedProspectiveSponsor);
7983
} catch (error: unknown) {
@@ -131,19 +135,33 @@ export default class ProspectiveSponsorController {
131135
static async acceptProspectiveSponsor(req: Request, res: Response, next: NextFunction) {
132136
try {
133137
const { prospectiveSponsorId } = req.params as Record<string, string>;
134-
const { sponsorTierId, sponsorValue, joinDate, activeYears, taxExempt, discountCode, sponsorNotes } = req.body;
138+
const {
139+
sponsorTierId,
140+
valueTypes,
141+
sponsorValue,
142+
joinDate,
143+
activeYears,
144+
taxExempt,
145+
discountCode,
146+
sponsorNotes,
147+
stockDescription,
148+
discountDescription
149+
} = req.body;
135150

136151
const acceptedProspectiveSponsor = await ProspectiveSponsorServices.acceptProspectiveSponsor(
137152
req.currentUser,
138153
req.organization,
139154
prospectiveSponsorId,
140-
sponsorTierId,
141-
sponsorValue,
155+
sponsorTierId || undefined,
156+
valueTypes,
142157
joinDate,
143158
activeYears,
144159
taxExempt,
160+
sponsorValue,
145161
discountCode,
146-
sponsorNotes
162+
sponsorNotes,
163+
stockDescription,
164+
discountDescription
147165
);
148166
res.status(200).json(acceptedProspectiveSponsor);
149167
} catch (error: unknown) {

src/backend/src/prisma-query-args/prospective-sponsor.query-args.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const getProspectiveSponsorQueryArgs = (organizationId: string) =>
88
Prisma.validator<Prisma.Prospective_SponsorDefaultArgs>()({
99
include: {
1010
contactor: getUserQueryArgs(organizationId),
11-
tasks: getSponsorTaskQueryArgs(organizationId)
11+
tasks: getSponsorTaskQueryArgs(organizationId),
12+
contact: true
1213
}
1314
});

src/backend/src/prisma-query-args/sponsor.query.args.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export const getSponsorQueryArgs = (organizationId: string) =>
99
Prisma.validator<Prisma.SponsorDefaultArgs>()({
1010
include: {
1111
sponsorTasks: getSponsorTaskQueryArgs(organizationId),
12-
tier: true
12+
tier: true,
13+
contact: true
1314
}
1415
});
1516

src/backend/src/prisma/migrations/20260205202908_prospective_sponsors/migration.sql

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Warnings:
33
44
- 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.
65
76
*/
87
-- CreateEnum
@@ -14,19 +13,53 @@ CREATE TYPE "First_Contact_Method" AS ENUM ('INBOUND_FORM', 'INBOUND_EMAIL', 'OU
1413
-- DropForeignKey
1514
ALTER TABLE "Sponsor_Task" DROP CONSTRAINT "Sponsor_Task_sponsorId_fkey";
1615

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;
16+
-- CreateTable: Sponsor_Contact
17+
CREATE TABLE "Sponsor_Contact" (
18+
"sponsorContactId" TEXT NOT NULL,
19+
"name" TEXT NOT NULL,
20+
"email" TEXT,
21+
"phone" TEXT,
22+
"position" TEXT,
2323

24-
-- AlterTable
24+
CONSTRAINT "Sponsor_Contact_pkey" PRIMARY KEY ("sponsorContactId")
25+
);
26+
27+
-- Add contactId column to Sponsor (nullable initially)
28+
ALTER TABLE "Sponsor" ADD COLUMN "contactId" TEXT;
29+
30+
-- Create one Sponsor_Contact per Sponsor and link them in one step
31+
WITH new_contacts AS (
32+
INSERT INTO "Sponsor_Contact" ("sponsorContactId", "name")
33+
SELECT gen_random_uuid(), COALESCE("vendorContact", '')
34+
FROM "Sponsor"
35+
RETURNING "sponsorContactId", "name", ctid
36+
), numbered_contacts AS (
37+
SELECT "sponsorContactId", ROW_NUMBER() OVER (ORDER BY ctid) AS rn
38+
FROM new_contacts
39+
), numbered_sponsors AS (
40+
SELECT "sponsorId", ROW_NUMBER() OVER (ORDER BY "sponsorId") AS rn
41+
FROM "Sponsor"
42+
)
43+
UPDATE "Sponsor" s
44+
SET "contactId" = nc."sponsorContactId"
45+
FROM numbered_sponsors ns
46+
JOIN numbered_contacts nc ON ns.rn = nc.rn
47+
WHERE s."sponsorId" = ns."sponsorId";
48+
49+
-- Enforce NOT NULL and unique, drop old column
50+
ALTER TABLE "Sponsor" ALTER COLUMN "contactId" SET NOT NULL;
51+
ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_contactId_key" UNIQUE ("contactId");
52+
ALTER TABLE "Sponsor" DROP COLUMN "vendorContact";
53+
54+
-- AddForeignKey: Sponsor -> Sponsor_Contact
55+
ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_contactId_fkey" FOREIGN KEY ("contactId") REFERENCES "Sponsor_Contact"("sponsorContactId") ON DELETE RESTRICT ON UPDATE CASCADE;
56+
57+
-- AlterTable: Sponsor_Task
2558
ALTER TABLE "Sponsor_Task" ADD COLUMN "done" BOOLEAN NOT NULL DEFAULT false,
2659
ADD COLUMN "prospectiveSponsorId" TEXT,
2760
ALTER COLUMN "sponsorId" DROP NOT NULL;
2861

29-
-- CreateTable
62+
-- CreateTable: Prospective_Sponsor (with contactId FK instead of inline fields)
3063
CREATE TABLE "Prospective_Sponsor" (
3164
"prospectiveSponsorId" TEXT NOT NULL,
3265
"organizationId" TEXT NOT NULL,
@@ -37,10 +70,7 @@ CREATE TABLE "Prospective_Sponsor" (
3770
"status" "Prospective_Sponsor_Status" NOT NULL DEFAULT 'IN_PROGRESS',
3871
"firstContactMethod" "First_Contact_Method" NOT NULL,
3972
"contactorUserId" TEXT NOT NULL,
40-
"contactName" TEXT NOT NULL,
41-
"contactEmail" TEXT,
42-
"contactPhone" TEXT,
43-
"contactPosition" TEXT,
73+
"contactId" TEXT NOT NULL,
4474
"dateDeleted" TIMESTAMP(3),
4575

4676
CONSTRAINT "Prospective_Sponsor_pkey" PRIMARY KEY ("prospectiveSponsorId")
@@ -55,6 +85,9 @@ CREATE INDEX "Prospective_Sponsor_contactorUserId_idx" ON "Prospective_Sponsor"(
5585
-- CreateIndex
5686
CREATE UNIQUE INDEX "Prospective_Sponsor_organizationName_organizationId_key" ON "Prospective_Sponsor"("organizationName", "organizationId");
5787

88+
-- CreateIndex: unique contactId on Prospective_Sponsor
89+
CREATE UNIQUE INDEX "Prospective_Sponsor_contactId_key" ON "Prospective_Sponsor"("contactId");
90+
5891
-- CreateIndex
5992
CREATE INDEX "Sponsor_Task_prospectiveSponsorId_idx" ON "Sponsor_Task"("prospectiveSponsorId");
6093

@@ -69,3 +102,6 @@ ALTER TABLE "Prospective_Sponsor" ADD CONSTRAINT "Prospective_Sponsor_organizati
69102

70103
-- AddForeignKey
71104
ALTER TABLE "Prospective_Sponsor" ADD CONSTRAINT "Prospective_Sponsor_contactorUserId_fkey" FOREIGN KEY ("contactorUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
105+
106+
-- AddForeignKey
107+
ALTER TABLE "Prospective_Sponsor" ADD CONSTRAINT "Prospective_Sponsor_contactId_fkey" FOREIGN KEY ("contactId") REFERENCES "Sponsor_Contact"("sponsorContactId") ON DELETE RESTRICT ON UPDATE CASCADE;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- CreateEnum
2+
CREATE TYPE "Sponsor_Value_Type" AS ENUM ('MONETARY', 'STOCK', 'DISCOUNT');
3+
4+
-- AlterTable: Sponsor
5+
ALTER TABLE "Sponsor"
6+
ADD COLUMN "valueTypes" "Sponsor_Value_Type"[] DEFAULT ARRAY['MONETARY']::"Sponsor_Value_Type"[],
7+
ADD COLUMN "stockDescription" TEXT,
8+
ADD COLUMN "discountDescription" TEXT;
9+
10+
-- Make sponsorValue nullable
11+
ALTER TABLE "Sponsor" ALTER COLUMN "sponsorValue" DROP NOT NULL;
12+
13+
-- AlterTable: Prospective_Sponsor (add notes)
14+
ALTER TABLE "Prospective_Sponsor" ADD COLUMN "notes" TEXT;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Sponsor" ALTER COLUMN "sponsorTierId" DROP NOT NULL;

src/backend/src/prisma/schema.prisma

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ enum First_Contact_Method {
173173
OTHER
174174
}
175175

176+
enum Sponsor_Value_Type {
177+
MONETARY
178+
STOCK
179+
DISCOUNT
180+
}
181+
176182
model User {
177183
userId String @id @default(uuid())
178184
firstName String
@@ -807,28 +813,39 @@ model Vendor {
807813
@@index([organizationId])
808814
}
809815

816+
model Sponsor_Contact {
817+
sponsorContactId String @id @default(uuid())
818+
name String
819+
email String?
820+
phone String?
821+
position String?
822+
sponsor Sponsor?
823+
prospectiveSponsor Prospective_Sponsor?
824+
}
825+
810826
model Sponsor {
811-
sponsorId String @id @default(uuid())
812-
name String
813-
organizationId String
814-
organization Organization @relation(fields: [organizationId], references: [organizationId])
815-
dateCreated DateTime @default(now())
816-
dateDeleted DateTime?
817-
activeStatus Boolean
818-
contactName String
819-
contactEmail String?
820-
contactPhone String?
821-
contactPosition String?
822-
tier Sponsor_Tier @relation(fields: [sponsorTierId], references: [sponsorTierId])
823-
sponsorTierId String
824-
sponsorValue Int
825-
joinDate DateTime
826-
discountCode String?
827-
activeYears Int[]
828-
taxExempt Boolean
829-
sponsorNotes String?
830-
sponsorTasks Sponsor_Task[]
831-
logoImageId String?
827+
sponsorId String @id @default(uuid())
828+
name String
829+
organizationId String
830+
organization Organization @relation(fields: [organizationId], references: [organizationId])
831+
dateCreated DateTime @default(now())
832+
dateDeleted DateTime?
833+
activeStatus Boolean
834+
contact Sponsor_Contact @relation(fields: [contactId], references: [sponsorContactId])
835+
contactId String @unique
836+
tier Sponsor_Tier? @relation(fields: [sponsorTierId], references: [sponsorTierId])
837+
sponsorTierId String?
838+
valueTypes Sponsor_Value_Type[]
839+
sponsorValue Int?
840+
stockDescription String?
841+
discountDescription String?
842+
joinDate DateTime
843+
discountCode String?
844+
activeYears Int[]
845+
taxExempt Boolean
846+
sponsorNotes String?
847+
sponsorTasks Sponsor_Task[]
848+
logoImageId String?
832849
833850
@@unique([name, organizationId], name: "uniqueSponsor")
834851
@@index([sponsorTierId])
@@ -865,10 +882,9 @@ model Prospective_Sponsor {
865882
firstContactMethod First_Contact_Method
866883
contactor User @relation(fields: [contactorUserId], references: [userId], name: "prospectiveSponsorContactor")
867884
contactorUserId String
868-
contactName String
869-
contactEmail String?
870-
contactPhone String?
871-
contactPosition String?
885+
contact Sponsor_Contact @relation(fields: [contactId], references: [sponsorContactId])
886+
contactId String @unique
887+
notes String?
872888
dateDeleted DateTime?
873889
tasks Sponsor_Task[]
874890

0 commit comments

Comments
 (0)