125 lines
3.2 KiB
TypeScript
125 lines
3.2 KiB
TypeScript
/**
|
|
* Files Routes - SharePoint file operations
|
|
*
|
|
* Note: Most file operations go through /api/jobs/:id/files
|
|
* This route provides additional file utilities
|
|
*/
|
|
|
|
import { Hono } from 'hono';
|
|
import { graphService } from '../services/graphService';
|
|
import { tokenService } from '../services/tokenService';
|
|
import { pocketbaseService } from '../services/pocketbaseService';
|
|
import { authMiddleware, getUserId } from '../middleware/auth';
|
|
import { BadRequestError, NotFoundError } from '../middleware/errorHandler';
|
|
|
|
const files = new Hono();
|
|
|
|
// All file routes require authentication
|
|
files.use('/*', authMiddleware);
|
|
|
|
/**
|
|
* GET /api/files
|
|
* List files in a job's folder - requires jobId query param
|
|
*/
|
|
files.get('/', async (c) => {
|
|
const userId = getUserId(c);
|
|
const jobId = c.req.query('jobId');
|
|
|
|
if (!jobId) {
|
|
throw new BadRequestError('jobId query parameter required');
|
|
}
|
|
|
|
// Get job to find site/drive info
|
|
const job = await pocketbaseService.getJob(jobId);
|
|
if (!job) {
|
|
throw new NotFoundError('Job not found');
|
|
}
|
|
|
|
if (!job.site_id || !job.drive_id) {
|
|
return c.json({ files: [] });
|
|
}
|
|
|
|
const tokenResult = await tokenService.getToken(userId, 'graph');
|
|
if (!tokenResult) {
|
|
throw new BadRequestError('Graph token not available');
|
|
}
|
|
|
|
const result = await graphService.getFiles(
|
|
tokenResult.token,
|
|
job.site_id,
|
|
job.drive_id,
|
|
job.folder_path
|
|
);
|
|
|
|
return c.json({ files: result.files });
|
|
});
|
|
|
|
/**
|
|
* GET /api/files/download-url
|
|
* Get download URL for a file - requires jobId and fileId
|
|
*/
|
|
files.get('/download-url', async (c) => {
|
|
const userId = getUserId(c);
|
|
const jobId = c.req.query('jobId');
|
|
const fileId = c.req.query('fileId');
|
|
|
|
if (!jobId || !fileId) {
|
|
throw new BadRequestError('jobId and fileId query parameters required');
|
|
}
|
|
|
|
// Get job to find site/drive info
|
|
const job = await pocketbaseService.getJob(jobId);
|
|
if (!job || !job.site_id || !job.drive_id) {
|
|
throw new NotFoundError('Job not found or not configured for files');
|
|
}
|
|
|
|
const tokenResult = await tokenService.getToken(userId, 'graph');
|
|
if (!tokenResult) {
|
|
throw new BadRequestError('Graph token not available');
|
|
}
|
|
|
|
const url = await graphService.getFileDownloadUrl(
|
|
tokenResult.token,
|
|
job.site_id,
|
|
job.drive_id,
|
|
fileId
|
|
);
|
|
|
|
if (!url) {
|
|
throw new NotFoundError('File not found');
|
|
}
|
|
|
|
return c.json({ url });
|
|
});
|
|
|
|
/**
|
|
* GET /api/files/search
|
|
* Search files in a job's SharePoint site
|
|
*/
|
|
files.get('/search', async (c) => {
|
|
const userId = getUserId(c);
|
|
const jobId = c.req.query('jobId');
|
|
const query = c.req.query('q');
|
|
|
|
if (!jobId || !query) {
|
|
throw new BadRequestError('jobId and q query parameters required');
|
|
}
|
|
|
|
// Get job to find site info
|
|
const job = await pocketbaseService.getJob(jobId);
|
|
if (!job || !job.site_id) {
|
|
throw new NotFoundError('Job not found or not configured for files');
|
|
}
|
|
|
|
const tokenResult = await tokenService.getToken(userId, 'graph');
|
|
if (!tokenResult) {
|
|
throw new BadRequestError('Graph token not available');
|
|
}
|
|
|
|
const results = await graphService.searchFiles(tokenResult.token, job.site_id, query);
|
|
|
|
return c.json({ files: results });
|
|
});
|
|
|
|
export default files;
|