feat(cc-052): FinancialIntelligenceController
This commit is contained in:
parent
b769613e49
commit
ebbbff123f
1 changed files with 66 additions and 0 deletions
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue