Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 8
feat: qol script for regen & evoting delegation#817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
8357ea52fb1c9e8c71a474fdd9e4ba35133b90f0d78fa0add26afa2e32765fc409497935c897fdd73f313d41508620ae4b8740997439222a85ad0a7b1ccd39File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,233 @@ | ||
| import { Request, Response } from "express"; | ||
| import { DelegationService } from "../services/DelegationService"; | ||
| import { VoteService } from "../services/VoteService"; | ||
| export class DelegationController { | ||
| private delegationService: DelegationService; | ||
| private voteService: VoteService; | ||
| constructor() { | ||
| this.delegationService = new DelegationService(); | ||
| this.voteService = new VoteService(); | ||
| } | ||
| async createDelegation(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const { delegateId } = req.body; | ||
| const delegatorId = (req as any).user?.id; | ||
| if (!delegatorId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| if (!delegateId) { | ||
| return res.status(400).json({ error: "Missing delegateId" }); | ||
| } | ||
| const delegation = await this.delegationService.createDelegation( | ||
| pollId, | ||
| delegatorId, | ||
| delegateId | ||
| ); | ||
| res.status(201).json(delegation); | ||
| } catch (error: any) { | ||
| console.error("Error creating delegation:", error); | ||
| res.status(400).json({ error: error.message }); | ||
| } | ||
| } | ||
| async revokeDelegation(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const delegatorId = (req as any).user?.id; | ||
| if (!delegatorId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegation = await this.delegationService.revokeDelegationByPoll( | ||
| pollId, | ||
| delegatorId | ||
| ); | ||
| res.json(delegation); | ||
| } catch (error: any) { | ||
| console.error("Error revoking delegation:", error); | ||
| res.status(400).json({ error: error.message }); | ||
| } | ||
| } | ||
| async acceptDelegation(req: Request, res: Response) { | ||
| try { | ||
| const { id } = req.params; | ||
| const delegateId = (req as any).user?.id; | ||
| if (!delegateId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegation = await this.delegationService.acceptDelegation( | ||
| id, | ||
| delegateId | ||
| ); | ||
| res.json(delegation); | ||
| } catch (error: any) { | ||
| console.error("Error accepting delegation:", error); | ||
| res.status(400).json({ error: error.message }); | ||
| } | ||
| } | ||
| async rejectDelegation(req: Request, res: Response) { | ||
| try { | ||
| const { id } = req.params; | ||
| const delegateId = (req as any).user?.id; | ||
| if (!delegateId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegation = await this.delegationService.rejectDelegation( | ||
| id, | ||
| delegateId | ||
| ); | ||
| res.json(delegation); | ||
| } catch (error: any) { | ||
| console.error("Error rejecting delegation:", error); | ||
| res.status(400).json({ error: error.message }); | ||
| } | ||
| } | ||
| async getActiveDelegations(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const delegateId = (req as any).user?.id; | ||
| const includeUsed = req.query.includeUsed === "true" || req.query.includeUsed === "1"; | ||
| if (!delegateId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegations = includeUsed | ||
| ? await this.delegationService.getActiveAndUsedDelegationsForDelegate( | ||
| pollId, | ||
| delegateId | ||
| ) | ||
| : await this.delegationService.getActiveDelegationsForDelegate( | ||
| pollId, | ||
| delegateId | ||
| ); | ||
| res.json(delegations); | ||
| } catch (error: any) { | ||
| console.error("Error getting active delegations:", error); | ||
| res.status(500).json({ error: error.message }); | ||
| } | ||
| } | ||
| async getPendingDelegations(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const delegateId = (req as any).user?.id; | ||
| if (!delegateId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegations = await this.delegationService.getPendingDelegationsForDelegate( | ||
| pollId, | ||
| delegateId | ||
| ); | ||
| res.json(delegations); | ||
| } catch (error: any) { | ||
| console.error("Error getting pending delegations:", error); | ||
| res.status(500).json({ error: error.message }); | ||
| } | ||
| } | ||
| async getAllPendingDelegations(req: Request, res: Response) { | ||
| try { | ||
| const userId = (req as any).user?.id; | ||
| if (!userId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegations = await this.delegationService.getAllPendingDelegationsForUser( | ||
| userId | ||
| ); | ||
| res.json(delegations); | ||
| } catch (error: any) { | ||
| console.error("Error getting all pending delegations:", error); | ||
| res.status(500).json({ error: error.message }); | ||
| } | ||
| } | ||
| async getMyDelegation(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const delegatorId = (req as any).user?.id; | ||
| if (!delegatorId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| const delegation = await this.delegationService.getDelegationForDelegator( | ||
| pollId, | ||
| delegatorId | ||
| ); | ||
| res.json(delegation); | ||
| } catch (error: any) { | ||
| console.error("Error getting my delegation:", error); | ||
| res.status(500).json({ error: error.message }); | ||
| } | ||
| } | ||
| async castDelegatedVote(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const { delegatorId, voteData, mode } = req.body; | ||
| const delegateId = (req as any).user?.id; | ||
| if (!delegateId) { | ||
| return res.status(401).json({ error: "Authentication required" }); | ||
| } | ||
| if (!delegatorId || !voteData) { | ||
| return res.status(400).json({ error: "Missing delegatorId or voteData" }); | ||
| } | ||
| const vote = await this.voteService.castDelegatedVote( | ||
| pollId, | ||
| delegateId, | ||
| delegatorId, | ||
| voteData, | ||
| mode || "normal" | ||
| ); | ||
| res.status(201).json(vote); | ||
| } catch (error: any) { | ||
| console.error("Error casting delegated vote:", error); | ||
| res.status(400).json({ error: error.message }); | ||
| } | ||
| } | ||
| async canPollHaveDelegation(req: Request, res: Response) { | ||
| try { | ||
| const { pollId } = req.params; | ||
| const result = await this.delegationService.canPollHaveDelegation(pollId); | ||
| res.json(result); | ||
| } catch (error: any) { | ||
| console.error("Error checking delegation eligibility:", error); | ||
| res.status(500).json({ error: error.message }); | ||
| } | ||
| } | ||
coodos marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import { | ||
| Column, | ||
| CreateDateColumn, | ||
| Entity, | ||
| JoinColumn, | ||
| ManyToOne, | ||
| PrimaryGeneratedColumn, | ||
| UpdateDateColumn, | ||
| } from "typeorm"; | ||
| import { Poll } from "./Poll"; | ||
| import { User } from "./User"; | ||
| export type DelegationStatus = "pending" | "active" | "rejected" | "revoked" | "used"; | ||
| @Entity("delegations") | ||
| export class Delegation { | ||
| @PrimaryGeneratedColumn("uuid") | ||
| id!: string; | ||
| @ManyToOne(() => Poll, { onDelete: "CASCADE" }) | ||
| @JoinColumn({ name: "pollId" }) | ||
| poll!: Poll; | ||
| @Column("uuid") | ||
| pollId!: string; | ||
| @ManyToOne(() => User, { onDelete: "CASCADE" }) | ||
| @JoinColumn({ name: "delegatorId" }) | ||
| delegator!: User; | ||
| @Column("uuid") | ||
| delegatorId!: string; | ||
| @ManyToOne(() => User, { onDelete: "CASCADE" }) | ||
| @JoinColumn({ name: "delegateId" }) | ||
| delegate!: User; | ||
| @Column("uuid") | ||
| delegateId!: string; | ||
| @Column("enum", { | ||
| enum: ["pending", "active", "rejected", "revoked", "used"], | ||
| default: "pending", | ||
| }) | ||
| status!: DelegationStatus; | ||
| @CreateDateColumn() | ||
| createdAt!: Date; | ||
| @UpdateDateColumn() | ||
| updatedAt!: Date; | ||
| } | ||
coodos marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { MigrationInterface, QueryRunner } from "typeorm"; | ||
| export class Migration1771588337031 implements MigrationInterface { | ||
| name = 'Migration1771588337031' | ||
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| await queryRunner.query(`CREATE TYPE "public"."delegations_status_enum" AS ENUM('pending', 'active', 'rejected', 'revoked', 'used')`); | ||
| await queryRunner.query(`CREATE TABLE "delegations" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "pollId" uuid NOT NULL, "delegatorId" uuid NOT NULL, "delegateId" uuid NOT NULL, "status" "public"."delegations_status_enum" NOT NULL DEFAULT 'pending', "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_01f9fbbc9b3bf52236a4e951b19" PRIMARY KEY ("id"))`); | ||
| await queryRunner.query(`ALTER TABLE "votes" ADD "castById" uuid`); | ||
| await queryRunner.query(`ALTER TABLE "votes" ADD CONSTRAINT "FK_c3f766036bdc68567015a3f6f9b" FOREIGN KEY ("castById") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`); | ||
coodos marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| await queryRunner.query(`ALTER TABLE "delegations" ADD CONSTRAINT "FK_32c81d839deb11bcfd8f83ba2f9" FOREIGN KEY ("pollId") REFERENCES "polls"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); | ||
| await queryRunner.query(`ALTER TABLE "delegations" ADD CONSTRAINT "FK_2efda215aa6a265a536fe68dcf6" FOREIGN KEY ("delegatorId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); | ||
| await queryRunner.query(`ALTER TABLE "delegations" ADD CONSTRAINT "FK_2d4590d0c84a5ca333fd64e4c2a" FOREIGN KEY ("delegateId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); | ||
| } | ||
| public async down(queryRunner: QueryRunner): Promise<void> { | ||
| await queryRunner.query(`ALTER TABLE "delegations" DROP CONSTRAINT "FK_2d4590d0c84a5ca333fd64e4c2a"`); | ||
| await queryRunner.query(`ALTER TABLE "delegations" DROP CONSTRAINT "FK_2efda215aa6a265a536fe68dcf6"`); | ||
| await queryRunner.query(`ALTER TABLE "delegations" DROP CONSTRAINT "FK_32c81d839deb11bcfd8f83ba2f9"`); | ||
| await queryRunner.query(`ALTER TABLE "votes" DROP CONSTRAINT "FK_c3f766036bdc68567015a3f6f9b"`); | ||
| await queryRunner.query(`ALTER TABLE "votes" DROP COLUMN "castById"`); | ||
| await queryRunner.query(`DROP TABLE "delegations"`); | ||
| await queryRunner.query(`DROP TYPE "public"."delegations_status_enum"`); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.