Skip to content

Commit

Permalink
Merge pull request #24 from MinaFoundation/feature/voting-phase
Browse files Browse the repository at this point in the history
Feature/voting phase
  • Loading branch information
iluxonchik authored Nov 27, 2024
2 parents bc7bb0d + 338bcbc commit d8254c5
Show file tree
Hide file tree
Showing 14 changed files with 311 additions and 129 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,5 @@ Thumbs.db
# Prisma
prisma/.env

# direnv
.direnv
3 changes: 1 addition & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
# Core dependencies
nodejs_20
nodePackages.typescript
nodePackages.tsx
podman
podman-compose
direnv
Expand Down Expand Up @@ -53,4 +52,4 @@
};
};
});
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pgt-web-app",
"version": "0.1.6",
"version": "0.1.7",
"private": true,
"type": "module",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "SubmissionPhase" (
"id" UUID NOT NULL,
"fundingRoundId" UUID NOT NULL,
"startDate" TIMESTAMPTZ(6) NOT NULL,
"endDate" TIMESTAMPTZ(6) NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,

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

-- CreateIndex
CREATE UNIQUE INDEX "SubmissionPhase_fundingRoundId_key" ON "SubmissionPhase"("fundingRoundId");

-- CreateIndex
CREATE INDEX "SubmissionPhase_startDate_endDate_idx" ON "SubmissionPhase"("startDate", "endDate");

-- AddForeignKey
ALTER TABLE "SubmissionPhase" ADD CONSTRAINT "SubmissionPhase_fundingRoundId_fkey" FOREIGN KEY ("fundingRoundId") REFERENCES "FundingRound"("id") ON DELETE CASCADE ON UPDATE CASCADE;
14 changes: 14 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ model FundingRound {
topic Topic @relation(fields: [topicId], references: [id])
proposals Proposal[]
submissionPhase SubmissionPhase?
considerationPhase ConsiderationPhase?
deliberationPhase DeliberationPhase?
votingPhase VotingPhase?
Expand Down Expand Up @@ -201,6 +202,19 @@ model VotingPhase {
@@index([startDate, endDate])
}

model SubmissionPhase {
id String @id @default(uuid()) @db.Uuid
fundingRoundId String @unique @db.Uuid
startDate DateTime @db.Timestamptz(6)
endDate DateTime @db.Timestamptz(6)
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
fundingRound FundingRound @relation(fields: [fundingRoundId], references: [id], onDelete: Cascade)
@@index([startDate, endDate])
}

model AdminUser {
id String @id @default(uuid()) @db.Uuid
userId String @unique @db.Uuid
Expand Down
78 changes: 57 additions & 21 deletions src/app/api/admin/funding-rounds/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ import { validatePhaseDates } from "@/lib/validation";

const adminService = new AdminService(prisma);

interface DateRange {
from: string;
to: string;
}

interface FundingRoundRequestData {
name: string;
description: string;
topicId: string;
totalBudget: number;
fundingRoundDates: DateRange;
submissionDates: DateRange;
considerationDates: DateRange;
deliberationDates: DateRange;
votingDates: DateRange;
}

interface RouteContext {
params: Promise<{
id: string;
Expand Down Expand Up @@ -58,37 +75,56 @@ export async function PUT(request: Request, context: RouteContext) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}

const data = await request.json();
const data: FundingRoundRequestData = await request.json();

// Convert string dates to Date objects for validation
const fundingRoundDates = {
from: new Date(data.fundingRoundDates.from),
to: new Date(data.fundingRoundDates.to),
};
const submissionDates = {
from: new Date(data.submissionDates.from),
to: new Date(data.submissionDates.to),
};
const considerationDates = {
from: new Date(data.considerationDates.from),
to: new Date(data.considerationDates.to),
};
const deliberationDates = {
from: new Date(data.deliberationDates.from),
to: new Date(data.deliberationDates.to),
};
const votingDates = {
from: new Date(data.votingDates.from),
to: new Date(data.votingDates.to),
};

// Validate phase dates
const datesValid = validatePhaseDates({
fundingRound: {
from: new Date(data.fundingRoundDates.from),
to: new Date(data.fundingRoundDates.to),
},
consideration: {
from: new Date(data.considerationDates.from),
to: new Date(data.considerationDates.to),
},
deliberation: {
from: new Date(data.deliberationDates.from),
to: new Date(data.deliberationDates.to),
},
voting: {
from: new Date(data.votingDates.from),
to: new Date(data.votingDates.to),
},
fundingRound: fundingRoundDates,
submission: submissionDates,
consideration: considerationDates,
deliberation: deliberationDates,
voting: votingDates,
});

if (!datesValid.valid) {
return NextResponse.json({ error: datesValid.error }, { status: 400 });
}

const round = await adminService.updateFundingRound(
(
await context.params
).id,
data
(await context.params).id,
{
name: data.name,
description: data.description,
topicId: data.topicId,
totalBudget: data.totalBudget,
fundingRoundDates,
submissionDates,
considerationDates,
deliberationDates,
votingDates,
}
);

return NextResponse.json(round);
Expand Down
72 changes: 54 additions & 18 deletions src/app/api/admin/funding-rounds/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ import prisma from "@/lib/prisma";
import { getUserFromRequest } from "@/lib/auth";
import { validatePhaseDates } from "@/lib/validation";

interface DateRange {
from: string;
to: string;
}

interface FundingRoundRequestData {
name: string;
description: string;
topicId: string;
totalBudget: number;
fundingRoundDates: DateRange;
submissionDates: DateRange;
considerationDates: DateRange;
deliberationDates: DateRange;
votingDates: DateRange;
}

const adminService = new AdminService(prisma);

export async function GET(req: Request) {
Expand Down Expand Up @@ -41,35 +58,54 @@ export async function POST(req: Request) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}

const data = await req.json();
const data: FundingRoundRequestData = await req.json();

// Convert string dates to Date objects for validation
const fundingRoundDates = {
from: new Date(data.fundingRoundDates.from),
to: new Date(data.fundingRoundDates.to),
};
const submissionDates = {
from: new Date(data.submissionDates.from),
to: new Date(data.submissionDates.to),
};
const considerationDates = {
from: new Date(data.considerationDates.from),
to: new Date(data.considerationDates.to),
};
const deliberationDates = {
from: new Date(data.deliberationDates.from),
to: new Date(data.deliberationDates.to),
};
const votingDates = {
from: new Date(data.votingDates.from),
to: new Date(data.votingDates.to),
};

// Validate phase dates
const datesValid = validatePhaseDates({
fundingRound: {
from: new Date(data.fundingRoundDates.from),
to: new Date(data.fundingRoundDates.to),
},
consideration: {
from: new Date(data.considerationDates.from),
to: new Date(data.considerationDates.to),
},
deliberation: {
from: new Date(data.deliberationDates.from),
to: new Date(data.deliberationDates.to),
},
voting: {
from: new Date(data.votingDates.from),
to: new Date(data.votingDates.to),
},
fundingRound: fundingRoundDates,
submission: submissionDates,
consideration: considerationDates,
deliberation: deliberationDates,
voting: votingDates,
});

if (!datesValid.valid) {
return NextResponse.json({ error: datesValid.error }, { status: 400 });
}

const round = await adminService.createFundingRound({
...data,
name: data.name,
description: data.description,
topicId: data.topicId,
totalBudget: data.totalBudget,
createdById: user.id,
fundingRoundDates,
submissionDates,
considerationDates,
deliberationDates,
votingDates,
});
return NextResponse.json(round);
} catch (error) {
Expand Down
Loading

0 comments on commit d8254c5

Please sign in to comment.