Skip to content

Commit acb9d30

Browse files
refactor server breaking it down to sub packages
1 parent 5ce1952 commit acb9d30

File tree

17 files changed

+222
-121
lines changed

17 files changed

+222
-121
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,5 @@ setup.sh
4444
.ignore
4545

4646
node_modules
47+
apps/pdf-analyzer-service/data
48+
sample-pay-statement.pdf

apps/pdf-analyzer-service/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"dev": "tsx watch src/index.ts",
7+
"dev": "tsx watch src/server.ts",
88
"build": "tsc -p tsconfig.json",
9-
"start": "node dist/index.js"
9+
"start": "node dist/server.js"
1010
},
1111
"dependencies": {
1212
"express": "^4.19.2",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import express from 'express';
2+
import swaggerUi from 'swagger-ui-express';
3+
import { registerRoutes } from './routes/index.js';
4+
import { errorHandler } from './middleware/error.middleware.js';
5+
import { notFound } from './middleware/notFound.middleware.js';
6+
import { loadOpenApi } from './utils/swagger.js';
7+
8+
const app = express();
9+
10+
app.use(express.json());
11+
12+
const openapiDoc = loadOpenApi();
13+
app.use('/docs', swaggerUi.serve, swaggerUi.setup(openapiDoc));
14+
app.get('/', (_req, res) => res.redirect('/docs'));
15+
16+
registerRoutes(app);
17+
18+
app.use(notFound);
19+
app.use(errorHandler);
20+
21+
export default app;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import path from 'path';
2+
import os from 'os';
3+
4+
export const config = {
5+
port: process.env.PORT ? Number(process.env.PORT) : 8080,
6+
commitSha: process.env.COMMIT_SHA || 'local-dev',
7+
storageRoot: process.env.STORAGE_DIR || path.join(process.cwd(), 'data'),
8+
};
9+
10+
export const paths = {
11+
uploadsDir: path.join(config.storageRoot, 'uploads'),
12+
tmpUploadDir: path.join(os.tmpdir(), 'pdf-analyzer-uploads'),
13+
openapiPath: path.join(process.cwd(), 'api', 'openapi.yaml'),
14+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Request, Response } from 'express';
2+
import { config } from '../config/index.js';
3+
4+
export const health = (_req: Request, res: Response) => {
5+
res.json({ status: 'ok', commit: config.commitSha });
6+
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Request, Response } from 'express';
2+
import { jobService } from '../services/job.service.js';
3+
4+
export const upload = (req: Request, res: Response) => {
5+
if (!req.file) {
6+
res.status(400).json({ error: 'file is required' });
7+
return;
8+
}
9+
const id = jobService.createJobFromUpload(req.file.path, req.file.originalname);
10+
res.status(201).json({ jobId: id });
11+
};
12+
13+
export const listJobs = (_req: Request, res: Response) => {
14+
res.json({ jobs: jobService.listJobs() });
15+
};
16+
17+
export const getJob = (req: Request, res: Response) => {
18+
const job = jobService.getJob(req.params.id);
19+
if (!job) {
20+
res.status(404).json({ error: 'not found' });
21+
return;
22+
}
23+
res.json(job);
24+
};
25+
26+
export const completeJob = (req: Request, res: Response) => {
27+
const status = req.body?.status === 'failed' ? 'failed' : 'completed';
28+
const ok = jobService.completeJob(req.params.id, status, req.body?.result, req.body?.error);
29+
if (!ok) {
30+
res.status(404).json({ error: 'not found' });
31+
return;
32+
}
33+
res.json({ ok: true });
34+
};

apps/pdf-analyzer-service/src/index.ts

Lines changed: 0 additions & 119 deletions
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Request, Response, NextFunction } from 'express';
2+
3+
export function errorHandler(err: any, _req: Request, res: Response, _next: NextFunction) {
4+
console.error('Unhandled error:', err);
5+
res.status(500).json({ error: 'internal server error' });
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Request, Response, NextFunction } from 'express';
2+
3+
export function notFound(_req: Request, res: Response, _next: NextFunction) {
4+
res.status(404).json({ error: 'not found' });
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Router } from 'express';
2+
import { health } from '../controllers/health.controller.js';
3+
4+
const router = Router();
5+
6+
router.get('/v1/health', health);
7+
8+
export default router;

0 commit comments

Comments
 (0)