mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-17 02:45:08 +00:00
fix: fix multiple submissions
This commit is contained in:
@ -1,36 +1,17 @@
|
|||||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
export class CreateTaskEntities1733833824321 implements MigrationInterface {
|
export class CreateTaskEntities1733904556416 implements MigrationInterface {
|
||||||
name = 'CreateTaskEntities1733833824321';
|
name = 'CreateTaskEntities1733904556416';
|
||||||
|
|
||||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
await queryRunner.query(
|
await queryRunner.query(
|
||||||
`CREATE TABLE "task_submissions"
|
`CREATE TABLE "task_submissions" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "status" character varying NOT NULL, "submitted_at" TIMESTAMP WITH TIME ZONE NOT NULL, "task_id" uuid NOT NULL, "proof_of_completion_id" uuid, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "REL_d6cfaee118a0300d652e28ee16" UNIQUE ("task_id"), CONSTRAINT "PK_8d19d6b5dd776e373113de50018" PRIMARY KEY ("id"))`,
|
||||||
("id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
|
||||||
"status" character varying NOT NULL, "submitted_at" TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
||||||
"task_id" uuid NOT NULL, "proof_of_completion_id" uuid,
|
|
||||||
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
||||||
"updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
||||||
CONSTRAINT "REL_d6cfaee118a0300d652e28ee16" UNIQUE ("task_id"),
|
|
||||||
CONSTRAINT "PK_8d19d6b5dd776e373113de50018" PRIMARY KEY ("id"))`,
|
|
||||||
);
|
);
|
||||||
await queryRunner.query(
|
await queryRunner.query(
|
||||||
`CREATE TABLE "tasks" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
`CREATE TABLE "tasks" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying(255) NOT NULL, "description" character varying(255) NOT NULL, "reward_amount" numeric(12,3) NOT NULL, "image_id" uuid NOT NULL, "task_frequency" character varying NOT NULL, "start_date" date NOT NULL, "due_date" date NOT NULL, "is_proof_required" boolean NOT NULL, "assigned_to_id" uuid NOT NULL, "assigned_by_id" uuid NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_8d12ff38fcc62aaba2cab748772" PRIMARY KEY ("id"))`,
|
||||||
"title" character varying(255) NOT NULL,
|
|
||||||
"description" character varying(255) NOT NULL,
|
|
||||||
"reward_amount" numeric(12,3) NOT NULL,
|
|
||||||
"image_id" uuid NOT NULL,
|
|
||||||
"task_frequency" character varying NOT NULL,
|
|
||||||
"start_date" date NOT NULL, "due_date" date NOT NULL,
|
|
||||||
"is_proof_required" boolean NOT NULL,
|
|
||||||
"assigned_to_id" uuid NOT NULL,
|
|
||||||
"assigned_by_id" uuid NOT NULL,
|
|
||||||
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
||||||
"updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
||||||
CONSTRAINT "PK_8d12ff38fcc62aaba2cab748772" PRIMARY KEY ("id"))`,
|
|
||||||
);
|
);
|
||||||
await queryRunner.query(
|
await queryRunner.query(
|
||||||
`ALTER TABLE "task_submissions" ADD CONSTRAINT "FK_d6cfaee118a0300d652e28ee166" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
|
`ALTER TABLE "task_submissions" ADD CONSTRAINT "FK_d6cfaee118a0300d652e28ee166" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
);
|
);
|
||||||
await queryRunner.query(
|
await queryRunner.query(
|
||||||
`ALTER TABLE "task_submissions" ADD CONSTRAINT "FK_87876dfe440de7aafce216e9f58" FOREIGN KEY ("proof_of_completion_id") REFERENCES "documents"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
|
`ALTER TABLE "task_submissions" ADD CONSTRAINT "FK_87876dfe440de7aafce216e9f58" FOREIGN KEY ("proof_of_completion_id") REFERENCES "documents"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
|
@ -8,4 +8,3 @@ export * from './1733731507261-create-junior-entity';
|
|||||||
export * from './1733732021622-create-guardian-entity';
|
export * from './1733732021622-create-guardian-entity';
|
||||||
export * from './1733748083604-create-theme-entity';
|
export * from './1733748083604-create-theme-entity';
|
||||||
export * from './1733750228289-seed-default-avatar';
|
export * from './1733750228289-seed-default-avatar';
|
||||||
export * from './1733833824321-create-task-entities';
|
|
||||||
|
@ -30,7 +30,7 @@ export class TaskSubmission extends BaseEntity {
|
|||||||
@Column({ type: 'uuid', name: 'proof_of_completion_id', nullable: true })
|
@Column({ type: 'uuid', name: 'proof_of_completion_id', nullable: true })
|
||||||
proofOfCompletionId!: string;
|
proofOfCompletionId!: string;
|
||||||
|
|
||||||
@OneToOne(() => Task, (task) => task.submission)
|
@OneToOne(() => Task, (task) => task.submission, { onDelete: 'CASCADE' })
|
||||||
@JoinColumn({ name: 'task_id' })
|
@JoinColumn({ name: 'task_id' })
|
||||||
task!: Task;
|
task!: Task;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
BaseEntity,
|
||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
@ -16,7 +17,7 @@ import { TaskFrequency } from '../enums/task.frequency.enum';
|
|||||||
import { TaskSubmission } from './task-submissions.entity';
|
import { TaskSubmission } from './task-submissions.entity';
|
||||||
|
|
||||||
@Entity('tasks')
|
@Entity('tasks')
|
||||||
export class Task {
|
export class Task extends BaseEntity {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ export class Task {
|
|||||||
@JoinColumn({ name: 'assigned_by_id' })
|
@JoinColumn({ name: 'assigned_by_id' })
|
||||||
assignedBy!: Guardian;
|
assignedBy!: Guardian;
|
||||||
|
|
||||||
@OneToOne(() => TaskSubmission, (submission) => submission.task, { onDelete: 'CASCADE' })
|
@OneToOne(() => TaskSubmission, (submission) => submission.task, { cascade: true })
|
||||||
submission?: TaskSubmission;
|
submission?: TaskSubmission;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamp', name: 'created_at', default: () => 'CURRENT_TIMESTAMP' })
|
@CreateDateColumn({ type: 'timestamp', name: 'created_at', default: () => 'CURRENT_TIMESTAMP' })
|
||||||
|
@ -81,14 +81,13 @@ export class TaskRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createSubmission(task: Task, body: TaskSubmissionRequestDto) {
|
createSubmission(task: Task, body: TaskSubmissionRequestDto) {
|
||||||
task.submission = TaskSubmission.create({
|
const submission = task.submission || new TaskSubmission();
|
||||||
status: task.isProofRequired ? SubmissionStatus.PENDING : SubmissionStatus.APPROVED,
|
submission.status = SubmissionStatus.PENDING;
|
||||||
submittedAt: new Date(),
|
submission.submittedAt = new Date();
|
||||||
taskId: task.id,
|
submission.taskId = task.id;
|
||||||
proofOfCompletionId: body.imageId,
|
submission.proofOfCompletionId = body.imageId;
|
||||||
});
|
|
||||||
|
|
||||||
return task.submission.save();
|
return task.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
approveSubmission(submission: TaskSubmission) {
|
approveSubmission(submission: TaskSubmission) {
|
||||||
|
@ -34,10 +34,6 @@ export class TaskService {
|
|||||||
throw new BadRequestException('TASK.ALREADY_COMPLETED');
|
throw new BadRequestException('TASK.ALREADY_COMPLETED');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.submission && task.submission.status !== SubmissionStatus.REJECTED) {
|
|
||||||
throw new BadRequestException('TASK.ALREADY_SUBMITTED');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (task.isProofRequired && !body.imageId) {
|
if (task.isProofRequired && !body.imageId) {
|
||||||
throw new BadRequestException('TASK.PROOF_REQUIRED');
|
throw new BadRequestException('TASK.PROOF_REQUIRED');
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user