@@ -39,7 +39,7 @@ export class DocumentProcessorController {
3939
4040 @Post ( 'upload' )
4141 @UseInterceptors ( FileInterceptor ( 'file' ) )
42- async processDocument (
42+ async uploadAndProcessReport (
4343 @UploadedFile ( ) file : Express . Multer . File ,
4444 @Body ( 'userId' ) userId : string ,
4545 @Body ( 'debug' ) debug ?: string ,
@@ -115,12 +115,12 @@ export class DocumentProcessorController {
115115 }
116116
117117 @Post ( 'process-file' )
118- async processFileFromPath (
119- @Body ( 'filePath ' ) filePath : string ,
118+ async processReport (
119+ @Body ( 'reportId ' ) reportId : string ,
120120 @Req ( ) request : RequestWithUser ,
121- ) : Promise < ProcessedDocumentResult | any > {
122- if ( ! filePath ) {
123- throw new BadRequestException ( 'No filePath provided' ) ;
121+ ) : Promise < any > {
122+ if ( ! reportId ) {
123+ throw new BadRequestException ( 'No reportId provided' ) ;
124124 }
125125
126126 // Extract userId from the request (attached by auth middleware)
@@ -129,21 +129,70 @@ export class DocumentProcessorController {
129129 throw new UnauthorizedException ( 'User ID not found in request' ) ;
130130 }
131131
132- this . logger . log ( `Processing document from file path : ${ filePath } ` ) ;
132+ this . logger . log ( `Queueing document for processing, report ID : ${ reportId } ` ) ;
133133
134134 try {
135- // Fetch the associated report record from DynamoDB
136- const report = await this . reportsService . findByFilePath ( filePath , userId ) ;
135+ // Fetch the associated report record from DynamoDB using findOne method
136+ const report = await this . reportsService . findOne ( reportId , userId ) ;
137137 if ( ! report ) {
138- throw new NotFoundException ( `Report with filePath ${ filePath } not found` ) ;
138+ throw new NotFoundException ( `Report with ID ${ reportId } not found` ) ;
139+ }
140+
141+ // Make sure we have a filePath to retrieve the file
142+ if ( ! report . filePath ) {
143+ throw new BadRequestException ( `Report with ID ${ reportId } has no associated file` ) ;
139144 }
140145
146+ // Update report status to IN_PROGRESS before starting async processing
147+ report . processingStatus = ProcessingStatus . IN_PROGRESS ;
148+ report . updatedAt = new Date ( ) . toISOString ( ) ;
149+ await this . reportsService . updateReport ( report ) ;
150+
151+ // Start async processing in background
152+ this . processReportAsync ( reportId , userId , report . filePath ) . catch ( error => {
153+ this . logger . error ( `Async processing failed for report ${ reportId } : ${ error . message } ` ) ;
154+ } ) ;
155+
156+ return {
157+ success : true ,
158+ reportId : report . id ,
159+ status : ProcessingStatus . IN_PROGRESS ,
160+ message : 'Document processing started. Check the report status to know when it completes.' ,
161+ } ;
162+ } catch ( error : unknown ) {
163+ this . logger . error (
164+ `Error queueing document for report ID ${ reportId } : ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
165+ ) ;
166+ throw error ;
167+ }
168+ }
169+
170+ /**
171+ * Processes a report file asynchronously
172+ * @param reportId - ID of the report to process
173+ * @param userId - ID of the user who owns the report
174+ * @param filePath - S3 path to the file
175+ */
176+ private async processReportAsync (
177+ reportId : string ,
178+ userId : string ,
179+ filePath : string ,
180+ ) : Promise < void > {
181+ try {
182+ this . logger . log ( `Started async processing for report: ${ reportId } ` ) ;
183+
141184 // Get the file from S3
142185 const fileBuffer = await this . getFileFromS3 ( filePath ) ;
143186
144187 // Process the document
145188 const result = await this . documentProcessorService . processDocument ( fileBuffer , userId ) ;
146189
190+ // Fetch the report again to ensure we have the latest version
191+ const report = await this . reportsService . findOne ( reportId , userId ) ;
192+ if ( ! report ) {
193+ throw new Error ( `Report ${ reportId } not found during async processing` ) ;
194+ }
195+
147196 // Update the report with analysis results
148197 report . title = result . analysis . title || 'Untitled Report' ;
149198 report . category = result . analysis . category || 'general' ;
@@ -163,13 +212,26 @@ export class DocumentProcessorController {
163212 // Update the report in DynamoDB
164213 await this . reportsService . updateReport ( report ) ;
165214
166- return {
167- success : true ,
168- reportId : report . id ,
169- } ;
170- } catch ( error : unknown ) {
215+ this . logger . log ( `Completed async processing for report: ${ reportId } ` ) ;
216+ } catch ( error ) {
217+ // If processing fails, update the report status to indicate failure
218+ try {
219+ const report = await this . reportsService . findOne ( reportId , userId ) ;
220+ if ( report ) {
221+ report . processingStatus = ProcessingStatus . UNPROCESSED ; // Could add a FAILED status in the enum if needed
222+ report . updatedAt = new Date ( ) . toISOString ( ) ;
223+ await this . reportsService . updateReport ( report ) ;
224+ }
225+ } catch ( updateError : unknown ) {
226+ this . logger . error (
227+ `Failed to update report status after processing error: ${
228+ updateError instanceof Error ? updateError . message : 'Unknown error'
229+ } `,
230+ ) ;
231+ }
232+
171233 this . logger . error (
172- `Error processing document from path ${ filePath } : ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
234+ `Error during async processing for report ${ reportId } : ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
173235 ) ;
174236 throw error ;
175237 }
@@ -607,4 +669,42 @@ export class DocumentProcessorController {
607669
608670 res . type ( 'text/html' ) . send ( html ) ;
609671 }
672+
673+ @Get ( 'report-status/:reportId' )
674+ async getReportStatus (
675+ @Req ( ) request : RequestWithUser ,
676+ @Body ( 'reportId' ) idFromBody : string ,
677+ ) : Promise < any > {
678+ // Get reportId from path parameter or body
679+ const reportId = request . params . reportId || idFromBody ;
680+
681+ if ( ! reportId ) {
682+ throw new BadRequestException ( 'No reportId provided' ) ;
683+ }
684+
685+ // Extract userId from the request (attached by auth middleware)
686+ const userId = request . user ?. sub ;
687+ if ( ! userId ) {
688+ throw new UnauthorizedException ( 'User ID not found in request' ) ;
689+ }
690+
691+ try {
692+ // Fetch the associated report record from DynamoDB
693+ const report = await this . reportsService . findOne ( reportId , userId ) ;
694+ if ( ! report ) {
695+ throw new NotFoundException ( `Report with ID ${ reportId } not found` ) ;
696+ }
697+
698+ return {
699+ reportId : report . id ,
700+ status : report . processingStatus ,
701+ isComplete : report . processingStatus === ProcessingStatus . PROCESSED ,
702+ } ;
703+ } catch ( error : unknown ) {
704+ this . logger . error (
705+ `Error fetching report status for ${ reportId } : ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
706+ ) ;
707+ throw error ;
708+ }
709+ }
610710}
0 commit comments