archetecture security fix
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
export declare function presentCustomer(customer: any): any;
|
||||
export declare function presentCustomerList(customers: any[], meta: {
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
}): {
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
data: any[];
|
||||
};
|
||||
//# sourceMappingURL=customer.presenter.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.presenter.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/customer.presenter.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,CAAC,QAAQ,EAAE,GAAG,OAO5C;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;WAA5D,MAAM;UAAQ,MAAM;cAAY,MAAM;gBAAc,MAAM;;EAE9H"}
|
||||
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.presentCustomer = presentCustomer;
|
||||
exports.presentCustomerList = presentCustomerList;
|
||||
const storage_1 = require("../../lib/storage");
|
||||
function presentCustomer(customer) {
|
||||
return {
|
||||
...customer,
|
||||
licenseImageUrl: customer?.licenseImageUrl
|
||||
? (0, storage_1.getProtectedCustomerLicenseImageUrl)(customer.id)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
function presentCustomerList(customers, meta) {
|
||||
return { data: customers, ...meta };
|
||||
}
|
||||
//# sourceMappingURL=customer.presenter.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.presenter.js","sourceRoot":"","sources":["../../../src/modules/customers/customer.presenter.ts"],"names":[],"mappings":";;AAEA,0CAOC;AAED,kDAEC;AAbD,+CAAuE;AAEvE,SAAgB,eAAe,CAAC,QAAa;IAC3C,OAAO;QACL,GAAG,QAAQ;QACX,eAAe,EAAE,QAAQ,EAAE,eAAe;YACxC,CAAC,CAAC,IAAA,6CAAmC,EAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,CAAC,CAAC,IAAI;KACT,CAAA;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,SAAgB,EAAE,IAA2E;IAC/H,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,CAAA;AACrC,CAAC"}
|
||||
@@ -0,0 +1,8 @@
|
||||
export declare function findMany(where: any, skip: number, take: number): Promise<any>;
|
||||
export declare function findById(id: string, companyId: string): Promise<any>;
|
||||
export declare function findByIdSimple(id: string, companyId: string): Promise<any>;
|
||||
export declare function create(data: any): Promise<any>;
|
||||
export declare function updateMany(id: string, companyId: string, data: any): Promise<any>;
|
||||
export declare function updateById(id: string, data: any): Promise<any>;
|
||||
export declare function findUniqueOrThrow(id: string, companyId?: string): Promise<any>;
|
||||
//# sourceMappingURL=customer.repo.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.repo.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/customer.repo.ts"],"names":[],"mappings":"AA+DA,wBAAsB,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,gBAMpE;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAS3D;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAEjE;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,GAAG,gBAErC;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,gBAExE;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,gBAMrD;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,gBAMrE"}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.findMany = findMany;
|
||||
exports.findById = findById;
|
||||
exports.findByIdSimple = findByIdSimple;
|
||||
exports.create = create;
|
||||
exports.updateMany = updateMany;
|
||||
exports.updateById = updateById;
|
||||
exports.findUniqueOrThrow = findUniqueOrThrow;
|
||||
const prisma_1 = require("../../lib/prisma");
|
||||
let customerLicenseImageColumnSupported = null;
|
||||
async function hasCustomerLicenseImageColumn() {
|
||||
if (customerLicenseImageColumnSupported !== null) {
|
||||
return customerLicenseImageColumnSupported;
|
||||
}
|
||||
const rows = await prisma_1.prisma.$queryRawUnsafe("select exists(select 1 from information_schema.columns where table_schema = 'public' and table_name = 'customers' and column_name = 'licenseImageUrl') as exists");
|
||||
customerLicenseImageColumnSupported = Boolean(rows[0]?.exists);
|
||||
return customerLicenseImageColumnSupported;
|
||||
}
|
||||
function buildCustomerSelect(includeLicenseImageUrl) {
|
||||
return {
|
||||
id: true,
|
||||
companyId: true,
|
||||
renterId: true,
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
email: true,
|
||||
phone: true,
|
||||
driverLicense: true,
|
||||
dateOfBirth: true,
|
||||
nationality: true,
|
||||
address: true,
|
||||
notes: true,
|
||||
flagged: true,
|
||||
flagReason: true,
|
||||
licenseExpiry: true,
|
||||
licenseIssuedAt: true,
|
||||
licenseCountry: true,
|
||||
licenseNumber: true,
|
||||
licenseCategory: true,
|
||||
licenseExpired: true,
|
||||
licenseExpiringSoon: true,
|
||||
licenseValidationStatus: true,
|
||||
licenseApprovedBy: true,
|
||||
licenseApprovedAt: true,
|
||||
licenseApprovalNote: true,
|
||||
...(includeLicenseImageUrl ? { licenseImageUrl: true } : {}),
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
};
|
||||
}
|
||||
async function getCustomerSelect() {
|
||||
return buildCustomerSelect(await hasCustomerLicenseImageColumn());
|
||||
}
|
||||
async function sanitizeCustomerData(data) {
|
||||
if (await hasCustomerLicenseImageColumn()) {
|
||||
return data;
|
||||
}
|
||||
const { licenseImageUrl, ...rest } = data;
|
||||
void licenseImageUrl;
|
||||
return rest;
|
||||
}
|
||||
async function findMany(where, skip, take) {
|
||||
const select = await getCustomerSelect();
|
||||
return Promise.all([
|
||||
prisma_1.prisma.customer.findMany({ where, skip, take, orderBy: { createdAt: 'desc' }, select }),
|
||||
prisma_1.prisma.customer.count({ where }),
|
||||
]);
|
||||
}
|
||||
async function findById(id, companyId) {
|
||||
const select = await getCustomerSelect();
|
||||
return prisma_1.prisma.customer.findFirst({
|
||||
where: { id, companyId },
|
||||
select: {
|
||||
...select,
|
||||
reservations: { include: { vehicle: true }, orderBy: { createdAt: 'desc' }, take: 20 },
|
||||
},
|
||||
});
|
||||
}
|
||||
async function findByIdSimple(id, companyId) {
|
||||
return prisma_1.prisma.customer.findFirst({ where: { id, companyId }, select: await getCustomerSelect() });
|
||||
}
|
||||
async function create(data) {
|
||||
return prisma_1.prisma.customer.create({ data: (await sanitizeCustomerData(data)), select: await getCustomerSelect() });
|
||||
}
|
||||
async function updateMany(id, companyId, data) {
|
||||
return prisma_1.prisma.customer.updateMany({ where: { id, companyId }, data });
|
||||
}
|
||||
async function updateById(id, data) {
|
||||
return prisma_1.prisma.customer.update({
|
||||
where: { id },
|
||||
data: (await sanitizeCustomerData(data)),
|
||||
select: await getCustomerSelect(),
|
||||
});
|
||||
}
|
||||
async function findUniqueOrThrow(id, companyId) {
|
||||
const select = await getCustomerSelect();
|
||||
if (companyId) {
|
||||
return prisma_1.prisma.customer.findFirstOrThrow({ where: { id, companyId }, select });
|
||||
}
|
||||
return prisma_1.prisma.customer.findUniqueOrThrow({ where: { id }, select });
|
||||
}
|
||||
//# sourceMappingURL=customer.repo.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.repo.js","sourceRoot":"","sources":["../../../src/modules/customers/customer.repo.ts"],"names":[],"mappings":"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"}
|
||||
@@ -0,0 +1,3 @@
|
||||
declare const router: import("express-serve-static-core").Router;
|
||||
export default router;
|
||||
//# sourceMappingURL=customer.routes.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/customer.routes.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,4CAAW,CAAA;AAwFvB,eAAe,MAAM,CAAA"}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const express_1 = require("express");
|
||||
const requireCompanyAuth_1 = require("../../middleware/requireCompanyAuth");
|
||||
const requireTenant_1 = require("../../middleware/requireTenant");
|
||||
const requireSubscription_1 = require("../../middleware/requireSubscription");
|
||||
const requireRole_1 = require("../../middleware/requireRole");
|
||||
const validate_1 = require("../../http/validate");
|
||||
const respond_1 = require("../../http/respond");
|
||||
const upload_1 = require("../../http/upload");
|
||||
const service = __importStar(require("./customer.service"));
|
||||
const customer_schemas_1 = require("./customer.schemas");
|
||||
const router = (0, express_1.Router)();
|
||||
router.get('/:id/license-image', requireCompanyAuth_1.requireCompanyDocumentAuth, requireTenant_1.requireTenant, requireSubscription_1.requireSubscription, async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const filePath = await service.getLicenseImageFile(id, req.companyId);
|
||||
res.sendFile(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.use(requireCompanyAuth_1.requireCompanyAuth, requireTenant_1.requireTenant, requireSubscription_1.requireSubscription);
|
||||
router.get('/', async (req, res, next) => {
|
||||
try {
|
||||
const query = (0, validate_1.parseQuery)(customer_schemas_1.listQuerySchema, req);
|
||||
const result = await service.listCustomers(req.companyId, query);
|
||||
res.json(result);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.post('/', async (req, res, next) => {
|
||||
try {
|
||||
const body = (0, validate_1.parseBody)(customer_schemas_1.customerSchema, req);
|
||||
const customer = await service.createCustomer(body, req.companyId);
|
||||
(0, respond_1.created)(res, customer);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.get('/:id', async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const customer = await service.getCustomer(id, req.companyId);
|
||||
(0, respond_1.ok)(res, customer);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.patch('/:id', (0, requireRole_1.requireRole)('MANAGER'), async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const body = (0, validate_1.parseBody)(customer_schemas_1.customerSchema.partial(), req);
|
||||
const customer = await service.updateCustomer(id, req.companyId, body);
|
||||
(0, respond_1.ok)(res, customer);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.post('/:id/flag', (0, requireRole_1.requireRole)('MANAGER'), async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const { reason } = (0, validate_1.parseBody)(customer_schemas_1.flagSchema, req);
|
||||
await service.flagCustomer(id, req.companyId, reason);
|
||||
(0, respond_1.ok)(res, { success: true });
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.delete('/:id/flag', (0, requireRole_1.requireRole)('MANAGER'), async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
await service.unflagCustomer(id, req.companyId);
|
||||
(0, respond_1.ok)(res, { success: true });
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.post('/:id/validate-license', async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const result = await service.validateCustomerLicense(id, req.companyId);
|
||||
(0, respond_1.ok)(res, result);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.post('/:id/license-image', upload_1.imageUpload.single('file'), async (req, res, next) => {
|
||||
try {
|
||||
(0, upload_1.assertImageFile)(req.file, 'license image');
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const updated = await service.uploadLicenseImage(id, req.companyId, req.file);
|
||||
(0, respond_1.ok)(res, updated);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
router.post('/:id/approve-license', (0, requireRole_1.requireRole)('MANAGER'), async (req, res, next) => {
|
||||
try {
|
||||
const { id } = (0, validate_1.parseParams)(customer_schemas_1.idParamSchema, req);
|
||||
const { decision, note } = (0, validate_1.parseBody)(customer_schemas_1.approveLicenseSchema, req);
|
||||
const approverName = `${req.employee.firstName} ${req.employee.lastName}`;
|
||||
const updated = await service.approveLicense(id, req.companyId, decision, note, approverName);
|
||||
(0, respond_1.ok)(res, updated);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
exports.default = router;
|
||||
//# sourceMappingURL=customer.routes.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,99 @@
|
||||
import { z } from 'zod';
|
||||
export declare const paginationSchema: z.ZodObject<{
|
||||
page: z.ZodDefault<z.ZodNumber>;
|
||||
pageSize: z.ZodDefault<z.ZodNumber>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}, {
|
||||
page?: number | undefined;
|
||||
pageSize?: number | undefined;
|
||||
}>;
|
||||
export declare const customerSchema: z.ZodObject<{
|
||||
firstName: z.ZodString;
|
||||
lastName: z.ZodString;
|
||||
email: z.ZodString;
|
||||
phone: z.ZodOptional<z.ZodString>;
|
||||
driverLicense: z.ZodOptional<z.ZodString>;
|
||||
dateOfBirth: z.ZodOptional<z.ZodString>;
|
||||
nationality: z.ZodOptional<z.ZodString>;
|
||||
address: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
||||
notes: z.ZodOptional<z.ZodString>;
|
||||
licenseExpiry: z.ZodOptional<z.ZodString>;
|
||||
licenseIssuedAt: z.ZodOptional<z.ZodString>;
|
||||
licenseCountry: z.ZodOptional<z.ZodString>;
|
||||
licenseNumber: z.ZodOptional<z.ZodString>;
|
||||
licenseCategory: z.ZodOptional<z.ZodString>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
notes?: string | undefined;
|
||||
phone?: string | undefined;
|
||||
driverLicense?: string | undefined;
|
||||
licenseExpiry?: string | undefined;
|
||||
licenseIssuedAt?: string | undefined;
|
||||
dateOfBirth?: string | undefined;
|
||||
nationality?: string | undefined;
|
||||
address?: Record<string, unknown> | undefined;
|
||||
licenseCountry?: string | undefined;
|
||||
licenseNumber?: string | undefined;
|
||||
licenseCategory?: string | undefined;
|
||||
}, {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
notes?: string | undefined;
|
||||
phone?: string | undefined;
|
||||
driverLicense?: string | undefined;
|
||||
licenseExpiry?: string | undefined;
|
||||
licenseIssuedAt?: string | undefined;
|
||||
dateOfBirth?: string | undefined;
|
||||
nationality?: string | undefined;
|
||||
address?: Record<string, unknown> | undefined;
|
||||
licenseCountry?: string | undefined;
|
||||
licenseNumber?: string | undefined;
|
||||
licenseCategory?: string | undefined;
|
||||
}>;
|
||||
export declare const listQuerySchema: z.ZodObject<{
|
||||
page: z.ZodDefault<z.ZodNumber>;
|
||||
pageSize: z.ZodDefault<z.ZodNumber>;
|
||||
} & {
|
||||
q: z.ZodOptional<z.ZodString>;
|
||||
flagged: z.ZodOptional<z.ZodEnum<["true", "false"]>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
q?: string | undefined;
|
||||
flagged?: "true" | "false" | undefined;
|
||||
}, {
|
||||
page?: number | undefined;
|
||||
pageSize?: number | undefined;
|
||||
q?: string | undefined;
|
||||
flagged?: "true" | "false" | undefined;
|
||||
}>;
|
||||
export declare const approveLicenseSchema: z.ZodObject<{
|
||||
decision: z.ZodEnum<["APPROVE", "DENY"]>;
|
||||
note: z.ZodOptional<z.ZodString>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
decision: "APPROVE" | "DENY";
|
||||
note?: string | undefined;
|
||||
}, {
|
||||
decision: "APPROVE" | "DENY";
|
||||
note?: string | undefined;
|
||||
}>;
|
||||
export declare const flagSchema: z.ZodObject<{
|
||||
reason: z.ZodOptional<z.ZodString>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
reason?: string | undefined;
|
||||
}, {
|
||||
reason?: string | undefined;
|
||||
}>;
|
||||
export declare const idParamSchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
id: string;
|
||||
}, {
|
||||
id: string;
|
||||
}>;
|
||||
//# sourceMappingURL=customer.schemas.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/customer.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,gBAAgB;;;;;;;;;EAG3B,CAAA;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAezB,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;EAG1B,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;EAG/B,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;EAErB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;EAA+B,CAAA"}
|
||||
@@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.idParamSchema = exports.flagSchema = exports.approveLicenseSchema = exports.listQuerySchema = exports.customerSchema = exports.paginationSchema = void 0;
|
||||
const zod_1 = require("zod");
|
||||
exports.paginationSchema = zod_1.z.object({
|
||||
page: zod_1.z.coerce.number().int().min(1).max(10000).default(1),
|
||||
pageSize: zod_1.z.coerce.number().int().min(1).max(100).default(20),
|
||||
});
|
||||
exports.customerSchema = zod_1.z.object({
|
||||
firstName: zod_1.z.string().min(1).max(100).trim(),
|
||||
lastName: zod_1.z.string().min(1).max(100).trim(),
|
||||
email: zod_1.z.string().email().max(255).trim().toLowerCase(),
|
||||
phone: zod_1.z.string().max(30).trim().optional(),
|
||||
driverLicense: zod_1.z.string().max(50).trim().optional(),
|
||||
dateOfBirth: zod_1.z.string().datetime().optional(),
|
||||
nationality: zod_1.z.string().max(100).trim().optional(),
|
||||
address: zod_1.z.record(zod_1.z.unknown()).optional(),
|
||||
notes: zod_1.z.string().max(2000).trim().optional(),
|
||||
licenseExpiry: zod_1.z.string().datetime().optional(),
|
||||
licenseIssuedAt: zod_1.z.string().datetime().optional(),
|
||||
licenseCountry: zod_1.z.string().max(100).trim().optional(),
|
||||
licenseNumber: zod_1.z.string().max(50).trim().optional(),
|
||||
licenseCategory: zod_1.z.string().max(20).trim().optional(),
|
||||
});
|
||||
exports.listQuerySchema = exports.paginationSchema.extend({
|
||||
q: zod_1.z.string().max(100).optional(),
|
||||
flagged: zod_1.z.enum(['true', 'false']).optional(),
|
||||
});
|
||||
exports.approveLicenseSchema = zod_1.z.object({
|
||||
decision: zod_1.z.enum(['APPROVE', 'DENY']),
|
||||
note: zod_1.z.string().optional(),
|
||||
});
|
||||
exports.flagSchema = zod_1.z.object({
|
||||
reason: zod_1.z.string().optional(),
|
||||
});
|
||||
exports.idParamSchema = zod_1.z.object({ id: zod_1.z.string() });
|
||||
//# sourceMappingURL=customer.schemas.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.schemas.js","sourceRoot":"","sources":["../../../src/modules/customers/customer.schemas.ts"],"names":[],"mappings":"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"}
|
||||
@@ -0,0 +1,22 @@
|
||||
export declare function listCustomers(companyId: string, query: {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
q?: string;
|
||||
flagged?: string;
|
||||
}): Promise<{
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
data: any[];
|
||||
}>;
|
||||
export declare function getCustomer(id: string, companyId: string): Promise<any>;
|
||||
export declare function createCustomer(data: any, companyId: string): Promise<any>;
|
||||
export declare function updateCustomer(id: string, companyId: string, data: any): Promise<any>;
|
||||
export declare function flagCustomer(id: string, companyId: string, reason?: string): Promise<void>;
|
||||
export declare function unflagCustomer(id: string, companyId: string): Promise<void>;
|
||||
export declare function validateCustomerLicense(id: string, companyId: string): Promise<import("../../services/licenseValidationService").LicenseValidationResult>;
|
||||
export declare function uploadLicenseImage(id: string, companyId: string, file: Express.Multer.File): Promise<any>;
|
||||
export declare function getLicenseImageFile(id: string, companyId: string): Promise<string>;
|
||||
export declare function approveLicense(id: string, companyId: string, decision: 'APPROVE' | 'DENY', note: string | undefined, approverName: string): Promise<any>;
|
||||
//# sourceMappingURL=customer.service.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.service.d.ts","sourceRoot":"","sources":["../../../src/modules/customers/customer.service.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;GAgB/H;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAI9D;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,gBAYhE;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,gBAU5E;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,iBAEhF;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAEjE;AAED,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,sFAI1E;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,gBAQhG;AAED,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAQtE;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,gBAS/I"}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.listCustomers = listCustomers;
|
||||
exports.getCustomer = getCustomer;
|
||||
exports.createCustomer = createCustomer;
|
||||
exports.updateCustomer = updateCustomer;
|
||||
exports.flagCustomer = flagCustomer;
|
||||
exports.unflagCustomer = unflagCustomer;
|
||||
exports.validateCustomerLicense = validateCustomerLicense;
|
||||
exports.uploadLicenseImage = uploadLicenseImage;
|
||||
exports.getLicenseImageFile = getLicenseImageFile;
|
||||
exports.approveLicense = approveLicense;
|
||||
const licenseValidationService_1 = require("../../services/licenseValidationService");
|
||||
const storage_1 = require("../../lib/storage");
|
||||
const errors_1 = require("../../http/errors");
|
||||
const customer_presenter_1 = require("./customer.presenter");
|
||||
const repo = __importStar(require("./customer.repo"));
|
||||
async function listCustomers(companyId, query) {
|
||||
const page = query.page ?? 1;
|
||||
const pageSize = query.pageSize ?? 20;
|
||||
const { q, flagged } = query;
|
||||
const safeQ = q ? q.trim().slice(0, 100) : undefined;
|
||||
const where = { companyId };
|
||||
if (flagged !== undefined)
|
||||
where.flagged = flagged === 'true';
|
||||
if (safeQ) {
|
||||
where.OR = [
|
||||
{ firstName: { contains: safeQ, mode: 'insensitive' } },
|
||||
{ lastName: { contains: safeQ, mode: 'insensitive' } },
|
||||
{ email: { contains: safeQ, mode: 'insensitive' } },
|
||||
];
|
||||
}
|
||||
const [customers, total] = await repo.findMany(where, (page - 1) * pageSize, pageSize);
|
||||
return (0, customer_presenter_1.presentCustomerList)(customers.map(customer_presenter_1.presentCustomer), { total, page, pageSize, totalPages: Math.ceil(total / pageSize) });
|
||||
}
|
||||
async function getCustomer(id, companyId) {
|
||||
const customer = await repo.findById(id, companyId);
|
||||
if (!customer)
|
||||
throw new errors_1.NotFoundError('Customer not found');
|
||||
return (0, customer_presenter_1.presentCustomer)(customer);
|
||||
}
|
||||
async function createCustomer(data, companyId) {
|
||||
const customer = await repo.create({
|
||||
...data,
|
||||
companyId,
|
||||
dateOfBirth: data.dateOfBirth ? new Date(data.dateOfBirth) : null,
|
||||
licenseExpiry: data.licenseExpiry ? new Date(data.licenseExpiry) : null,
|
||||
licenseIssuedAt: data.licenseIssuedAt ? new Date(data.licenseIssuedAt) : null,
|
||||
});
|
||||
if (data.licenseExpiry) {
|
||||
await (0, licenseValidationService_1.validateAndFlagLicense)(customer.id, companyId).catch(() => null);
|
||||
}
|
||||
return (0, customer_presenter_1.presentCustomer)(customer);
|
||||
}
|
||||
async function updateCustomer(id, companyId, data) {
|
||||
const result = await repo.updateMany(id, companyId, {
|
||||
...data,
|
||||
dateOfBirth: data.dateOfBirth ? new Date(data.dateOfBirth) : undefined,
|
||||
licenseExpiry: data.licenseExpiry ? new Date(data.licenseExpiry) : undefined,
|
||||
licenseIssuedAt: data.licenseIssuedAt ? new Date(data.licenseIssuedAt) : undefined,
|
||||
});
|
||||
if (result.count === 0)
|
||||
throw new errors_1.NotFoundError('Customer not found');
|
||||
if (data.licenseExpiry)
|
||||
await (0, licenseValidationService_1.validateAndFlagLicense)(id, companyId).catch(() => null);
|
||||
return (0, customer_presenter_1.presentCustomer)(await repo.findUniqueOrThrow(id, companyId));
|
||||
}
|
||||
async function flagCustomer(id, companyId, reason) {
|
||||
await repo.updateMany(id, companyId, { flagged: true, flagReason: reason ?? null });
|
||||
}
|
||||
async function unflagCustomer(id, companyId) {
|
||||
await repo.updateMany(id, companyId, { flagged: false, flagReason: null });
|
||||
}
|
||||
async function validateCustomerLicense(id, companyId) {
|
||||
const customer = await repo.findByIdSimple(id, companyId);
|
||||
if (!customer)
|
||||
throw new errors_1.NotFoundError('Customer not found');
|
||||
return (0, licenseValidationService_1.validateAndFlagLicense)(customer.id, companyId);
|
||||
}
|
||||
async function uploadLicenseImage(id, companyId, file) {
|
||||
const customer = await repo.findByIdSimple(id, companyId);
|
||||
if (!customer)
|
||||
throw new errors_1.NotFoundError('Customer not found');
|
||||
const url = await (0, storage_1.uploadImage)(file.buffer, `companies/${companyId}/customers/${customer.id}`);
|
||||
if (customer.licenseImageUrl) {
|
||||
await (0, storage_1.deleteImage)(customer.licenseImageUrl).catch(() => null);
|
||||
}
|
||||
return (0, customer_presenter_1.presentCustomer)(await repo.updateById(customer.id, { licenseImageUrl: url }));
|
||||
}
|
||||
async function getLicenseImageFile(id, companyId) {
|
||||
const customer = await repo.findByIdSimple(id, companyId);
|
||||
if (!customer || !customer.licenseImageUrl)
|
||||
throw new errors_1.NotFoundError('License image not found');
|
||||
const filePath = (0, storage_1.resolveStoredFilePath)(customer.licenseImageUrl);
|
||||
if (!filePath)
|
||||
throw new errors_1.NotFoundError('License image not found');
|
||||
return filePath;
|
||||
}
|
||||
async function approveLicense(id, companyId, decision, note, approverName) {
|
||||
const customer = await repo.findByIdSimple(id, companyId);
|
||||
if (!customer)
|
||||
throw new errors_1.NotFoundError('Customer not found');
|
||||
return (0, customer_presenter_1.presentCustomer)(await repo.updateById(customer.id, {
|
||||
licenseValidationStatus: decision === 'APPROVE' ? 'APPROVED' : 'DENIED',
|
||||
licenseApprovedBy: approverName,
|
||||
licenseApprovedAt: new Date(),
|
||||
licenseApprovalNote: note ?? null,
|
||||
}));
|
||||
}
|
||||
//# sourceMappingURL=customer.service.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"customer.service.js","sourceRoot":"","sources":["../../../src/modules/customers/customer.service.ts"],"names":[],"mappings":"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"}
|
||||
Reference in New Issue
Block a user