feat(cc-052): FinancialIntelligenceController

This commit is contained in:
admin-valentin 2026-08-01 10:32:03 +00:00
parent b769613e49
commit ebbbff123f

View file

@ -0,0 +1,66 @@
import { Body, Controller, Get, Post, Query } 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 { 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,
@Query('limit') limitStr?: string,
@Query('category') category?: string,
@Query('region') region?: string,
) {
const limit = Math.min(Math.max(1, parseInt(limitStr ?? '50', 10) || 50), 200);
const now = new Date();
const conditions = [
or(isNull(financialSignals.tenantId), eq(financialSignals.tenantId, session.tenantId)),
or(isNull(financialSignals.expiresAt), gte(financialSignals.expiresAt, now)),
];
if (category) conditions.push(eq(financialSignals.category, category));
if (region) conditions.push(eq(financialSignals.region, region));
return db.query.financialSignals.findMany({
where: and(...conditions),
orderBy: [desc(financialSignals.publishedAt)],
limit,
});
}
/** POST /v1/financial-intelligence/ingest — webhook pentru n8n */
@Post('ingest')
async ingest(
@CurrentSession() session: AuthenticatedSession,
@Body() dto: IngestSignalsDto,
) {
if (!dto.signals || dto.signals.length === 0) {
return { ingested: 0 };
}
const rows = dto.signals.map((s) => ({
tenantId: dto.tenantId ?? null,
category: s.category ?? 'macro',
region: s.region ?? 'global',
niche: s.niche ?? null,
source: s.source,
indicatorCode: s.indicatorCode ?? null,
title: s.title,
summary: s.summary,
rawValue: s.rawValue != null ? String(s.rawValue) : null,
changePercent: s.changePercent != null ? String(s.changePercent) : null,
unit: s.unit ?? null,
severity: s.severity ?? 'info',
publishedAt: s.publishedAt ? new Date(s.publishedAt) : new Date(),
expiresAt: s.expiresAt ? new Date(s.expiresAt) : null,
}));
await db.insert(financialSignals).values(rows);
return { ingested: rows.length };
}
}