Skip to content

Commit

Permalink
Preliminary Donation Routes (#13)
Browse files Browse the repository at this point in the history
* finish get allDonations route (it works!)

* add more donation routes

* Add working create donation route

* Refactor routes location

* add working create donation route

* add recurrence enum

* Add route testing docs in swagger

* fix route to get donations by id

* test linting

* called prettier

* more linting fixes

* hopefully final lint fixes
  • Loading branch information
jessica2673 authored Apr 4, 2024
1 parent 7cb5770 commit 38eab82
Show file tree
Hide file tree
Showing 18 changed files with 302 additions and 215 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cd don-efficace
/.env
/frontend/.env
```
3. Run the application
3. Run the application. Make sure the DATABASE_URL is with scv2_db when building the container.
```bash
docker compose up --build
```
Expand All @@ -67,7 +67,7 @@ docker exec -it scv2-frontend bash -c "yarn fix"
## Database/Prisma Information
"npx prisma generate" to generate at the start
"npx prisma db push" to push
"npx prisma studio" to run prisma
"npx prisma studio" to run prisma. Make sure the DATABASE_URL is with localhost

### Creating Prisma Migration

Expand Down
1 change: 0 additions & 1 deletion backend/typescript/models/entity.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ export default class Entity extends Model {
@Column
file_name!: string;
}

This file was deleted.

32 changes: 0 additions & 32 deletions backend/typescript/prisma/migrations/20240317173631_/migration.sql

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
-- CreateEnum
CREATE TYPE "RoleType" AS ENUM ('Admin', 'User');

-- CreateEnum
CREATE TYPE "Recurrence" AS ENUM ('None', 'Weekly', 'Monthly', 'Annually');

-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
Expand All @@ -23,20 +26,13 @@ CREATE TABLE "Donation" (
"user_id" TEXT NOT NULL,
"amount" DOUBLE PRECISION NOT NULL,
"donation_date" TIMESTAMP(3) NOT NULL,
"is_recurring" BOOLEAN NOT NULL,
"cause_id" INTEGER NOT NULL,
"is_recurring" "Recurrence" NOT NULL,
"confirmation_email_sent" BOOLEAN NOT NULL,

CONSTRAINT "Donation_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "CauseDonation" (
"donation_id" INTEGER NOT NULL,
"cause_id" INTEGER NOT NULL,

CONSTRAINT "CauseDonation_pkey" PRIMARY KEY ("donation_id","cause_id")
);

-- CreateTable
CREATE TABLE "Cause" (
"id" SERIAL NOT NULL,
Expand Down Expand Up @@ -67,9 +63,6 @@ CREATE TABLE "Item" (
CONSTRAINT "Item_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "Donation_user_id_key" ON "Donation"("user_id");

-- CreateIndex
CREATE UNIQUE INDEX "NPO_item_id_key" ON "NPO"("item_id");

Expand Down
15 changes: 11 additions & 4 deletions backend/typescript/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ model User {
opt_in Boolean?
createdAt DateTime @default(now())
updatedAt DateTime?
role RoleType
donations Donation?
role RoleType
donations Donation[]
}

enum RoleType{
Expand All @@ -32,15 +32,22 @@ enum RoleType{
model Donation {
id Int @id @default(autoincrement())
user User @relation(fields: [user_id], references: [id])
user_id String @unique
user_id String
amount Float
donation_date DateTime
cause Cause @relation(fields: [cause_id], references: [id])
cause_id Int
is_recurring Boolean
is_recurring Recurrence
confirmation_email_sent Boolean
}

enum Recurrence {
None
Weekly
Monthly
Annually
}

// Cause and NPO: One-to-Many: A single cause can be associated with many NPOs, and each NPO is linked to one cause
model Cause {
id Int @id @default(autoincrement())
Expand Down
65 changes: 33 additions & 32 deletions backend/typescript/rest/donationsRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// import { Prisma } from "@prisma/client";
import { Router } from "express";
import prisma from '../prisma';
import prisma from "../prisma";
import DonationService from "../services/implementations/donationService";
import IDonationService from "../services/interfaces/donationService";
import { getErrorMessage } from "../utilities/errorUtils";
Expand All @@ -11,44 +11,45 @@ const donationRouter = Router();

// display all donations
donationRouter.get("/", async (req: any, res: any) => {
try {
const allDonations = await donationService.getAllDonations();

res.status(200).json(allDonations);
} catch (error) {
res.status(500).json({ error: getErrorMessage(error) });
}
try {
const allDonations = await donationService.getAllDonations();
console.log("getting donations");
res.status(200).json(allDonations);
} catch (error) {
res.status(500).json({ error: getErrorMessage(error) });
}
});

// display all donations made by a user
donationRouter.get("/:id", async (req: any, res: any) => {
const id = req.params.id;
const { id } = req.params;

try {
const userDonations = donationService.getUserDonation(id);
try {
const userDonations = await donationService.getUserDonation(id);

res.status(200).json(userDonations);
} catch (error) {
res.status(500).json({ error: getErrorMessage(error) });
}
res.status(200).json(userDonations);
} catch (error) {
res.status(500).json({ error: getErrorMessage(error) });
}
});

// Each donation has 1 cause associated with it, the donation from user will be split before calling this route.
donationRouter.post("/give", async (req: any, res: any) => {
try {
const { user_id, amount, cause_id, is_recurring, confirmation_email_sent } = req.body;

const newDonation = await donationService.createDonation(
user_id,
amount,
cause_id,
is_recurring,
confirmation_email_sent
);
res.status(200).json(newDonation);
} catch (error) {
res.status(500).json({ error: getErrorMessage(error) });
}
})

export default donationRouter;
try {
const { userId, amount, causeId, isRecurring, confirmationEmailSent } =
req.body;

const newDonation = await donationService.createDonation(
userId,
amount,
causeId,
isRecurring,
confirmationEmailSent,
);
res.status(200).json(newDonation);
} catch (error) {
res.status(500).json({ error: getErrorMessage(error) });
}
});

export default donationRouter;
2 changes: 1 addition & 1 deletion backend/typescript/rest/userRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ userRouter.post("/", createUserDtoValidator, async (req, res) => {
});

await authService.sendEmailVerificationLink(req.body.email);

res.status(201).json(newUser);
} catch (error: unknown) {
res.status(500).json({ error: getErrorMessage(error) });
Expand Down
4 changes: 2 additions & 2 deletions backend/typescript/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ app.use("/entities", entityRouter);
app.use("/simple-entities", simpleEntityRouter);
app.use("/users", userRouter);
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.use('/donations', donationRouter);
app.use("/donations", donationRouter);

// Health check
app.get("/test", async (req: any, res: any) => {
res.status(200).json('endpoint hath been hit');
res.status(200).json("endpoint hath been hit");
});

sequelize.authenticate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ jest.mock("firebase-admin", () => {
return { auth };
});


describe("pg userService", () => {
let userService: UserService;

Expand Down
15 changes: 6 additions & 9 deletions backend/typescript/services/implementations/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,8 @@ class AuthService implements IAuthService {
roles: Set<Role>,
): Promise<boolean> {
try {
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken = await firebaseAdmin
.auth()
.verifyIdToken(accessToken, true);
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken =
await firebaseAdmin.auth().verifyIdToken(accessToken, true);
const userRole = await this.userService.getUserRoleByAuthId(
decodedIdToken.uid,
);
Expand All @@ -190,9 +189,8 @@ class AuthService implements IAuthService {
requestedUserId: string,
): Promise<boolean> {
try {
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken = await firebaseAdmin
.auth()
.verifyIdToken(accessToken, true);
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken =
await firebaseAdmin.auth().verifyIdToken(accessToken, true);
const tokenUserId = await this.userService.getUserIdByAuthId(
decodedIdToken.uid,
);
Expand All @@ -214,9 +212,8 @@ class AuthService implements IAuthService {
requestedEmail: string,
): Promise<boolean> {
try {
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken = await firebaseAdmin
.auth()
.verifyIdToken(accessToken, true);
const decodedIdToken: firebaseAdmin.auth.DecodedIdToken =
await firebaseAdmin.auth().verifyIdToken(accessToken, true);

const firebaseUser = await firebaseAdmin
.auth()
Expand Down
Loading

0 comments on commit 38eab82

Please sign in to comment.