Skip to content

Commit b029358

Browse files
authored
feat(backend): log method and url for each request (#480)
* feat(backend): log method and url for each request * test(backend): set env before app build, fix import order * fix(backend): resolve eslint errors in app.ts * fix(backend): generate prisma client on install
1 parent a7ec352 commit b029358

4 files changed

Lines changed: 32 additions & 6 deletions

File tree

apps/backend/package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"db:deploy": "prisma migrate deploy",
1616
"db:seed": "tsx prisma/seed.ts",
1717
"db:studio": "prisma studio",
18+
"postinstall": "prisma generate",
1819
"typecheck": "tsc --noEmit"
1920
},
2021
"dependencies": {

apps/backend/src/__tests__/app.test.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
process.env.NODE_ENV = 'test';
1+
import { describe, it, expect, vi } from 'vitest';
22

3-
import { describe, it, expect } from 'vitest';
43
import { buildApp } from '../app';
54

5+
process.env.NODE_ENV = 'test';
6+
process.env.JWT_SECRET ||= 'test-jwt-secret';
7+
process.env.ENCRYPTION_KEY ||= 'test-encryption-key';
8+
69
describe('GET /health', () => {
710
it('should return status ok', async () => {
811
const app = await buildApp();
@@ -15,6 +18,22 @@ describe('GET /health', () => {
1518
expect(res.statusCode).toBe(200);
1619
expect(JSON.parse(res.body)).toEqual({ status: 'ok' });
1720

21+
await app.close();
22+
});
23+
});
24+
25+
describe('request logging hook', () => {
26+
it('logs method and url for each request', async () => {
27+
const app = await buildApp();
28+
const spy = vi.spyOn(app.log, 'info');
29+
30+
await app.inject({ method: 'GET', url: '/health' });
31+
32+
expect(spy).toHaveBeenCalledWith(
33+
expect.objectContaining({ method: 'GET', url: '/health' }),
34+
'incoming request',
35+
);
36+
1837
await app.close();
1938
});
2039
});

apps/backend/src/app.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import helmet from '@fastify/helmet';
77
import jwt from '@fastify/jwt';
88
import multipart from '@fastify/multipart';
99
import rateLimit from '@fastify/rate-limit';
10-
import fastifyStatic from '@fastify/static';
1110
import Fastify, {type FastifyInstance} from 'fastify';
1211

1312
import { prismaPlugin } from './plugins/prisma.js';
@@ -21,8 +20,8 @@ import { followRoutes } from './routes/follow.js';
2120
import { nfcRoutes } from './routes/nfc.js';
2221
import { profileRoutes } from './routes/profiles.js';
2322
import { publicRoutes } from './routes/public.js';
24-
import { validateEnv } from './utils/validateEnv.js';
2523
import { teamRoutes } from './routes/team.js';
24+
import { validateEnv } from './utils/validateEnv.js';
2625

2726
const __dirname = path.dirname(fileURLToPath(import.meta.url));
2827

@@ -42,6 +41,12 @@ export async function buildApp():Promise<FastifyInstance> {
4241
},
4342
});
4443

44+
// Log method + path for every incoming request.
45+
app.addHook('onRequest', (request, _reply, done) => {
46+
app.log.info({ method: request.method, url: request.url }, 'incoming request');
47+
done();
48+
});
49+
4550
// ─── Core Plugins ───
4651
await app.register(cors, {
4752
origin: process.env.PUBLIC_APP_URL || 'http://localhost:5173',
@@ -92,8 +97,8 @@ export async function buildApp():Promise<FastifyInstance> {
9297
try {
9398
// Ensure the verified payload is assigned to `request.user` like the original plugin.
9499
const payload = await request.jwtVerify();
95-
if (payload) request.user = payload;
96-
} catch (error) {
100+
if (payload) { request.user = payload; }
101+
} catch (_error) {
97102
reply.status(401).send({ error: 'Unauthorized' });
98103
}
99104
});

0 commit comments

Comments
 (0)