fr fixes
This commit is contained in:
parent
d84102e8a1
commit
45269327c5
50
server/DB_COLLECTIONS.md
Normal file
50
server/DB_COLLECTIONS.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# MongoDB Collections (Duxiter Server)
|
||||
|
||||
Questo documento elenca le collection MongoDB usate dal server (via modelli Mongoose) e le TTL applicate dove presenti.
|
||||
|
||||
## Collections con nome esplicito
|
||||
|
||||
| Collection | Model | File | TTL (seconds) |
|
||||
| --- | --- | --- | --- |
|
||||
| `equifax-responses` | `EquifaxResponse` | [EquifaxResponse.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/EquifaxResponse.ts) | `EQUIFAX_RESPONSE_TTL_SECONDS` (default: `604800`) |
|
||||
| `consulta_history` | `ConsultaHistory` | [ConsultaHistory.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/ConsultaHistory.ts) | `CONSULTA_HISTORY_TTL_SECONDS` (default: `63072000`) |
|
||||
| `summaries` | `Summary` | [Summary.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/Summary.ts) | (none) |
|
||||
| `snifasancionatorios` | `SnifaSancionatorio` | [SnifaSancionatorio.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/SnifaSancionatorio.ts) | (none) |
|
||||
|
||||
## Collections con nome “default” (Mongoose pluralizza il nome del model)
|
||||
|
||||
| Collection (attesa) | Model | File | TTL (seconds) |
|
||||
| --- | --- | --- | --- |
|
||||
| `users` | `User` | [user.model.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/user.model.ts) | (none) |
|
||||
| `tenants` | `Tenant` | [tenant.model.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/tenant.model.ts) | (none) |
|
||||
| `results` | `Result` | [Result.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/Result.ts) | (none) |
|
||||
| `sheriffdatalogs` | `SheriffDataLog` | [SheriffDataLog.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/SheriffDataLog.ts) | `SHERIFF_DATA_LOG_TTL_SECONDS` (default: `86400`) |
|
||||
| `sheriffapicalllogs` | `SheriffApiCallLog` | [SheriffApiCallLog.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/SheriffApiCallLog.ts) | `SHERIFF_API_CALL_LOG_TTL_SECONDS` (default: `86400`) |
|
||||
| `monitoringschedules` | `MonitoringSchedule` | [MonitoringSchedule.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/MonitoringSchedule.ts) | (none) |
|
||||
| `monitoringexecutions` | `MonitoringExecution` | [MonitoringExecution.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/MonitoringExecution.ts) | (none) |
|
||||
| `riskchangenotifications` | `RiskChangeNotification` | [RiskChangeNotification.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/RiskChangeNotification.ts) | (none) |
|
||||
| `companydetails` | `CompanyDetails` | [CompanyDetails.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/CompanyDetails.ts) | (none) |
|
||||
| `companyrisks` | `CompanyRisks` | [CompanyRisks.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/CompanyRisks.ts) | (none) |
|
||||
| `duxcompanyinfos` | `DuxCompanyInfo` | [DuxCompanyInfo.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/DuxCompanyInfo.ts) | (none) |
|
||||
| `creditoperations` | `CreditOperation` | [creditOperation.model.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/creditOperation.model.ts) | (none) |
|
||||
| `tenantbillings` | `TenantBilling` | [tenantBilling.model.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/tenantBilling.model.ts) | (none) |
|
||||
| `billingsettings` | `BillingSettings` | [billingSettings.model.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/billingSettings.model.ts) | (none) |
|
||||
| `evaluationjobs` | `EvaluationJob` | [evaluation.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/evaluation.ts) | (none) |
|
||||
| `evaluationresults` | `EvaluationResult` | [evaluation.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/evaluation.ts) | (none) |
|
||||
| `evaluationparameters` | `EvaluationParameter` | [EvaluationParameter.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/EvaluationParameter.ts) | (none) |
|
||||
| `promptconfigurations` | `PromptConfiguration` | [PromptConfiguration.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/PromptConfiguration.ts) | (none) |
|
||||
| `antiunioncases` | `AntiunionCase` | [AntiunionCase.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/AntiunionCase.ts) | (none) |
|
||||
| `usernotes` | `UserNote` | [UserNote.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/UserNote.ts) | (none) |
|
||||
| `snifaimportjobs` | `SnifaImportJob` | [SnifaImportJob.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/SnifaImportJob.ts) | (none) |
|
||||
| `snifachangelogs` | `SnifaChangeLog` | [SnifaChangeLog.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/SnifaChangeLog.ts) | (none) |
|
||||
| `ley20393s` | `Ley20393` | [Ley20393.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/Ley20393.ts) | (none) |
|
||||
| `ley21121s` | `Ley21121` | [Ley21121.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/Ley21121.ts) | (none) |
|
||||
| `lpaltos` | `Lpalto` | [Lpalto.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/Lpalto.ts) | (none) |
|
||||
| `lpmedios` | `Lpmedio` | [Lpmedio.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/Lpmedio.ts) | (none) |
|
||||
| `logsherifdatas` | `logSherifData` | [LogSherifData.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/LogSherifData.ts) | `LOG_SHERIFF_DATA_TTL_SECONDS` (default: `86400`) |
|
||||
| `aioperationlogs` | `AIOperationLog` | [AIOperationLog.ts](file:///home/duxiter/duxiter_intermediate/server/src/models/AIOperationLog.ts) | `AI_OPERATION_LOG_TTL_SECONDS` (default: `86400`) |
|
||||
|
||||
## Note
|
||||
|
||||
- Alcuni modelli risultano duplicati nel codebase (es. `AIOperationLog.ts` e `aiOperationLog.model.ts`): la collection usata resta comunque la stessa se il `modelName` coincide.
|
||||
- Il nome “atteso” delle collection in questa sezione dipende dalla pluralizzazione di Mongoose; per vedere i nomi reali in DB usare `db.listCollections()` oppure l’endpoint/admin di database management se presente.
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
"rut": "79559670",
|
||||
"events": [
|
||||
{
|
||||
"cve": "2733935",
|
||||
"published_at": "2025-11-27",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "Proquiel Químicos SpA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/11/27/44310/05/2733935.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2708229",
|
||||
"published_at": "2025-10-04",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "Proquiel Químicos SpA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/10/04/44266/05/2708229.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2624462",
|
||||
"published_at": "2025-03-22",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "PROQUIEL QUÍMICOS SpA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/03/22/44106/05/2624462.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2554845",
|
||||
"published_at": "2024-10-09",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "PROQUIEL QUIMICOS SpA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/10/09/43969/05/2554845.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2554840",
|
||||
"published_at": "2024-10-09",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "PROQUIEL QUIMICOS SpA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/10/09/43969/05/2554840.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2521272",
|
||||
"published_at": "2024-07-20",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "PROQUIEL TRANSPORTES QUÍMICOS SpA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/07/20/43904/05/2521272.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2049643",
|
||||
"published_at": "2021-11-29",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "PROQUIEL QUIMICOS LIMITADA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2021/11/29/43115/05/2049643.pdf"
|
||||
},
|
||||
{
|
||||
"cve": "2040579",
|
||||
"published_at": "2021-11-12",
|
||||
"actuation_type": "MODIFICACIÓN",
|
||||
"company_name": "PROQUIEL TRANSPORTES QUIMICOS LIMITADA",
|
||||
"source": "DO",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2021/11/12/43101/05/2040579.pdf"
|
||||
}
|
||||
],
|
||||
"cached": true,
|
||||
"timestamp": "2026-04-16T09:22:51.301740",
|
||||
"constitution_date": null
|
||||
}
|
||||
|
|
@ -1,879 +0,0 @@
|
|||
{
|
||||
"pathCount": 81,
|
||||
"relationships": [
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2010-03-25",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "1994-10-05",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2005-02-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2010-03-25",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "77881423",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2733935",
|
||||
"cve": "2733935",
|
||||
"shares_percent": 30,
|
||||
"source": "DO",
|
||||
"published_at": "2025-11-27",
|
||||
"doc_extraction_id": "2264351",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/11/27/44310/05/2733935.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "59219100",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2733935",
|
||||
"cve": "2733935",
|
||||
"shares_percent": 70,
|
||||
"source": "DO",
|
||||
"published_at": "2025-11-27",
|
||||
"doc_extraction_id": "2264351",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/11/27/44310/05/2733935.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "79559670",
|
||||
"target": "76632794",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76165184",
|
||||
"target": "79559670",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 50,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632707",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-09-02",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632794",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632793",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-04-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76243196",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2012-10-23",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76049214",
|
||||
"target": "17700725",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2016-04-08",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76243196",
|
||||
"target": "17700725",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_505687",
|
||||
"cve": "505687",
|
||||
"source": "DO",
|
||||
"doc_extraction_id": "1406518",
|
||||
"published_at": "2012-06-23",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/2012/06/23/505687_C_EIRL_20120623_firmado.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "17700725",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2479373",
|
||||
"cve": "2479373",
|
||||
"shares_percent": 25,
|
||||
"source": "DO",
|
||||
"published_at": "2024-04-13",
|
||||
"doc_extraction_id": "1678068",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/04/13/43825/05/2479373.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76109383",
|
||||
"target": "17700725",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_808751",
|
||||
"cve": "808751",
|
||||
"shares_percent": 50,
|
||||
"source": "DO",
|
||||
"published_at": "2014-08-21",
|
||||
"doc_extraction_id": "2270667",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/2014/08/21/808751_M_LTDA_20140821_firmado.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632707",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-09-02",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77963188",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2025-02-06",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632794",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632793",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "78714990",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "1995-07-18",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "78713520",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "1995-05-18",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "78296030",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "1995-05-18",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-04-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77791034",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2023-05-09",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76626600",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2006-09-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76249044",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2012-11-28",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76109383",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2010-08-20",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76162244",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2011-08-26",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76165184",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2019-07-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76049214",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2016-04-08",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "53331365",
|
||||
"target": "6288822",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2017-06-15",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76626600",
|
||||
"target": "6288822",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_799322",
|
||||
"cve": "799322",
|
||||
"source": "DO",
|
||||
"doc_extraction_id": "1685839",
|
||||
"published_at": "2014-07-25",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/2014/07/25/799322_M_LTDA_20140725_firmado.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "78713520",
|
||||
"target": "6288822",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "doh_id_2984726",
|
||||
"doh_extraction_id": "480765",
|
||||
"shares_percent": 95,
|
||||
"source": "DOH",
|
||||
"doh_id": "2984726",
|
||||
"published_at": "1995-04-06",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/1995/04/06/do-19950406.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "78296030",
|
||||
"target": "6288822",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_799318",
|
||||
"cve": "799318",
|
||||
"source": "DO",
|
||||
"doc_extraction_id": "1557120",
|
||||
"published_at": "2014-07-25",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/2014/07/25/799318_M_LTDA_20140725_firmado.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "6288822",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2479373",
|
||||
"cve": "2479373",
|
||||
"shares_percent": 25,
|
||||
"source": "DO",
|
||||
"published_at": "2024-04-13",
|
||||
"doc_extraction_id": "1678068",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/04/13/43825/05/2479373.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76249044",
|
||||
"target": "6288822",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "563766",
|
||||
"match_type": "bt_pn",
|
||||
"source": "DO",
|
||||
"published_at": "2012-11-17",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/2012/11/17/563766_C_SPA_20121117_firmado.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "99541230",
|
||||
"target": "6288822",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"match_type": "i_bt",
|
||||
"source": "DOH",
|
||||
"published_at": "2003-12-03",
|
||||
"doh_id": "6252959",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/media/2003/12/03/do-20031203.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632707",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-09-02",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632794",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632793",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-04-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77372997",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2021-05-26",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76239620",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2011-05-02",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76049214",
|
||||
"target": "16212300",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2009-03-03",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "16212300",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2479373",
|
||||
"cve": "2479373",
|
||||
"shares_percent": 25,
|
||||
"source": "DO",
|
||||
"published_at": "2024-04-13",
|
||||
"doc_extraction_id": "1678068",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/04/13/43825/05/2479373.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77372997",
|
||||
"target": "16212300",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "ACcGRVee0mFz",
|
||||
"source": "RES",
|
||||
"published_at": "2021-05-26"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632707",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-09-02",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632794",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632793",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-11-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2024-04-04",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77737301",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2023-03-14",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77695054",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2023-01-11",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77414574",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2021-07-19",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77320239",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2021-02-17",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76612946",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2016-04-21",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76239620",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2011-05-02",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76049214",
|
||||
"target": "17267165",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2009-03-03",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77881423",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2479373",
|
||||
"cve": "2479373",
|
||||
"shares_percent": 25,
|
||||
"source": "DO",
|
||||
"published_at": "2024-04-13",
|
||||
"doc_extraction_id": "1678068",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/04/13/43825/05/2479373.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77737301",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2288299",
|
||||
"cve": "2288299",
|
||||
"shares_percent": 50,
|
||||
"source": "DO",
|
||||
"published_at": "2023-03-22",
|
||||
"doc_extraction_id": "1956740",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2023/03/22/43508/05/2288299.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77414574",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_1981944",
|
||||
"cve": "1981944",
|
||||
"shares_percent": 100,
|
||||
"source": "DO",
|
||||
"published_at": "2021-07-23",
|
||||
"doc_extraction_id": "1597070",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2021/07/23/43009/05/1981944.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77320239",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_1898902",
|
||||
"cve": "1898902",
|
||||
"shares_percent": 100,
|
||||
"source": "DO",
|
||||
"published_at": "2021-02-19",
|
||||
"doc_extraction_id": "1823771",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2021/02/19/42885/05/1898902.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77695054",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "ACVgYG050Wid",
|
||||
"source": "RES",
|
||||
"published_at": "2024-05-08"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77695054",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "ACsp82eIi12n",
|
||||
"source": "RES",
|
||||
"published_at": "2023-01-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76633549",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "ACxkvJZLvZKs",
|
||||
"source": "RES"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76531048",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "ACKgOwuZ3Rrw",
|
||||
"source": "RES",
|
||||
"published_at": "2015-08-03"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76612946",
|
||||
"target": "17267165",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"cve": "ACHOUOkDmInm",
|
||||
"source": "RES",
|
||||
"published_at": "2016-04-21"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632794",
|
||||
"target": "77881423",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2572292",
|
||||
"cve": "2572292",
|
||||
"shares_percent": 100,
|
||||
"source": "DO",
|
||||
"published_at": "2024-11-20",
|
||||
"doc_extraction_id": "2135577",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/11/20/44003/05/2572292.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76049214",
|
||||
"target": "77881423",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2572668",
|
||||
"cve": "2572668",
|
||||
"shares_percent": 100,
|
||||
"source": "DO",
|
||||
"published_at": "2024-11-20",
|
||||
"doc_extraction_id": "1889820",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/11/20/44003/05/2572668.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632794",
|
||||
"target": "77881423",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76632793",
|
||||
"target": "77881423",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76049214",
|
||||
"target": "77881423",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "59219100",
|
||||
"target": "16365908",
|
||||
"label": "REPRESENTED_BY",
|
||||
"information_source": {
|
||||
"started_at": "2016-05-17",
|
||||
"source": "SII_REP"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77963188",
|
||||
"target": "59219100",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2580888",
|
||||
"cve": "2580888",
|
||||
"source": "DO",
|
||||
"doc_extraction_id": "1291559",
|
||||
"published_at": "2024-12-07",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2024/12/07/44018/05/2580888.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77963188",
|
||||
"target": "59219100",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "77590990",
|
||||
"target": "76632794",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2624458",
|
||||
"cve": "2624458",
|
||||
"shares_percent": 100,
|
||||
"source": "DO",
|
||||
"published_at": "2025-03-22",
|
||||
"doc_extraction_id": "1373489",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/03/22/44106/05/2624458.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76162244",
|
||||
"target": "76632794",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"pub_id": "cve_2624466",
|
||||
"cve": "2624466",
|
||||
"shares_percent": 100,
|
||||
"source": "DO",
|
||||
"published_at": "2025-03-22",
|
||||
"doc_extraction_id": "1370738",
|
||||
"url": "https://www.diariooficial.interior.gob.cl/publicaciones/2025/03/22/44106/05/2624466.pdf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76162244",
|
||||
"target": "76632794",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76239620",
|
||||
"target": "76632794",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 100,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "76165184",
|
||||
"target": "76152508",
|
||||
"label": "OWNED_BY",
|
||||
"information_source": {
|
||||
"shares_percent": 50,
|
||||
"source": "SII_REC_COM"
|
||||
}
|
||||
}
|
||||
],
|
||||
"entityNames": {
|
||||
"6288822": "EDUARDO RAFAEL LATORRE SALAS",
|
||||
"16212300": "FERNANDA DEL CARMEN LATORRE ARAYA",
|
||||
"16365908": "JOSE TOMAS LABBE FIGUEROA",
|
||||
"17267165": "EDUARDO PATRICIO LATORRE ARAYA",
|
||||
"17700725": "FELIPE ANDRES LATORRE ARAYA",
|
||||
"53331365": "CONDOMINIO PARQUE INDUSTRIAL LOS YACIMIENTOS",
|
||||
"59219100": "MANUCHAR NV",
|
||||
"76049214": "INVERSIONES LATORRE SPA",
|
||||
"76109383": "TRANSPORTES SOINVER LIMITADA",
|
||||
"76152508": "INVERSIONES CERAS LIMITADA",
|
||||
"76162244": "PROQUIEL TRANSPORTES QUIMICOS SPA",
|
||||
"76165184": "COMERCIALIZADORA PROCERAS S.A.",
|
||||
"76239620": "TRANSPORTES EDUARDO LATORRE Y COMPANIA SPA",
|
||||
"76243196": "COMERCIALIZADORA E IMPORTADORA FELIPE ANDRES LATORRE ARAYA E.I.R.L.",
|
||||
"76249044": "DOS E SPA",
|
||||
"76531048": "INTECH REMATES SPA",
|
||||
"76612946": "ALPHA MOTORS SPA",
|
||||
"76626600": "RENTAS SOINVER S A",
|
||||
"76632707": "INVERSIONES CARMEN SPA",
|
||||
"76632793": "INMOBILIARIA LATORRE UNO SPA",
|
||||
"76632794": "INVERSIONES NUEVA LATORRE SPA",
|
||||
"76633549": "LAVCAR SPA",
|
||||
"77320239": "INPARTS SPA",
|
||||
"77372997": "ESTUDIO K SPA",
|
||||
"77414574": "COMERCIALIZADORA REL SPA",
|
||||
"77590990": "TRANSPORTES LATORRE LIMITADA",
|
||||
"77695054": "T ACERCA SPA",
|
||||
"77737301": "INVERSIONES LATBAR SPA",
|
||||
"77791034": "COMERCIALIZADORA PINTURAS CUMBRES SPA",
|
||||
"77881423": "PARAPENTE SPA",
|
||||
"77963188": "PROQUIEL MANUCHAR SPA",
|
||||
"78296030": "SOINVER INGENIERIA S A",
|
||||
"78713520": "IMPORTADORA EDUARDO LATORRE Y CIA LTDA",
|
||||
"78714990": "INMOBILIARIA SOINVER DOS LTDA",
|
||||
"79559670": "PROQUIEL QUIMICOS SPA",
|
||||
"99541230": "SOUTH TRADING AND SERVICES S A"
|
||||
},
|
||||
"_cache_info": {
|
||||
"cached": true,
|
||||
"cache_key": "dequienes_cache:dequienes_relationships:966a5a06bf0ed9da5ce8d7a43a610cb117281cb3174a11d869d15f89313d6819",
|
||||
"retrieved_at": "2026-04-16T09:22:51.292584"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -268,6 +268,49 @@ app.use((err: Error, req: express.Request, res: express.Response, next: express.
|
|||
ELKService.info('Global error handling middleware registered');
|
||||
|
||||
// Start server
|
||||
const getEnvFlag = (name: string): boolean => {
|
||||
const rawExact = process.env[name];
|
||||
const raw =
|
||||
rawExact ??
|
||||
Object.entries(process.env).find(([key]) => key.trim() === name)?.[1];
|
||||
|
||||
if (!raw) return false;
|
||||
|
||||
const normalized = raw.trim().toLowerCase();
|
||||
return normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on';
|
||||
};
|
||||
|
||||
const rebuildMongoIndexes = async () => {
|
||||
if (mongoose.connection.readyState !== 1) {
|
||||
throw new Error('MongoDB is not connected');
|
||||
}
|
||||
|
||||
const models = Object.values(mongoose.models);
|
||||
ELKService.warn('REBUILD_MONGO_INDEX enabled: rebuilding MongoDB indexes', { models: models.length });
|
||||
|
||||
for (const model of models) {
|
||||
try {
|
||||
await model.collection.dropIndexes();
|
||||
} catch (error) {
|
||||
ELKService.warn('Failed to drop indexes for model', {
|
||||
model: model.modelName,
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await model.createIndexes();
|
||||
} catch (error) {
|
||||
ELKService.warn('Failed to create indexes for model', {
|
||||
model: model.modelName,
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ELKService.info('MongoDB indexes rebuild completed');
|
||||
};
|
||||
|
||||
const startServer = async () => {
|
||||
ELKService.info('Starting server...');
|
||||
try {
|
||||
|
|
@ -282,6 +325,10 @@ const startServer = async () => {
|
|||
await connectDB();
|
||||
ELKService.info('MongoDB connected successfully');
|
||||
|
||||
if (getEnvFlag('REBUILD_MONGO_INDEX')) {
|
||||
await rebuildMongoIndexes();
|
||||
}
|
||||
|
||||
// Initialize RabbitMQ and evaluation service (temporarily disabled for testing)
|
||||
try {
|
||||
await EvaluationService.initialize();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import mongoose, { Schema, Document } from 'mongoose';
|
||||
|
||||
const AI_OPERATION_LOG_TTL_SECONDS = (() => {
|
||||
const fallback = 86400;
|
||||
const parsed = Number.parseInt(process.env.AI_OPERATION_LOG_TTL_SECONDS || '', 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
})();
|
||||
|
||||
export interface IAIOperationLog extends Document {
|
||||
rut?: string;
|
||||
tenantId?: string;
|
||||
|
|
@ -82,6 +88,6 @@ AIOperationLogSchema.index({ rut: 1, createdAt: -1 });
|
|||
AIOperationLogSchema.index({ success: 1, createdAt: -1 });
|
||||
|
||||
// Add TTL index to automatically delete documents after 24 hours
|
||||
AIOperationLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: 86400 }); // 24 hours = 86400 seconds
|
||||
AIOperationLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: AI_OPERATION_LOG_TTL_SECONDS }); // 24 hours = 86400 seconds
|
||||
|
||||
export const AIOperationLog = mongoose.model<IAIOperationLog>('AIOperationLog', AIOperationLogSchema);
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import mongoose, { Schema, Document } from 'mongoose';
|
||||
|
||||
const CONSULTA_HISTORY_TTL_SECONDS = (() => {
|
||||
const fallback = 63072000;
|
||||
const parsed = Number.parseInt(process.env.CONSULTA_HISTORY_TTL_SECONDS || '', 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
})();
|
||||
|
||||
export interface IUserInfo {
|
||||
_id: string;
|
||||
name: string;
|
||||
|
|
@ -155,6 +161,6 @@ ConsultaHistorySchema.index({ tenantId: 1, responseStatus: 1, createdAt: -1 });
|
|||
ConsultaHistorySchema.index({ tenantId: 1, endpoint: 1, createdAt: -1 });
|
||||
|
||||
// TTL index to automatically delete old records after 2 years (730 days)
|
||||
ConsultaHistorySchema.index({ createdAt: 1 }, { expireAfterSeconds: 63072000 });
|
||||
ConsultaHistorySchema.index({ createdAt: 1 }, { expireAfterSeconds: CONSULTA_HISTORY_TTL_SECONDS });
|
||||
|
||||
export const ConsultaHistory = mongoose.model<IConsultaHistory>('ConsultaHistory', ConsultaHistorySchema);
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import mongoose, { Schema, Document } from 'mongoose';
|
||||
|
||||
const LOG_SHERIFF_DATA_TTL_SECONDS = (() => {
|
||||
const fallback = 86400;
|
||||
const parsed = Number.parseInt(process.env.LOG_SHERIFF_DATA_TTL_SECONDS || '', 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
})();
|
||||
|
||||
export interface IlogSherifData extends Document {
|
||||
sheriffLogData: any;
|
||||
}
|
||||
|
|
@ -9,6 +15,6 @@ const logSherifSchema: Schema = new Schema({
|
|||
}, { timestamps: true });
|
||||
|
||||
// Add TTL index to automatically delete documents after 24 hours
|
||||
logSherifSchema.index({ createdAt: 1 }, { expireAfterSeconds: 86400 }); // 24 hours = 86400 seconds
|
||||
logSherifSchema.index({ createdAt: 1 }, { expireAfterSeconds: LOG_SHERIFF_DATA_TTL_SECONDS }); // 24 hours = 86400 seconds
|
||||
|
||||
export const logSherifData = mongoose.model<IlogSherifData>('logSherifData', logSherifSchema);
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import mongoose, { Schema, Document } from 'mongoose';
|
||||
|
||||
const SHERIFF_API_CALL_LOG_TTL_SECONDS = (() => {
|
||||
const fallback = 86400;
|
||||
const parsed = Number.parseInt(process.env.SHERIFF_API_CALL_LOG_TTL_SECONDS || '', 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
})();
|
||||
|
||||
export interface ISheriffApiCallLog extends Document {
|
||||
rut: string;
|
||||
logId: mongoose.Types.ObjectId; // Reference to the main SheriffDataLog
|
||||
|
|
@ -24,6 +30,6 @@ const SheriffApiCallLogSchema: Schema = new Schema({
|
|||
}, { timestamps: { createdAt: true, updatedAt: false } }); // Only track creation time
|
||||
|
||||
// Add TTL index to automatically delete documents after 24 hours
|
||||
SheriffApiCallLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: 86400 }); // 24 hours = 86400 seconds
|
||||
SheriffApiCallLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: SHERIFF_API_CALL_LOG_TTL_SECONDS }); // 24 hours = 86400 seconds
|
||||
|
||||
export const SheriffApiCallLog = mongoose.model<ISheriffApiCallLog>('SheriffApiCallLog', SheriffApiCallLogSchema);
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import mongoose, { Schema, Document } from 'mongoose';
|
||||
|
||||
const SHERIFF_DATA_LOG_TTL_SECONDS = (() => {
|
||||
const fallback = 86400;
|
||||
const parsed = Number.parseInt(process.env.SHERIFF_DATA_LOG_TTL_SECONDS || '', 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
})();
|
||||
|
||||
// Define interfaces for the data from each Sheriff API call
|
||||
// These are placeholders and should be refined based on actual API responses if possible
|
||||
interface GenericApiResponseData { [key: string]: any; }
|
||||
|
|
@ -143,6 +149,6 @@ const SheriffDataLogSchema: Schema = new Schema({
|
|||
}, { timestamps: true }); // Adds createdAt and updatedAt
|
||||
|
||||
// Add TTL index to automatically delete documents after 24 hours
|
||||
SheriffDataLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: 86400 }); // 24 hours = 86400 seconds
|
||||
SheriffDataLogSchema.index({ createdAt: 1 }, { expireAfterSeconds: SHERIFF_DATA_LOG_TTL_SECONDS }); // 24 hours = 86400 seconds
|
||||
|
||||
export const SheriffDataLog = mongoose.model<ISheriffDataLog>('SheriffDataLog', SheriffDataLogSchema);
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
import React, { useEffect, useState, useMemo, useRef } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getResults, deleteResult } from '../services/api';
|
||||
import { getResults, deleteResult, apiClient } from '../services/api';
|
||||
import { IResult as IResultBackend } from '../../server/src/models/Result';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import logger from '../utils/logger';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
import { DocumentArrowDownIcon } from '@heroicons/react/24/outline';
|
||||
interface IResult extends IResultBackend {
|
||||
_id: string;
|
||||
createdAt: string;
|
||||
|
|
@ -16,6 +17,7 @@ interface IResult extends IResultBackend {
|
|||
}
|
||||
|
||||
const Consultas: React.FC = () => {
|
||||
const [loadingExportInfo, setLoadingExportInfo] = useState(false);
|
||||
const [allResults, setAllResults] = useState<IResult[]>([]);
|
||||
const [displayedResults, setDisplayedResults] = useState<IResult[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
|
@ -153,6 +155,353 @@ const Consultas: React.FC = () => {
|
|||
}
|
||||
return true;
|
||||
};
|
||||
const handleExportInfo = async () => {
|
||||
setLoadingExportInfo(true);
|
||||
try {
|
||||
// Cargar todos los RUTs de todas las páginas
|
||||
let allExportResults: IResult[] = [];
|
||||
let currentExportPage = 1;
|
||||
let exportTotalPages = totalPages;
|
||||
|
||||
while (currentExportPage <= exportTotalPages) {
|
||||
toast.loading(`Cargando página ${currentExportPage}/${exportTotalPages}`, { id: 'export-info-progress' });
|
||||
const response = await getResults({
|
||||
page: currentExportPage,
|
||||
limit: itemsPerPage,
|
||||
search: cleanRutForApi(debouncedSearch),
|
||||
sortField: undefined,
|
||||
sortDirection: undefined
|
||||
});
|
||||
if (response?.data && Array.isArray(response.data)) {
|
||||
allExportResults = [...allExportResults, ...(response.data as IResult[])];
|
||||
}
|
||||
exportTotalPages = response?.pagination?.totalPages || 1;
|
||||
currentExportPage++;
|
||||
}
|
||||
|
||||
// Filtrar con los filtros activos
|
||||
const filteredResults = allExportResults.filter(r => checkRowVisibility(r));
|
||||
|
||||
// Extraer RUTs únicos
|
||||
const uniqueRuts = Array.from(new Set(
|
||||
filteredResults.map(r => r.rut || r.details?.rut || '').filter(Boolean)
|
||||
));
|
||||
|
||||
if (uniqueRuts.length === 0) {
|
||||
toast.dismiss('export-info-progress');
|
||||
toast.error('No hay RUTs para consultar');
|
||||
setLoadingExportInfo(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const riskToColor: Record<string, string> = {
|
||||
critico: 'rojo', alto: 'naranjo', medio: 'amarillo', bajo: 'verde', no_disponible: 'gris',
|
||||
};
|
||||
|
||||
const calculateSemaphore = (c: { critical: number; high: number; low: number }) => {
|
||||
const total = c.critical + c.high + c.low;
|
||||
if (c.critical >= 1) return 'red';
|
||||
if (c.low === total && total > 0) return 'green';
|
||||
if (total > 0 && c.high / total >= 0.5) return 'red';
|
||||
if (total > 0 && c.high / total >= 0.3) return 'orange';
|
||||
return 'yellow';
|
||||
};
|
||||
|
||||
const semaphoreToColor: Record<string, string> = { red: 'rojo', orange: 'naranjo', yellow: 'amarillo', green: 'verde' };
|
||||
const semaphoreToLabel: Record<string, string> = { red: 'CRÍTICO', orange: 'ALTO', yellow: 'MEDIO', green: 'BAJO' };
|
||||
|
||||
const allRuleLabelsOrdered: string[] = [];
|
||||
const allRuleLabelsSet = new Set<string>();
|
||||
const allRutResponses: Array<{ rutValue: string; data: any }> = [];
|
||||
|
||||
for (let i = 0; i < uniqueRuts.length; i++) {
|
||||
const rutValue = uniqueRuts[i];
|
||||
try {
|
||||
toast.loading(`Consultando RUT ${i + 1}/${uniqueRuts.length}: ${rutValue}`, { id: 'export-info-progress' });
|
||||
|
||||
const response = await apiClient.get(`/rut/results/rut/${rutValue}`);
|
||||
allRutResponses.push({ rutValue, data: response.data });
|
||||
|
||||
const allRulesData = response.data?.riskAssessment?.allRules || {};
|
||||
for (const catKey of ['complianceRules', 'legalRules', 'capitalHumanoRules', 'financieroTributarioRules']) {
|
||||
const rules: any[] = allRulesData[catKey] || [];
|
||||
for (const rule of rules) {
|
||||
if (!allRuleLabelsSet.has(rule.label)) {
|
||||
allRuleLabelsSet.add(rule.label);
|
||||
allRuleLabelsOrdered.push(rule.label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allRuleLabelsSet.has('Causas Penales')) {
|
||||
allRuleLabelsSet.add('Causas Penales');
|
||||
allRuleLabelsOrdered.push('Causas Penales');
|
||||
}
|
||||
if (!allRuleLabelsSet.has('Reputación Pública y Mediática')) {
|
||||
allRuleLabelsSet.add('Reputación Pública y Mediática');
|
||||
allRuleLabelsOrdered.push('Reputación Pública y Mediática');
|
||||
}
|
||||
|
||||
if (i < uniqueRuts.length - 1) {
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Error RUT ${rutValue}:`, err);
|
||||
allRutResponses.push({ rutValue, data: null });
|
||||
}
|
||||
}
|
||||
|
||||
toast.dismiss('export-info-progress');
|
||||
toast.loading('Generando Excel...', { id: 'export-generating' });
|
||||
|
||||
const fixedHeaders = [
|
||||
'Razón Social', 'RUT', 'Fecha Evaluación',
|
||||
'Resultado Fast Check (color Semáforo)', 'Resultado Fast Check (Nivel de Riesgo)',
|
||||
'# parámetros riesgo crítico', '# parámetros riesgo alto', '# parámetros sin riesgo',
|
||||
];
|
||||
|
||||
const subCols = ['Impacto', 'Detectado', 'Riesgo', 'Cant. Detalles'];
|
||||
|
||||
const headerRow1: string[] = [...fixedHeaders];
|
||||
for (const label of allRuleLabelsOrdered) {
|
||||
headerRow1.push(label, '', '', '');
|
||||
}
|
||||
headerRow1.push('Resumen de hallazgos', '# hallazgos detectados');
|
||||
|
||||
const headerRow2: string[] = fixedHeaders.map(() => '');
|
||||
for (const _label of allRuleLabelsOrdered) {
|
||||
headerRow2.push(...subCols);
|
||||
}
|
||||
headerRow2.push('', '');
|
||||
|
||||
const columnTotals: Record<string, { detected: number; totalDetails: number }> = {};
|
||||
allRuleLabelsOrdered.forEach(l => { columnTotals[l] = { detected: 0, totalDetails: 0 }; });
|
||||
let totalCritical = 0, totalHigh = 0, totalLow = 0;
|
||||
|
||||
const dataRows: any[][] = [];
|
||||
|
||||
for (const { rutValue, data: d } of allRutResponses) {
|
||||
if (!d) {
|
||||
const row: any[] = ['Error al consultar', rutValue, '', '', '', 0, 0, 0];
|
||||
allRuleLabelsOrdered.forEach(() => { row.push('', '', '', ''); });
|
||||
row.push('Error al consultar', '');
|
||||
dataRows.push(row);
|
||||
continue;
|
||||
}
|
||||
|
||||
const razonSocial = d?.details?.razonSocial || 'N/A';
|
||||
const fechaEval = d?.createdAt ? new Date(d.createdAt).toLocaleDateString('es-CL') : 'N/A';
|
||||
const allRulesData = d?.riskAssessment?.allRules || {};
|
||||
|
||||
const ruleMap: Record<string, { detected: boolean; risk: string; impacto: string; detailCount: number; details: any }> = {};
|
||||
|
||||
for (const catKey of ['complianceRules', 'legalRules', 'capitalHumanoRules', 'financieroTributarioRules']) {
|
||||
const rules: any[] = allRulesData[catKey] || [];
|
||||
for (const rule of rules) {
|
||||
let details = rule.details;
|
||||
if (rule.label === 'Deuda Previsional Presunta' && details?.casos) {
|
||||
details = details.casos;
|
||||
}
|
||||
const detailCount = Array.isArray(details) ? details.length
|
||||
: (details && typeof details === 'object' && Object.keys(details).length > 0) ? 1
|
||||
: 0;
|
||||
|
||||
ruleMap[rule.label] = {
|
||||
detected: rule.detected || false,
|
||||
risk: rule.risk || 'bajo',
|
||||
impacto: rule.impacto || '',
|
||||
detailCount,
|
||||
details,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const todasCoincidencias =
|
||||
d?.sheriffLogData?.filteredDetails?.compliance?.penal?.coincidencias ||
|
||||
d?.details?.sheriffLogData?.filteredDetails?.compliance?.penal?.coincidencias ||
|
||||
d?.logEntry?.filteredDetails?.compliance?.penal?.coincidencias || [];
|
||||
const coincidenciasFiltradas = todasCoincidencias.filter((item: any) => {
|
||||
const postura = item?.postura?.toLowerCase() || '';
|
||||
return postura === 'demandado' || postura === 'querellado' || postura === 'denunciado';
|
||||
});
|
||||
ruleMap['Causas Penales'] = {
|
||||
detected: coincidenciasFiltradas.length > 0,
|
||||
risk: coincidenciasFiltradas.length > 0 ? 'critico' : 'bajo',
|
||||
impacto: 'severo',
|
||||
detailCount: coincidenciasFiltradas.length,
|
||||
details: coincidenciasFiltradas,
|
||||
};
|
||||
|
||||
const noticiasCoincidencias =
|
||||
d?.sheriffLogData?.filteredDetails?.compliance?.noticias?.coincidencias ||
|
||||
d?.details?.sheriffLogData?.filteredDetails?.compliance?.noticias?.coincidencias ||
|
||||
d?.logEntry?.filteredDetails?.compliance?.noticias?.coincidencias || [];
|
||||
ruleMap['Reputación Pública y Mediática'] = {
|
||||
detected: noticiasCoincidencias.length > 0,
|
||||
risk: noticiasCoincidencias.length > 0 ? 'alto' : 'bajo',
|
||||
impacto: 'significativo',
|
||||
detailCount: noticiasCoincidencias.length,
|
||||
details: noticiasCoincidencias,
|
||||
};
|
||||
|
||||
if (ruleMap['Deuda Previsional Presunta']?.detailCount > 0) {
|
||||
ruleMap['Deuda Previsional Presunta'].risk = 'alto';
|
||||
ruleMap['Deuda Previsional Presunta'].detected = true;
|
||||
}
|
||||
|
||||
if (ruleMap['Inicio de Actividades']) {
|
||||
const ia = ruleMap['Inicio de Actividades'];
|
||||
ia.detected = !ia.detected;
|
||||
ia.risk = ia.detected ? 'alto' : 'bajo';
|
||||
}
|
||||
|
||||
let critical = 0, high = 0, low = 0;
|
||||
for (const label of allRuleLabelsOrdered) {
|
||||
const r = ruleMap[label];
|
||||
if (!r || r.risk === 'no_disponible') continue;
|
||||
if (r.risk === 'critico') critical++;
|
||||
else if (r.risk === 'alto') high++;
|
||||
else low++;
|
||||
}
|
||||
|
||||
const semaphore = calculateSemaphore({ critical, high, low });
|
||||
totalCritical += critical;
|
||||
totalHigh += high;
|
||||
totalLow += low;
|
||||
|
||||
const row: any[] = [
|
||||
razonSocial, rutValue, fechaEval,
|
||||
semaphoreToColor[semaphore] || '', semaphoreToLabel[semaphore] || '',
|
||||
critical, high, low,
|
||||
];
|
||||
|
||||
for (const label of allRuleLabelsOrdered) {
|
||||
const r = ruleMap[label];
|
||||
if (r) {
|
||||
const impactoCapitalized = r.impacto ? r.impacto.charAt(0).toUpperCase() + r.impacto.slice(1) : '';
|
||||
row.push(
|
||||
impactoCapitalized,
|
||||
r.detected ? 'Sí' : 'No',
|
||||
riskToColor[r.risk] || r.risk,
|
||||
r.detailCount > 0 ? r.detailCount : '',
|
||||
);
|
||||
|
||||
if (r.detected && r.risk !== 'bajo' && r.risk !== 'no_disponible') {
|
||||
columnTotals[label].detected++;
|
||||
}
|
||||
columnTotals[label].totalDetails += r.detailCount;
|
||||
} else {
|
||||
row.push('', '', '', '');
|
||||
}
|
||||
}
|
||||
|
||||
const hallazgos: string[] = [];
|
||||
for (const label of allRuleLabelsOrdered) {
|
||||
const r = ruleMap[label];
|
||||
if (!r || !r.detected || r.risk === 'bajo' || r.risk === 'no_disponible') continue;
|
||||
|
||||
const color = riskToColor[r.risk] || r.risk;
|
||||
let detail = `${label} (${color})`;
|
||||
if (r.detailCount > 0) detail += `: ${r.detailCount} hallazgo${r.detailCount > 1 ? 's' : ''}`;
|
||||
|
||||
if (['Multas Laborales', 'Deuda Previsional Publicada', 'Protestos y Morosidades', 'Condenas por Prácticas Antisindicales'].includes(label) && Array.isArray(r.details)) {
|
||||
let monto = 0;
|
||||
r.details.forEach((item: any) => {
|
||||
const m = item?.monto || item?.Monto || item?.montoMulta || item?.['Monto Multa'] || item?.unpaidAmount || 0;
|
||||
monto += typeof m === 'number' ? m : parseFloat(String(m).replace(/[^0-9.-]/g, '')) || 0;
|
||||
});
|
||||
if (monto > 0) detail += ` | Monto: $${Math.round(monto).toLocaleString('es-CL')}`;
|
||||
}
|
||||
|
||||
if (['Causas Civiles', 'Causas Laborales', 'Causas de Cobranza Laboral'].includes(label) && Array.isArray(r.details)) {
|
||||
let vigentes = 0, concluidas = 0;
|
||||
r.details.forEach((item: any) => {
|
||||
const estado = String(item?.estado || '').toLowerCase();
|
||||
if (estado.includes('vigente')) vigentes++;
|
||||
else if (estado.includes('concluida') || estado.includes('concluido')) concluidas++;
|
||||
});
|
||||
detail += ` | Vigentes: ${vigentes}, Concluidas: ${concluidas}`;
|
||||
}
|
||||
|
||||
if (label === 'Causas Penales' && Array.isArray(r.details)) {
|
||||
const posturas: Record<string, number> = {};
|
||||
r.details.forEach((item: any) => {
|
||||
const p = (item?.postura || '').toLowerCase().trim();
|
||||
if (p) posturas[p] = (posturas[p] || 0) + 1;
|
||||
});
|
||||
const parts = Object.entries(posturas).map(([k, v]) => `${k}: ${v}`);
|
||||
if (parts.length > 0) detail += ` | ${parts.join(', ')}`;
|
||||
}
|
||||
|
||||
if (label === 'Deuda Previsional Presunta' && r.detailCount > 0) {
|
||||
detail += ` | ${r.detailCount} afiliado${r.detailCount > 1 ? 's' : ''}`;
|
||||
}
|
||||
|
||||
hallazgos.push(detail);
|
||||
}
|
||||
|
||||
row.push(hallazgos.join('\n'), hallazgos.length > 0 ? hallazgos.length : '');
|
||||
dataRows.push(row);
|
||||
}
|
||||
|
||||
const totalsRow: any[] = [
|
||||
'TOTALES', `${uniqueRuts.length} RUTs`, '', '', '',
|
||||
totalCritical, totalHigh, totalLow,
|
||||
];
|
||||
for (const label of allRuleLabelsOrdered) {
|
||||
const ct = columnTotals[label];
|
||||
totalsRow.push(
|
||||
'',
|
||||
ct.detected > 0 ? `${ct.detected} RUTs` : '',
|
||||
'',
|
||||
ct.totalDetails > 0 ? ct.totalDetails : '',
|
||||
);
|
||||
}
|
||||
totalsRow.push('', '');
|
||||
|
||||
const wb = XLSX.utils.book_new();
|
||||
const allRows = [headerRow1, headerRow2, ...dataRows, totalsRow];
|
||||
const ws = XLSX.utils.aoa_to_sheet(allRows);
|
||||
|
||||
const merges: XLSX.Range[] = [];
|
||||
let colIdx = fixedHeaders.length;
|
||||
for (const _label of allRuleLabelsOrdered) {
|
||||
merges.push({
|
||||
s: { r: 0, c: colIdx },
|
||||
e: { r: 0, c: colIdx + 3 },
|
||||
});
|
||||
colIdx += 4;
|
||||
}
|
||||
ws['!merges'] = merges;
|
||||
|
||||
const colWidths: { wch: number }[] = [
|
||||
{ wch: 40 }, { wch: 16 }, { wch: 16 },
|
||||
{ wch: 14 }, { wch: 14 },
|
||||
{ wch: 12 }, { wch: 12 }, { wch: 12 },
|
||||
];
|
||||
for (const _label of allRuleLabelsOrdered) {
|
||||
colWidths.push({ wch: 14 }, { wch: 12 }, { wch: 12 }, { wch: 14 });
|
||||
}
|
||||
colWidths.push({ wch: 80 }, { wch: 12 });
|
||||
ws['!cols'] = colWidths;
|
||||
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'Reporte');
|
||||
|
||||
const fileName = `Reporte_FastCheck_Consultas_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
||||
XLSX.writeFile(wb, fileName);
|
||||
|
||||
toast.dismiss('export-generating');
|
||||
const conRiesgo = dataRows.filter(r => (r[5] as number) > 0).length;
|
||||
toast.success(`Excel generado: ${uniqueRuts.length} RUTs, ${conRiesgo} con riesgo crítico`);
|
||||
} catch (error) {
|
||||
toast.dismiss('export-info-progress');
|
||||
toast.dismiss('export-generating');
|
||||
console.error('Error generating Excel:', error);
|
||||
toast.error('Error al generar el Excel');
|
||||
} finally {
|
||||
setLoadingExportInfo(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchResults = async () => {
|
||||
|
|
@ -620,6 +969,14 @@ const Consultas: React.FC = () => {
|
|||
>
|
||||
{isExporting ? `Exportando ${exportProgress}%` : 'Exportar Excel'}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleExportInfo}
|
||||
disabled={loadingExportInfo}
|
||||
className={`px-4 py-2 rounded-md text-white transition-colors flex items-center gap-2 ${loadingExportInfo ? 'bg-blue-800 cursor-not-allowed' : 'bg-blue-600 hover:bg-blue-700'}`}
|
||||
>
|
||||
<DocumentArrowDownIcon className="h-5 w-5" />
|
||||
{loadingExportInfo ? 'Exportando info RUTs...' : 'Exportar Excel Info RUTs'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ const FastCheck: React.FC = () => {
|
|||
'Causas Civiles': ['Fecha de ingreso', 'Fecha', 'postura', 'Postura', 'estado', 'Estado', 'fase', 'Fase', 'etapa', 'Etapa', 'materia', 'Materia', 'rol', 'ROL', 'tribunal', 'Tribunal'],
|
||||
'Causas Laborales': ['fecha', 'Fecha', 'postura', 'Postura', 'estado', 'Estado', 'fase', 'Fase', 'etapa', 'Etapa', 'materia', 'Materia', 'rol', 'ROL', 'tribunal', 'Tribunal'],
|
||||
'Causas de Cobranza Laboral': ['fecha', 'Fecha', 'postura', 'Postura', 'estado', 'Estado', 'fase', 'Fase', 'etapa', 'Etapa', 'materia', 'Materia', 'rol', 'ROL', 'tribunal', 'Tribunal'],
|
||||
'Causas Penales': ['nombre', 'Nombre', 'postura', 'Postura', 'rol', 'ROL', 'fecha', 'Fecha', 'infraccion', 'Infracción', 'estado', 'Estado', 'etapa', 'Etapa', 'materia', 'Materia', 'tribunal', 'Tribunal'],
|
||||
'Inicio de Actividades': ['activities', 'category', 'ivaAffection'],
|
||||
'PEP Chile': ['rut', 'name', 'count'],
|
||||
'Familiares PEP': ['rut', 'name', 'count']
|
||||
|
|
@ -2366,99 +2367,22 @@ const FastCheck: React.FC = () => {
|
|||
|
||||
for (const section of normalSections) {
|
||||
const heading = section.querySelector('h2');
|
||||
if (heading && heading.textContent?.trim() === 'Resumen') {
|
||||
const headerDiv = section.querySelector('.flex.items-center.justify-between.mb-4');
|
||||
const gridContainer = section.querySelector('.grid.grid-cols-\\[auto_auto\\]');
|
||||
|
||||
if (headerDiv && gridContainer) {
|
||||
const headerImgData = await captureElementInIframe(headerDiv as HTMLElement);
|
||||
const headerImg = new Image();
|
||||
await new Promise((resolve) => {
|
||||
headerImg.onload = resolve;
|
||||
headerImg.src = headerImgData;
|
||||
});
|
||||
const headerImgWidth = contentWidth;
|
||||
const headerImgHeight = (headerImg.height * headerImgWidth) / headerImg.width;
|
||||
|
||||
const resumenCards = gridContainer.querySelectorAll('.border.border-gray-500.rounded-lg.overflow-hidden');
|
||||
let firstRowHeight = 0;
|
||||
|
||||
if (resumenCards.length > 0) {
|
||||
const firstRowDiv = document.createElement('div');
|
||||
firstRowDiv.className = 'grid grid-cols-[auto_auto] gap-4';
|
||||
firstRowDiv.style.width = '100%';
|
||||
|
||||
const card1 = resumenCards[0].cloneNode(true) as HTMLElement;
|
||||
firstRowDiv.appendChild(card1);
|
||||
|
||||
if (resumenCards.length > 1) {
|
||||
const card2 = resumenCards[1].cloneNode(true) as HTMLElement;
|
||||
firstRowDiv.appendChild(card2);
|
||||
}
|
||||
|
||||
const firstRowImgData = await captureElementInIframe(firstRowDiv);
|
||||
const firstRowImg = new Image();
|
||||
await new Promise((resolve) => {
|
||||
firstRowImg.onload = resolve;
|
||||
firstRowImg.src = firstRowImgData;
|
||||
});
|
||||
|
||||
firstRowHeight = (firstRowImg.height * contentWidth) / firstRowImg.width;
|
||||
}
|
||||
|
||||
const minHeightNeeded = headerImgHeight + firstRowHeight + 20;
|
||||
const spaceAvailable = pageHeight - margin - 25 - currentY;
|
||||
|
||||
if (minHeightNeeded > spaceAvailable) {
|
||||
if (heading && heading.textContent?.trim().includes('Resumen')) {
|
||||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.addImage(headerImgData, 'JPEG', margin, currentY, headerImgWidth, headerImgHeight);
|
||||
currentY += headerImgHeight + 5;
|
||||
}
|
||||
|
||||
if (gridContainer) {
|
||||
const resumenCards = gridContainer.querySelectorAll('.border.border-gray-300.rounded-lg.overflow-hidden');
|
||||
|
||||
for (let i = 0; i < resumenCards.length; i += 2) {
|
||||
const rowDiv = document.createElement('div');
|
||||
rowDiv.className = 'grid grid-cols-[auto_auto] gap-4';
|
||||
rowDiv.style.width = '100%';
|
||||
|
||||
const card1 = resumenCards[i].cloneNode(true) as HTMLElement;
|
||||
rowDiv.appendChild(card1);
|
||||
|
||||
if (i + 1 < resumenCards.length) {
|
||||
const card2 = resumenCards[i + 1].cloneNode(true) as HTMLElement;
|
||||
rowDiv.appendChild(card2);
|
||||
}
|
||||
|
||||
const rowImgData = await captureElementInIframe(rowDiv);
|
||||
|
||||
const rowImg = new Image();
|
||||
const imgData = await captureElementInIframe(section);
|
||||
const tempImg = new Image();
|
||||
await new Promise((resolve) => {
|
||||
rowImg.onload = resolve;
|
||||
rowImg.src = rowImgData;
|
||||
tempImg.onload = resolve;
|
||||
tempImg.src = imgData;
|
||||
});
|
||||
|
||||
const rowImgWidth = contentWidth;
|
||||
const rowImgHeight = (rowImg.height * rowImgWidth) / rowImg.width;
|
||||
|
||||
if (currentY + rowImgHeight > pageHeight - margin - 15) {
|
||||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.addImage(rowImgData, 'JPEG', margin, currentY, rowImgWidth, rowImgHeight);
|
||||
currentY += rowImgHeight + 6;
|
||||
}
|
||||
}
|
||||
|
||||
const imgHeight = (tempImg.height * contentWidth) / tempImg.width;
|
||||
pdf.addImage(imgData, 'JPEG', margin, currentY, contentWidth, imgHeight);
|
||||
currentY += imgHeight + 5;
|
||||
continue;
|
||||
}
|
||||
|
||||
// ── MeshTable: guardar para el final del PDF ──────────────────────
|
||||
// ── MeshTable: guardar para el final del PDF ──────────────────────
|
||||
const meshEl = section.querySelector('[data-pdf="mesh-table"]') as HTMLElement | null;
|
||||
|
||||
|
|
@ -2587,12 +2511,16 @@ const FastCheck: React.FC = () => {
|
|||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
// Círculo azul (bullet)
|
||||
pdf.setFillColor(59, 130, 246);
|
||||
pdf.circle(margin + 2, currentY - 1.5, 2.5, "F");
|
||||
|
||||
pdf.setFontSize(20);
|
||||
// Texto del título
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text("Detalles de hallazgos", margin, currentY);
|
||||
currentY += 12;
|
||||
pdf.text("Detalles de hallazgos", margin + 7, currentY);
|
||||
currentY += 7;
|
||||
|
||||
// ====== CONSTRUIR SECCIONES DESDE riskSummary ======
|
||||
const tableSections: Array<{
|
||||
|
|
@ -2836,7 +2764,7 @@ const FastCheck: React.FC = () => {
|
|||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
pdf.setFontSize(14);
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h3Title, margin, currentY);
|
||||
|
|
@ -2849,13 +2777,13 @@ const FastCheck: React.FC = () => {
|
|||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.setFontSize(11);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h4Title, margin, currentY);
|
||||
currentY += 8;
|
||||
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "normal");
|
||||
pdf.setTextColor(55, 65, 81);
|
||||
pdf.text('Rut no presenta registros de Inicio de Actividades', margin, currentY);
|
||||
|
|
@ -2890,7 +2818,7 @@ const FastCheck: React.FC = () => {
|
|||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
pdf.setFontSize(14);
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h3Title, margin, currentY);
|
||||
|
|
@ -2903,13 +2831,13 @@ const FastCheck: React.FC = () => {
|
|||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.setFontSize(11);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h4Title, margin, currentY);
|
||||
currentY += 8;
|
||||
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "normal");
|
||||
pdf.setTextColor(55, 65, 81);
|
||||
pdf.text("Tiene Quiebra Judicial en Tribunales", margin, currentY);
|
||||
|
|
@ -2956,7 +2884,7 @@ const FastCheck: React.FC = () => {
|
|||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
pdf.setFontSize(14);
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h3Title, margin, currentY);
|
||||
|
|
@ -2969,13 +2897,13 @@ const FastCheck: React.FC = () => {
|
|||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.setFontSize(11);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h4Title, margin, currentY);
|
||||
currentY += 8;
|
||||
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "normal");
|
||||
pdf.setTextColor(55, 65, 81);
|
||||
pdf.text(specialCaseMessage, margin, currentY);
|
||||
|
|
@ -3001,7 +2929,7 @@ const FastCheck: React.FC = () => {
|
|||
pdf.addPage();
|
||||
await addPageHeaderImage();
|
||||
}
|
||||
pdf.setFontSize(14);
|
||||
pdf.setFontSize(10);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h3Title, margin, currentY);
|
||||
|
|
@ -3014,7 +2942,7 @@ const FastCheck: React.FC = () => {
|
|||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.setFontSize(11);
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text(h4Title, margin, currentY);
|
||||
|
|
@ -3099,7 +3027,7 @@ const FastCheck: React.FC = () => {
|
|||
};
|
||||
|
||||
const drawTableHeader = async () => {
|
||||
pdf.setFontSize(9);
|
||||
pdf.setFontSize(8);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(55, 65, 81);
|
||||
|
||||
|
|
@ -3155,7 +3083,7 @@ const FastCheck: React.FC = () => {
|
|||
|
||||
for (const row of normalizedData) {
|
||||
pdf.setFont("helvetica", "normal");
|
||||
pdf.setFontSize(8);
|
||||
pdf.setFontSize(7);
|
||||
pdf.setTextColor(17, 24, 39);
|
||||
|
||||
let maxLines = 1;
|
||||
|
|
@ -3203,7 +3131,7 @@ const FastCheck: React.FC = () => {
|
|||
await drawTableHeader();
|
||||
|
||||
pdf.setFont("helvetica", "normal");
|
||||
pdf.setFontSize(8);
|
||||
pdf.setFontSize(7);
|
||||
pdf.setTextColor(17, 24, 39);
|
||||
}
|
||||
|
||||
|
|
@ -3255,11 +3183,19 @@ const FastCheck: React.FC = () => {
|
|||
await addPageHeaderImage();
|
||||
}
|
||||
|
||||
pdf.setFontSize(20);
|
||||
|
||||
// Círculo azul (bullet)
|
||||
pdf.setFillColor(59, 130, 246);
|
||||
pdf.circle(margin + 2, currentY - 1.5, 2.5, "F");
|
||||
|
||||
// Texto del título
|
||||
pdf.setFontSize(11);
|
||||
pdf.setFont("helvetica", "bold");
|
||||
pdf.setTextColor(59, 130, 246);
|
||||
pdf.text("Malla Relacional", margin, currentY);
|
||||
currentY += 12;
|
||||
pdf.text("Malla Relacional Detalles", margin + 7, currentY);
|
||||
currentY += 7;
|
||||
|
||||
|
||||
|
||||
// Capturar encabezado del MeshTable (sin tablas)
|
||||
const meshClone = deferredMeshEl.cloneNode(true) as HTMLElement;
|
||||
|
|
@ -3607,17 +3543,17 @@ const FastCheck: React.FC = () => {
|
|||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 ">
|
||||
<div className="border-r pr-4">
|
||||
<div className="border-r pr-2 flex flex-col items-start justify-end">
|
||||
<p className="font-bold dark:text-white">Razón Social:</p>
|
||||
<p className="dark:text-gray-300">{companyData.razonSocial}</p>
|
||||
<p className="text-xl dark:text-gray-300">{companyData.razonSocial}</p>
|
||||
</div>
|
||||
<div className="border-r pr-4">
|
||||
<div className="border-r pr-2 flex flex-col items-start justify-end">
|
||||
<p className="font-bold dark:text-white">Rut / ID:</p>
|
||||
<p className="dark:text-gray-300">{companyData.rut}</p>
|
||||
<p className="text-xl dark:text-gray-300">{companyData.rut}</p>
|
||||
</div>
|
||||
<div className="border-r pr-4">
|
||||
<div className="border-r pr-2 flex flex-col items-start justify-end">
|
||||
<p className="font-bold dark:text-white">Fecha Evaluación:</p>
|
||||
<p className="dark:text-gray-300">{companyData.fechaEvaluacion}</p>
|
||||
<p className="text-xl dark:text-gray-300">{companyData.fechaEvaluacion}</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<div className={`w-16 h-16 rounded-full ${getSemaphoreColor(calculateSemaphore(count))}`}></div>
|
||||
|
|
|
|||
|
|
@ -829,6 +829,13 @@ const AdminResultsPage: React.FC = () => {
|
|||
</div>
|
||||
{!allPagesLoaded && (
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => setPage(1)}
|
||||
disabled={page === 1}
|
||||
className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 transition-colors"
|
||||
>
|
||||
Primera
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setPage(page - 1)}
|
||||
disabled={page === 1}
|
||||
|
|
@ -843,6 +850,13 @@ const AdminResultsPage: React.FC = () => {
|
|||
>
|
||||
{t('common.next', 'Siguiente')}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setPage(totalPages)}
|
||||
disabled={page === totalPages}
|
||||
className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 transition-colors"
|
||||
>
|
||||
Última
|
||||
</button>
|
||||
<select
|
||||
value={limit}
|
||||
onChange={(e) => setLimit(parseInt(e.target.value, 10))}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,11 @@ const formatJsonToMarkdown = (data: Record<string, any>): string => {
|
|||
};
|
||||
|
||||
const SingleEvaluation: React.FC = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [rut, setRut] = useState('');
|
||||
const [formattedRut, setFormattedRut] = useState('');
|
||||
|
|
@ -153,23 +158,21 @@ const SingleEvaluation: React.FC = () => {
|
|||
// Estado para el modal de créditos agotados
|
||||
const [showNoCreditsDialog, setShowNoCreditsDialog] = useState(false);
|
||||
|
||||
const { tenant } = useTenant();
|
||||
const { tenant, loading: tenantLoading, updateTenant } = useTenant();
|
||||
const availableCredits = tenant?.creditBalance?.availableCredits || 0;
|
||||
const navigate = useNavigate(); // Kept if navigation is needed post-operation
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Efecto para mostrar el modal si no hay créditos al iniciar
|
||||
useEffect(() => {
|
||||
if (availableCredits === 0) {
|
||||
if (!tenantLoading && tenant && availableCredits === 0) {
|
||||
setShowNoCreditsDialog(true);
|
||||
}
|
||||
}, [availableCredits]);
|
||||
}, [availableCredits, tenantLoading, tenant]);
|
||||
|
||||
const handleCloseNoCreditsDialog = () => {
|
||||
setShowNoCreditsDialog(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Clear results when RUT changes after a submission
|
||||
if (markdownResult || processError) {
|
||||
setMarkdownResult(null);
|
||||
setDownloadablePdfs([]);
|
||||
|
|
@ -343,6 +346,7 @@ const SingleEvaluation: React.FC = () => {
|
|||
<div>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">{t('singleEvaluation.reportLabel')}</p>
|
||||
<h1 className="text-3xl font-bold text-gray-900 dark:text-white">{t('singleEvaluation.title')}</h1>
|
||||
<h3 className="text-2xl font-bold text-gray-900 dark:text-white"> <span>Creditos disponibles:</span> {availableCredits}</h3>
|
||||
</div>
|
||||
<div className="mt-4 sm:mt-0 flex items-center space-x-2">
|
||||
<button
|
||||
|
|
@ -408,8 +412,7 @@ const SingleEvaluation: React.FC = () => {
|
|||
value={formattedRut}
|
||||
onChange={handleRutChange}
|
||||
placeholder={t('singleEvaluation.rutPlaceholder')}
|
||||
className={`w-full pl-3 pr-10 py-2 border rounded-md shadow-sm text-sm bg-white dark:bg-gray-700 ${
|
||||
isValidRut === false
|
||||
className={`w-full pl-3 pr-10 py-2 border rounded-md shadow-sm text-sm bg-white dark:bg-gray-700 ${isValidRut === false
|
||||
? 'border-red-500 text-red-900 dark:text-red-200 focus:ring-red-500 focus:border-red-500'
|
||||
: isValidRut === true
|
||||
? 'border-green-500 text-green-900 dark:text-green-200 focus:ring-green-500 focus:border-green-500'
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user