Skip to content

Commit e9930cf

Browse files
authored
Merge pull request #99 from johnsmccain/main
feat: add timestamp header helper for public creator responses
2 parents f34f0d1 + 1d7592a commit e9930cf

4 files changed

Lines changed: 48 additions & 6 deletions

File tree

prisma/schema/schema.prisma

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
66

77
generator client {
8-
provider = "prisma-client-js"
9-
output = "../../node_modules/.prisma/client"
8+
provider = "prisma-client-js"
9+
output = "../../node_modules/.prisma/client"
10+
previewFeatures = ["prismaSchemaFolder"]
1011
}
1112

1213
datasource db {

src/modules/creator/creator.controller.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import {
88
sendValidationError,
99
ErrorCode,
1010
} from '../../utils/api-response.utils';
11-
12-
// Creator service and utilities
11+
import { attachTimestampHeader } from '../../utils/timestamp-headers.utils';
1312
import { getPaginatedCreators } from './creator.service';
1413
import { parseCreatorSortOptions } from './creator.utils';
1514
import { parsePublicQuery } from '../../utils/public-query-parse.utils';
@@ -109,7 +108,7 @@ export const listCreators: RequestHandler = async (req, res) => {
109108
});
110109

111110
const response = wrapPublicCreatorListResponse(creators, meta);
112-
111+
attachTimestampHeader(res);
113112
const filteredItems = Array.isArray(response.items)
114113
? response.items.map((item) =>
115114
pickFields(item as Record<string, unknown>, selectedFields)
@@ -129,4 +128,4 @@ export const listCreators: RequestHandler = async (req, res) => {
129128
console.error('Error listing creators:', error);
130129
return sendError(res, 500, ErrorCode.INTERNAL_ERROR, 'Failed to retrieve creators');
131130
}
132-
};
131+
};

src/modules/creators/creators.controllers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
sendSuccess,
1111
sendValidationError,
1212
} from '../../utils/api-response.utils';
13+
import { attachTimestampHeader } from '../../utils/timestamp-headers.utils';
1314
import { parsePublicQuery } from '../../utils/public-query-parse.utils';
1415
import { buildOffsetPaginationMeta } from '../../utils/pagination.utils';
1516
import { buildCreatorListRequestContext } from './creator-list-context.utils';
@@ -43,6 +44,7 @@ export const httpListCreators: AsyncController = async (req, res, next) => {
4344
})
4445
);
4546

47+
attachTimestampHeader(res);
4648
sendSuccess(res, response);
4749
} catch (error) {
4850
next(error);
@@ -78,6 +80,7 @@ export const httpGetCreatorStats: AsyncController = async (req, res, next) => {
7880
// Serialize using the public stats mapper
7981
const stats = mapPublicCreatorStats(placeholderMetrics);
8082

83+
attachTimestampHeader(res);
8184
sendSuccess(res, stats);
8285
} catch (error) {
8386
next(error);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// src/utils/timestamp-headers.utils.ts
2+
// Centralizes timestamp header formatting for public creator-facing responses.
3+
4+
import { Response } from 'express';
5+
6+
/**
7+
* Header name used to communicate the server-side response timestamp to clients.
8+
*
9+
* Clients can use this to detect stale cached responses or correlate
10+
* request timing without parsing the response body.
11+
*/
12+
export const RESPONSE_TIMESTAMP_HEADER = 'X-Response-Timestamp';
13+
14+
/**
15+
* Formats a Date as an ISO 8601 string suitable for use in HTTP headers.
16+
*
17+
* @param date - Defaults to `new Date()` (now)
18+
* @returns ISO 8601 UTC string, e.g. "2026-03-29T12:00:00.000Z"
19+
*/
20+
export function formatTimestampHeader(date: Date = new Date()): string {
21+
return date.toISOString();
22+
}
23+
24+
/**
25+
* Attaches an `X-Response-Timestamp` header to the response.
26+
*
27+
* Call this before sending any public creator response so clients
28+
* receive a consistent, parseable timestamp on every reply.
29+
*
30+
* @param res - Express response object
31+
* @param date - Timestamp to attach; defaults to now
32+
*
33+
* @example
34+
* attachTimestampHeader(res);
35+
* sendSuccess(res, data);
36+
*/
37+
export function attachTimestampHeader(res: Response, date: Date = new Date()): void {
38+
res.set(RESPONSE_TIMESTAMP_HEADER, formatTimestampHeader(date));
39+
}

0 commit comments

Comments
 (0)