FEAT: pii

This commit is contained in:
marcos-silva-rodrigues
2025-04-29 14:00:23 -03:00
parent 7a6db36554
commit 58e3c7be94
12 changed files with 883 additions and 59 deletions
+18 -5
View File
@@ -346,7 +346,7 @@ export class CatalogController {
@Language() language: LanguageEnum,
@Param('id') id: string,
): Promise<IPreviewResponse> {
const { customer_name, customer_id, user_id, username } = user;
const { customer_name, customer_id, user_id, username, customer_modules } = user;
this.logger.info(`/catalog - ON GET DATA DOCS ROUTE`, {
user_id,
@@ -359,6 +359,7 @@ export class CatalogController {
user_id,
username,
language,
is_mask: customer_modules.some(mod => mod === 'pii')
});
const preview = await this.catalogService.getDatasetPreview(id, metadata);
@@ -863,15 +864,27 @@ export class CatalogController {
@RequireModule(
DADOSFERA_MODULES_KEYS.PII
)
async getPiiReporter(@User() user: RequestUser, @Res() res: Response) {
async getPiiReporter(@User() user: RequestUser, @Res() res: Response, @Query('type') type: "html" | "csv") {
this.logger.info('GET pii-reporter');
const metadata = PackTheMetadata(user);
try {
const reporterHtml = await this.catalogService.getPiiReporter(metadata);
const reporter = await this.catalogService.getPiiReporter(metadata, type);
res.setHeader('Content-Type', 'text/html');
return res.send(reporterHtml);
if (type === "html") {
res.setHeader('Content-Type', 'text/html');
} else if (type === "csv") {
res.setHeader('Content-Type', 'text/csv');
} else if (type === "pdf") {
res.setHeader('Content-Type', 'application/pdf');
}
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `relatorio-pii-${timestamp}.${type}`;
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
return res.send(reporter);
} catch (error) {
this.logger.error(error);
}
+43 -41
View File
@@ -34,8 +34,12 @@ import {
GetNimbusDashboardsRequest,
GetRlsRulesRequest,
} from '@dadosfera/protospack-v2/dist/lib/Catalog/interfaces/messages';
import { readFileSync } from 'fs';
import { writeFileSync } from 'fs';
import path from 'path';
import { HtmlParser } from 'src/utils/FileParser/html-parser';
import { PiiDto } from './dtos/pii.dto';
import { CsvParser } from 'src/utils/FileParser/csv-parser';
import { PDFParser } from 'src/utils/FileParser/pdf-parser';
class CatalogService implements OnModuleInit {
catalogReadService: ReadService.CatalogReadServices;
@@ -82,49 +86,47 @@ class CatalogService implements OnModuleInit {
)}.dadosfera.ai`;
}
async getPiiReporter(metadata: Metadata) {
const {
data
} = await lastValueFrom(
this.catalogWriteService.GetPiiReporter({}, metadata)
)
async getPiiReporter(metadata: Metadata, type: "html"| "csv") {
try {
const {
data
} = await lastValueFrom(
this.catalogWriteService.GetPiiReporter({}, metadata)
)
this.logger.info("Finish grpc call")
// 3. Ler o template HTML
const templatePath = path.join(
__dirname,
'../../../src/template/pii-reporter.html',
);
const result = data.map((props) => ({
...props,
pii_rules: this.formatPiiRules(JSON.parse(props.pii_rules)),
}));
this.logger.info("templatePath: " + templatePath);
// 3. Ler o template HTML
const templatePath = path.join(
__dirname,
'../../../src/template/pii-reporter.html',
);
const templateSource = readFileSync(templatePath, 'utf8');
// 4. Compilar o template
const template = Handlebars.compile(templateSource);
// 5. Aplicar os dados ao template
return template({
dados: result,
dataGeracao: new Date().toLocaleString('pt-BR'),
});
}
private formatPiiRules(
data: Record<
string,
{
avg_score: number;
max_score: number;
if (type === "html") {
const htmlParser = new HtmlParser<PiiDto>(templatePath);
return htmlParser.parse(data);
} else if (type === "csv") {
const csvParser = new CsvParser<PiiDto>();
return await csvParser.parse(data)
} else if (type === "pdf") {
const htmlParser = new HtmlParser<PiiDto>(templatePath);
const pdfParser = new PDFParser();
const pdf = await pdfParser.parse(htmlParser.parse(data));
const pdfPath = path.join(
__dirname,
'../../../src/template/teste.pdf',
);
writeFileSync(pdfPath, pdf);
return pdf
}
>,
) {
return Object.keys(data)
.filter((key) => {
return data[key].max_score > 0.7;
})
.join(', ');
throw new Error("Unsupported Type: " + type)
} catch (error) {
this.logger.error(error);
}
}
async createDataAsset(data: Messages.CreateDataAssetRequest, metadata) {
+8
View File
@@ -0,0 +1,8 @@
export class PiiDto {
database_name: string;
table_schema: string;
table_name: string;
column_name: string;
data_type: string;
pii_rules: string;
}