feat(CC-054): add @Public ingest endpoint with X-Ingest-Key auth

This commit is contained in:
admin-valentin 2026-08-01 12:32:04 +00:00
parent f52fe6d709
commit 925ce11a06

View file

@ -1,14 +1,14 @@
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { Body, Controller, Get, Headers, Post, Query, UnauthorizedException } from '@nestjs/common';
import { desc, isNull, or, eq, and, gte } from 'drizzle-orm';
import { CurrentSession } from '../auth/session.decorator';
import type { AuthenticatedSession } from '../auth/tenant.guard';
import { Public } from '../auth/public.decorator';
import { db } from '../db/client';
import { financialSignals } from '../db/schema';
import { IngestSignalsDto } from './dto';
@Controller('financial-intelligence')
export class FinancialIntelligenceController {
/** GET /v1/financial-intelligence/signals — semnale active pentru tenant */
@Get('signals')
async signals(
@CurrentSession() session: AuthenticatedSession,
@ -33,16 +33,20 @@ export class FinancialIntelligenceController {
});
}
/** POST /v1/financial-intelligence/ingest — webhook pentru n8n */
/** POST /v1/financial-intelligence/ingest — n8n webhook, semnat cu X-Ingest-Key */
@Public()
@Post('ingest')
async ingest(
@CurrentSession() session: AuthenticatedSession,
@Headers('x-ingest-key') ingestKey: string | undefined,
@Body() dto: IngestSignalsDto,
) {
if (!dto.signals || dto.signals.length === 0) {
return { ingested: 0 };
const expected = process.env.INGEST_SECRET;
if (expected && ingestKey !== expected) {
throw new UnauthorizedException('Invalid ingest key');
}
if (!dto.signals || dto.signals.length === 0) return { ingested: 0 };
const rows = dto.signals.map((s) => ({
tenantId: dto.tenantId ?? null,
category: s.category ?? 'macro',