This commit is contained in:
2026-10-01 13:31:40 +05:30
parent 6937b4e114
commit 1ea59d8a3a
2 changed files with 41 additions and 21 deletions
+24 -13
View File
@@ -93,19 +93,30 @@ async function run(port) {
const missing = await request(port, 'GET', '/api/auth/me'); const missing = await request(port, 'GET', '/api/auth/me');
assert(missing.status === 401, 'missing token should be 401'); assert(missing.status === 401, 'missing token should be 401');
const dealerMissingPhone = await request(port, 'POST', '/api/admin/dealers', {
token: adminToken,
body: { name: 'No Phone', code: 'NONE' },
});
assert(dealerMissingPhone.status === 400, 'dealer without a phone should fail');
const dealerA = await request(port, 'POST', '/api/admin/dealers', { const dealerA = await request(port, 'POST', '/api/admin/dealers', {
token: adminToken, token: adminToken,
body: { name: 'Kandy Motors', code: 'KDY', district: 'Kandy' }, body: { name: 'Kandy Motors', code: 'KDY', district: 'Kandy', phone: '94772222222' },
}); });
const dealerB = await request(port, 'POST', '/api/admin/dealers', { const dealerB = await request(port, 'POST', '/api/admin/dealers', {
token: adminToken, token: adminToken,
body: { name: 'Galle Motors', code: 'GAL', district: 'Galle' }, body: { name: 'Galle Motors', code: 'GAL', district: 'Galle', phone: '94774444444' },
}); });
const dealerC = await request(port, 'POST', '/api/admin/dealers', { const dealerC = await request(port, 'POST', '/api/admin/dealers', {
token: adminToken, token: adminToken,
body: { name: 'Jaffna Motors', code: 'JAF', district: 'Jaffna' }, body: { name: 'Jaffna Motors', code: 'JAF', district: 'Jaffna', phone: '94773333333' },
}); });
assert(dealerA.status === 201 && dealerB.status === 201 && dealerC.status === 201, 'dealer create failed'); assert(dealerA.status === 201 && dealerB.status === 201 && dealerC.status === 201, 'dealer create failed');
const kandyLogin = await prisma.user.findUnique({ where: { phone: '94772222222' } });
assert(
kandyLogin && kandyLogin.role === 'dealer' && kandyLogin.dealerId === dealerA.json.data.id,
'creating a dealer should create its login'
);
const rep = await request(port, 'POST', '/api/admin/sales-reps', { const rep = await request(port, 'POST', '/api/admin/sales-reps', {
token: adminToken, token: adminToken,
@@ -118,12 +129,6 @@ async function run(port) {
}); });
assert(rep.status === 201, `sales rep create failed ${rep.status}`); assert(rep.status === 201, `sales rep create failed ${rep.status}`);
const dealerUser = await request(port, 'POST', '/api/admin/dealer-users', {
token: adminToken,
body: { name: 'Kandy Desk', phone: '94772222222', dealerId: dealerA.json.data.id },
});
assert(dealerUser.status === 201, 'dealer user create failed');
async function staffLogin(phone, password) { async function staffLogin(phone, password) {
const result = await request(port, 'POST', '/api/auth/staff-login', { const result = await request(port, 'POST', '/api/auth/staff-login', {
body: { phone, password }, body: { phone, password },
@@ -158,11 +163,17 @@ async function run(port) {
}); });
assert(dealerStaff.status === 401, 'dealer should not use staff login'); assert(dealerStaff.status === 401, 'dealer should not use staff login');
const otherDealer = await request(port, 'POST', '/api/admin/dealer-users', { const repDealer = await request(port, 'POST', '/api/admin/dealers', {
token: adminToken, token: repToken,
body: { name: 'Jaffna Desk', phone: '94773333333', dealerId: dealerC.json.data.id }, body: { name: 'Matara Motors', code: 'MTR', district: 'Matara', phone: '0715555555' },
}); });
assert(otherDealer.status === 201, 'second dealer user create failed'); assert(repDealer.status === 201, `sales rep dealer create failed ${repDealer.status}`);
const repDealers = await request(port, 'GET', '/api/dealers', { token: repToken });
assert(
repDealers.status === 200 && repDealers.json.data.some((item) => item.code === 'MTR'),
'sales rep should see the dealer they created'
);
const outsideRequest = await request(port, 'POST', '/api/auth/dealer-login', { const outsideRequest = await request(port, 'POST', '/api/auth/dealer-login', {
body: { phone: '94773333333' }, body: { phone: '94773333333' },
}); });
+17 -8
View File
@@ -22,21 +22,30 @@ router.get(
router.post( router.post(
'/dealers', '/dealers',
requireRole('superAdmin'), requireRole('superAdmin', 'salesRep'),
asyncHandler(async (req, res) => { asyncHandler(async (req, res) => {
const name = String(req.body?.name || '').trim(); const name = String(req.body?.name || '').trim();
const code = String(req.body?.code || '').trim(); const code = String(req.body?.code || '').trim();
const district = String(req.body?.district || '').trim() || null; const district = String(req.body?.district || '').trim() || null;
const address = String(req.body?.address || '').trim() || null; const address = String(req.body?.address || '').trim() || null;
const rawPhone = String(req.body?.phone || '').trim(); const phone = normalizePhone(req.body?.phone);
const phone = rawPhone ? normalizePhone(rawPhone) : null; if (!name || !code || !isValidPhone(phone)) {
if (!name || !code) throw httpError(400, 'Name and code are required'); throw httpError(400, 'Name, code, and a Sri Lankan mobile number are required');
if (phone && !isValidPhone(phone)) {
throw httpError(400, 'Dealer phone must be a Sri Lankan mobile number');
} }
const dealer = await prisma.dealer.create({ const dealer = await prisma.$transaction(async (tx) => {
data: { name, code, district, address, phone }, const created = await tx.dealer.create({
data: { name, code, district, address, phone },
});
await tx.user.create({
data: { name, phone, role: 'dealer', dealerId: created.id },
});
if (req.user.role === 'salesRep') {
await tx.dealerAssignment.create({
data: { salesRepId: req.user.id, dealerId: created.id },
});
}
return created;
}); });
return res.status(201).json({ success: true, data: dealer }); return res.status(201).json({ success: true, data: dealer });
}) })