feat(website-intake): dual-write endpoint + migration chain repair
Adds website_submissions table + shared-secret POST endpoint so the marketing site can dual-write inquiries alongside its NocoDB write. Race-safe via INSERT ... ON CONFLICT, idempotent on submission_id, refuses every request when WEBSITE_INTAKE_SECRET is unset. Also repairs pre-existing 0020/0021/0022 prevId collision (renumbered + journal re-sorted) so db:generate works again. 11 unit tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,6 +85,12 @@ export const rateLimiters = {
|
||||
exports: { windowMs: 60 * 60 * 1000, max: 30, keyPrefix: 'export' },
|
||||
/** Public unauthenticated form posts (interest, residential inquiry): 5 per hour per IP. */
|
||||
publicForm: { windowMs: 60 * 60 * 1000, max: 5, keyPrefix: 'publicform' },
|
||||
/** Server-to-server intake from the marketing website's dual-write helper.
|
||||
* All traffic shares the website's egress IP, so the bucket has to
|
||||
* accommodate every legitimate inquiry the site can produce in an hour
|
||||
* without dropping data. The shared-secret header gates abuse; this
|
||||
* limiter is just a defensive backstop in case the secret leaks. */
|
||||
websiteIntake: { windowMs: 60 * 60 * 1000, max: 500, keyPrefix: 'websiteintake' },
|
||||
} as const satisfies Record<string, RateLimitConfig>;
|
||||
|
||||
export type RateLimiterName = keyof typeof rateLimiters;
|
||||
|
||||
Reference in New Issue
Block a user