@@ -47,46 +47,109 @@ app.get("/", (req, res) => {
4747 1️⃣ CREATE REQUEST & AI ANALYSIS
4848====================================================== */
4949app . post ( "/createRequest" , async ( req , res ) => {
50- try {
51- const data = req . body ;
52- let newRequest = {
53- ...data ,
54- status : "PENDING_ADMIN" ,
55- createdAt : admin . firestore . FieldValue . serverTimestamp ( ) ,
56- } ;
57-
58- if ( data . flowType === "VERIFICATION" ) {
59- newRequest . aiVerdict = "AUTHENTIC" ;
60- newRequest . aiConfidence = 92 ;
61- newRequest . aiReasons = [ "Valid academic structure" , "No manipulation detected" ] ;
62- } else {
63- newRequest . aiVerdict = "NOT_APPLICABLE" ;
64- newRequest . aiReasons = [ "Direct issuance request" ] ;
65- }
50+ try {
51+ const {
52+ requestedType,
53+ userEmail,
54+ flowType,
55+ student
56+ } = req . body ;
57+
58+ // 🔒 STRICT VALIDATION
59+ if ( ! requestedType || ! userEmail || ! student ) {
60+ return res . status ( 400 ) . json ( {
61+ error : "Missing required fields"
62+ } ) ;
63+ }
6664
67- const docRef = await db . collection ( "requests" ) . add ( newRequest ) ;
68- res . status ( 201 ) . json ( { success : true , id : docRef . id } ) ;
69- } catch ( err ) {
70- console . error ( "❌ Error in createRequest:" , err ) ;
71- res . status ( 500 ) . json ( { error : err . message } ) ;
65+ const requiredStudentFields = [
66+ "name" ,
67+ "usn" ,
68+ "department" ,
69+ "semester" ,
70+ "college"
71+ ] ;
72+
73+ for ( const field of requiredStudentFields ) {
74+ if ( ! student [ field ] ) {
75+ return res . status ( 400 ) . json ( {
76+ error : `Student field '${ field } ' is required`
77+ } ) ;
78+ }
79+ }
80+
81+ // ✅ SAFE REQUEST OBJECT
82+ const newRequest = {
83+ requestedType,
84+ userEmail,
85+ student : {
86+ name : student . name ,
87+ usn : student . usn ,
88+ department : student . department ,
89+ semester : student . semester ,
90+ college : student . college
91+ } ,
92+ flowType,
93+ status : "PENDING_ADMIN" ,
94+ createdAt : admin . firestore . FieldValue . serverTimestamp ( )
95+ } ;
96+
97+ // 🤖 AI LOGIC
98+ if ( flowType === "VERIFICATION" ) {
99+ newRequest . aiVerdict = "AUTHENTIC" ;
100+ newRequest . aiConfidence = 92 ;
101+ newRequest . aiReasons = [
102+ "Valid academic structure" ,
103+ "No manipulation detected"
104+ ] ;
105+ } else {
106+ newRequest . aiVerdict = "NOT_APPLICABLE" ;
107+ newRequest . aiReasons = [ "Direct issuance request" ] ;
72108 }
109+
110+ const docRef = await db . collection ( "requests" ) . add ( newRequest ) ;
111+
112+ res . status ( 201 ) . json ( {
113+ success : true ,
114+ requestId : docRef . id
115+ } ) ;
116+
117+ } catch ( err ) {
118+ console . error ( "❌ createRequest error:" , err ) ;
119+ res . status ( 500 ) . json ( { error : err . message } ) ;
120+ }
73121} ) ;
74122
123+
75124/* ======================================================
76125 2️⃣ APPROVE & ISSUE CERTIFICATE (SUPABASE VERSION)
77126====================================================== */
78127app . post ( "/approveRequest" , async ( req , res ) => {
79128 try {
80129 const { requestId } = req . body ;
81- if ( ! requestId ) return res . status ( 400 ) . json ( { error : "requestId required" } ) ;
130+ if ( ! requestId ) {
131+ return res . status ( 400 ) . json ( { error : "requestId is required" } ) ;
132+ }
82133
83134 const ref = db . collection ( "requests" ) . doc ( requestId ) ;
84135 const snap = await ref . get ( ) ;
85136
86- if ( ! snap . exists ) return res . status ( 404 ) . send ( "Request not found" ) ;
137+ if ( ! snap . exists ) {
138+ return res . status ( 404 ) . json ( { error : "Request not found" } ) ;
139+ }
87140
88141 const data = snap . data ( ) ;
89- const student = data . student || { } ;
142+ const student = data . student ;
143+
144+ // 🔒 SAFETY CHECK (NO PLACEHOLDERS EVER)
145+ const requiredFields = [ "name" , "usn" , "department" , "semester" , "college" ] ;
146+ for ( const field of requiredFields ) {
147+ if ( ! student || ! student [ field ] ) {
148+ return res . status ( 400 ) . json ( {
149+ error : `Missing student field: ${ field } `
150+ } ) ;
151+ }
152+ }
90153
91154 /* ===============================
92155 📄 PDF GENERATION
@@ -106,40 +169,35 @@ app.post("/approveRequest", async (req, res) => {
106169 x : 215 , y : 765 , size : 12 , font : bodyFont
107170 } ) ;
108171
109- // 📜 TITLE
172+ // 📜 CERTIFICATE TITLE
110173 page . drawText (
111- `${ ( data . requestedType || "CERTIFICATE" ) . toUpperCase ( ) } CERTIFICATE` ,
174+ `${ data . requestedType . toUpperCase ( ) } CERTIFICATE` ,
112175 { x : 120 , y : 710 , size : 20 , font : titleFont }
113176 ) ;
114177
115178 // 🧑 STUDENT DETAILS (AUTO)
116- let y = 650 ;
117- const gap = 28 ;
118-
119- page . drawText (
120- `This is to certify that ${ student . name || "__________" } ,` ,
121- { x : 70 , y, size : 14 , font : bodyFont }
122- ) ;
123-
124- page . drawText (
125- `bearing USN ${ student . usn || "__________" } , is a bonafide student of` ,
126- { x : 70 , y, gap, size : 14 , font : bodyFont }
127- ) ;
128-
129- page . drawText (
130- `${ student . department || "__________" } , Semester ${ student . semester || "__" } ,` ,
131- { x : 70 , y , gap, size : 14 , font : bodyFont }
132- ) ;
179+ let y = 640 ;
180+ const lineGap = 26 ;
181+
182+ const lines = [
183+ `This is to certify that ${ student . name } ,` ,
184+ `bearing USN ${ student . usn } , is a bonafide student of` ,
185+ `${ student . department } , Semester ${ student . semester } ,` ,
186+ `${ student . college } during the academic year.` ,
187+ `This certificate is issued upon request for official purposes.`
188+ ] ;
189+
190+ lines . forEach ( line => {
191+ page . drawText ( line , {
192+ x : 70 ,
193+ y,
194+ size : 14 ,
195+ font : bodyFont
196+ } ) ;
197+ y -= lineGap ;
198+ } ) ;
133199
134- page . drawText (
135- `${ student . college || "RNS Institute of Technology" } during the academic year.` ,
136- { x : 70 , y , gap, size : 14 , font : bodyFont }
137- ) ;
138200
139- page . drawText (
140- "This certificate is issued upon request for official purposes." ,
141- { x : 70 , y , gap :1.2 , size : 14 , font : bodyFont }
142- ) ;
143201
144202 // ✍ SIGNATURE
145203 page . drawText ( "Principal" , {
0 commit comments