added other modules and forms

This commit is contained in:
2026-05-27 23:04:01 +03:30
parent df1dda764c
commit 6673edbfc3
9 changed files with 418 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
// src/modules/job-info/controller/job-info.controller.ts
import { Request, Response, NextFunction } from "express";
import { JobInfoPayload } from "../types/index.type";
import { Controller } from "../../../../core/controller/main.controller";
import JobInfoService from "../service/jobInfo.service";
class JobInfoControllerClass extends Controller {
#service;
constructor(){
super();
this.#service = JobInfoService
}
async upsert(req: any, res: Response, next: NextFunction) {
try {
const applicantId = req.user.id;
const data = await this.#service.upsert(applicantId, req.body);
return res.status(200).json({
status: 200,
message: "اطلاعات وضعیت شغلی با موفقیت ذخیره شد",
data,
});
} catch (error) {
next(error);
}
}
async getMy(req: any, res: Response, next: NextFunction) {
try {
const applicantId = req.user.id;
const data = await this.#service.getMy(applicantId);
return res.status(200).json({
status: 200,
data,
});
} catch (error) {
next(error);
}
}
async getByApplicantId(req: any, res: Response, next: NextFunction) {
try {
const { applicantId } = req.params;
const data = await this.#service.getByApplicantId(applicantId);
return res.status(200).json({
status: 200,
data,
});
} catch (error) {
next(error);
}
}
async delete(req: any, res: Response, next: NextFunction) {
try {
const applicantId = req.user.id;
await this.#service.delete(applicantId);
return res.status(200).json({
status: 200,
message: "اطلاعات وضعیت شغلی با موفقیت حذف شد",
});
} catch (error) {
next(error);
}
}
}
const JobInfoController = new JobInfoControllerClass()
export default JobInfoController;

View File

@@ -0,0 +1,56 @@
import { JobInfo } from "../../../../models/JobInfo";
import { JobInfoPayload } from "../types/index.type";
class JobInfoServiceClass {
async upsert(applicantId: string, payload: JobInfoPayload) {
const existing = await JobInfo.findOne({where: {applicantId}});
const data = {
applicantId,
readyToWorkDate: payload.readyToWorkDate,
isCurrentEmployee: payload.isCurrentEmployee ?? false,
hasPastCooperation: payload.hasPastCooperation ?? false,
isCurrentlyEmployed: payload.isCurrentlyEmployed ?? false,
dualJobInterest: payload.dualJobInterest ?? false,
retirementStatus: payload.retirementStatus ?? "None",
isMilitary: payload.isMilitary ?? false,
hasInsurance: payload.hasInsurance ?? false,
insuranceType: payload.hasInsurance
? (payload.insuranceType ?? null)
: null,
totalInsuranceYears: payload.hasInsurance
? (payload.totalInsuranceYears ?? 0)
: 0,
};
if (existing) {
await existing.update(data);
return existing;
}
return await JobInfo.create(data as any);
}
async getMy(applicantId: string) {
return await JobInfo.findOne({where: {applicantId}});
}
async getByApplicantId(applicantId: string) {
return await JobInfo.findOne({where: {applicantId}});
}
async delete(applicantId: string) {
const record = await JobInfo.findOne({where: {applicantId}});
if (!record) {
throw new Error("اطلاعات وضعیت شغلی یافت نشد");
}
await record.destroy();
return true;
}
}
const JobInfoService = new JobInfoServiceClass();
export default JobInfoService;

View File

@@ -0,0 +1,13 @@
export interface JobInfoPayload {
applicantId?: string; // از کلاینت نادیده گرفته می‌شود
readyToWorkDate: string; // چون از req.body می‌آید بهتر است string باشد
isCurrentEmployee?: boolean;
hasPastCooperation?: boolean;
isCurrentlyEmployed?: boolean;
dualJobInterest?: boolean;
retirementStatus?: "None" | "Retired" | "Redeemed";
isMilitary?: boolean;
hasInsurance?: boolean;
insuranceType?: string | null;
totalInsuranceYears?: number;
}

View File

@@ -0,0 +1,83 @@
import {NextFunction} from "express";
import PermissionService from "../service/permission.service";
import {Controller} from "../../../core/controller/main.controller";
import {ServerResponse} from "../../../core/types";
class PermissionController extends Controller {
#service;
constructor() {
super();
this.#service = PermissionService;
}
async create(req: any, res: ServerResponse, next: NextFunction) {
try {
const data = await PermissionService.create(req.body);
return res.status(201).json({
status: 201,
message: "سطح دسترسی با موفقیت ایجاد شد",
data,
});
} catch (error) {
next(error);
}
}
async getAll(req: any, res: ServerResponse, next: NextFunction) {
try {
const data = await this.#service.getAll();
return res.status(200).json({
status: 200,
data,
});
} catch (error) {
next(error);
}
}
async getById(req: any, res: ServerResponse, next: NextFunction) {
try {
const {id} = req.params;
const data = await this.#service.getById(id);
return res.status(200).json({
status: 200,
data,
});
} catch (error) {
next(error);
}
}
async update(req: any, res: ServerResponse, next: NextFunction) {
try {
const {id} = req.params;
const data = await this.#service.update(id, req.body);
return res.status(200).json({
status: 200,
message: "سطح دسترسی با موفقیت بروزرسانی شد",
data,
});
} catch (error) {
next(error);
}
}
async delete(req: any, res: ServerResponse, next: NextFunction) {
try {
const {id} = req.params;
const data = await this.#service.delete(id);
return res.status(200).json({
status: 200,
data: {...data},
});
} catch (error) {
next(error);
}
}
}
export default new PermissionController();

View File

@@ -0,0 +1,75 @@
import { Permission } from "../../../models/Permission";
interface CreatePermissionDto {
name: string;
}
interface UpdatePermissionDto {
name?: string;
}
class PermissionService {
async create(data: CreatePermissionDto) {
const existingPermission = await Permission.findOne({
where: { name: data.name },
});
if (existingPermission) {
throw new Error("سطح دسترسی با این نام قبلاً ثبت شده است");
}
const permission = await Permission.create({
name: data.name,
});
return permission;
}
async getAll() {
return await Permission.findAll({
order: [["createdAt", "DESC"]],
});
}
async getById(id: string) {
const permission = await Permission.findByPk(id);
if (!permission) {
throw new Error("سطح دسترسی مورد نظر یافت نشد");
}
return permission;
}
async update(id: string, data: UpdatePermissionDto) {
const permission = await this.getById(id);
if (data.name && data.name !== permission.name) {
const existingPermission = await Permission.findOne({
where: { name: data.name },
});
if (existingPermission) {
throw new Error("سطح دسترسی با این نام قبلاً ثبت شده است");
}
}
await permission.update({
name: data.name ?? permission.name,
});
return permission;
}
async delete(id: string) {
const permission = await this.getById(id);
await permission.destroy();
return {
message: "سطح دسترسی با موفقیت حذف شد",
};
}
}
export default new PermissionService();

View File

@@ -0,0 +1,66 @@
// src/modules/role/controller/role.controller.ts
import {NextFunction} from "express";
import RoleService from "../service/role.service";
import {Controller} from "../../../core/controller/main.controller";
import {ServerResponse} from "../../../core/types";
class RoleControllerClass extends Controller {
#service;
constructor() {
super();
this.#service = RoleService;
}
async create(req: any, res: ServerResponse, next: NextFunction) {
try {
const data = await this.#service.create(req.body);
res
.status(201)
.json({status: 201, message: "نقش با موفقیت ایجاد شد", data});
} catch (error) {
next(error);
}
}
async getAll(req: any, res: ServerResponse, next: NextFunction) {
try {
const data = await this.#service.getAll();
res.status(200).json({status: 200, data});
} catch (error) {
next(error);
}
}
async getById(req: any, res: ServerResponse, next: NextFunction) {
try {
const data = await this.#service.getById(req.params.id);
res.status(200).json({status: 200, data});
} catch (error) {
next(error);
}
}
async update(req: any, res: ServerResponse, next: NextFunction) {
try {
const data = await this.#service.update(req.params.id, req.body);
res
.status(200)
.json({status: 200, message: "نقش با موفقیت بروزرسانی شد", data});
} catch (error) {
next(error);
}
}
async delete(req: any, res: ServerResponse, next: NextFunction) {
try {
const id = req?.params?.id;
await this.#service.delete(id);
res.status(200).json({status: 200,data:{}, message: "نقش با موفقیت حذف شد"});
} catch (error) {
next(error);
}
}
}
const RoleController = new RoleControllerClass();
export default RoleController;

View File

@@ -0,0 +1,14 @@
// src/modules/role/role.routes.ts
import {Router} from "express";
import RoleController from "../controller/role.controller";
const roleRouter = Router();
// پیشنهاد می‌شود این مسیرها فقط برای ادمین در دسترس باشند
roleRouter.post("/", RoleController.create);
roleRouter.get("/", RoleController.getAll);
roleRouter.get("/:id", RoleController.getById);
roleRouter.put("/:id", RoleController.update);
roleRouter.delete("/:id", RoleController.delete);
export default roleRouter;

View File

@@ -0,0 +1,35 @@
import {Role} from "../../../models/Role";
class RoleServiceClass {
async create(data: {name: string; description?: string}) {
return await Role.create(data);
}
async getAll() {
return await Role.findAll({order: [["createdAt", "DESC"]]});
}
async getById(id: string) {
const role = await Role.findByPk(id);
if (!role) throw new Error("نقش مورد نظر یافت نشد");
return role;
}
async update(id: string, data: {name?: string; description?: string}) {
const role = await this.getById(id);
return await role.update(data);
}
async delete(id: string) {
const role = await this.getById(id);
await role.destroy();
return true;
}
// متد کمکی برای چک کردن وجود نقش (مثلاً در زمان ثبت‌نام)
async getByName(name: string) {
return await Role.findOne({where: {name}});
}
}
const RoleService = new RoleServiceClass();
export default RoleService;