Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions drizzle/migrations/0001_add_payroll_drafts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CREATE TYPE "payroll_draft_status" AS ENUM('active', 'processed', 'cancelled');
--> statement-breakpoint
CREATE TABLE "payroll_drafts" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"organization_id" uuid NOT NULL,
"status" "payroll_draft_status" DEFAULT 'active' NOT NULL,
"employees_payload" jsonb DEFAULT '[]'::jsonb NOT NULL,
"total_amount" integer DEFAULT 0 NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "payroll_drafts" ADD CONSTRAINT "payroll_drafts_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
CREATE INDEX "payroll_drafts_organization_id_idx" ON "payroll_drafts" ("organization_id");
--> statement-breakpoint
CREATE INDEX "payroll_drafts_status_idx" ON "payroll_drafts" ("status");
9 changes: 8 additions & 1 deletion drizzle/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"when": 1776872929566,
"tag": "0000_perfect_ravenous",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1777132800000,
"tag": "0001_add_payroll_drafts",
"breakpoints": true
}
]
}
}
11 changes: 3 additions & 8 deletions src/app/api/v1/auth/2fa/verify/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import { eq } from "drizzle-orm";
*/
export async function POST(req: NextRequest) {
try {

const body = await req.json();
const validatedData = VerifyTwoFactorSchema.parse(body);

Expand Down Expand Up @@ -77,9 +76,9 @@ export async function POST(req: NextRequest) {
return ApiResponse.error("User not found", 404);
}

const accessToken = AuthUtils.generateToken(user.id, user.email);
const accessToken = await AuthUtils.generateToken(user.id, user.email);

const refreshToken = AuthUtils.generateToken(user.id, user.email);
const refreshToken = await AuthUtils.generateToken(user.id, user.email);

return ApiResponse.success(
{
Expand All @@ -99,9 +98,7 @@ export async function POST(req: NextRequest) {
200,
);
} catch (error) {

if (error instanceof AppError) {

if (error.statusCode === 403 || error.statusCode === 429) {
try {
const body = await req.clone().json();
Expand All @@ -128,9 +125,7 @@ export async function POST(req: NextRequest) {
}
}
}
} catch {

}
} catch {}
}

return ApiResponse.error(error.message, error.statusCode, error.errors);
Expand Down
30 changes: 21 additions & 9 deletions src/app/api/v1/kyb/submit/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { NextRequest } from "next/server";
import { ApiResponse } from "@/server/utils/api-response";
import { AppError, ValidationError } from "@/server/utils/errors";
import { AuthUtils } from "@/server/utils/auth";
import { KybSubmitSchema, KYB_FILE_CONSTRAINTS } from "@/server/validations/kyb.schema";
import {
KybSubmitSchema,
KYB_FILE_CONSTRAINTS,
} from "@/server/validations/kyb.schema";
import { KybService } from "@/server/services/kyb.service";
import { KybUploadService } from "@/server/services/kyb-upload.service";
import { ZodError } from "zod";
Expand Down Expand Up @@ -72,13 +75,13 @@ export const POST = withKybRateLimit(async (req: NextRequest) => {
});

if (!incorporationCertificatePath) {
throw new ValidationError("Incorporation certificate path is required", {
throw new ValidationError("Validation failed", {
fieldErrors: { incorporationCertificatePath: "Path is required" },
});
}

if (!memorandumArticlePath) {
throw new ValidationError("Memorandum & Article of Association path is required", {
throw new ValidationError("Validation failed", {
fieldErrors: { memorandumArticlePath: "Path is required" },
});
}
Expand All @@ -88,16 +91,25 @@ export const POST = withKybRateLimit(async (req: NextRequest) => {
registrationType: validatedFields.registrationType,
registrationNo: validatedFields.registrationNo,
incorporationCertificatePath: incorporationCertificatePath,
incorporationCertificateUrl: KybUploadService.getPublicUrl(incorporationCertificatePath),
incorporationCertificateUrl: KybUploadService.getPublicUrl(
incorporationCertificatePath,
),
memorandumArticlePath: memorandumArticlePath,
memorandumArticleUrl: KybUploadService.getPublicUrl(memorandumArticlePath),
memorandumArticleUrl: KybUploadService.getPublicUrl(
memorandumArticlePath,
),
formC02C07Path: formC02C07Path ?? null,
formC02C07Url: formC02C07Path ? KybUploadService.getPublicUrl(formC02C07Path) : null,
formC02C07Url: formC02C07Path
? KybUploadService.getPublicUrl(formC02C07Path)
: null,
});

return ApiResponse.success(result, "KYB documents submitted successfully", 201);
return ApiResponse.success(
result,
"KYB documents submitted successfully",
201,
);
} catch (error) {

if (error instanceof ZodError) {
const fieldErrors: Record<string, string> = {};
error.issues.forEach((issue: any) => {
Expand All @@ -114,5 +126,5 @@ export const POST = withKybRateLimit(async (req: NextRequest) => {

console.error("[KYB Submit Error]", error);
return ApiResponse.error("Internal server error", 500);
}
}
});
Loading
Loading