@mcpassure/mcp-anvisa-bulario 0.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap.d.ts +11 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +120 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/config.d.ts +10 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -12
- package/dist/config.js.map +1 -1
- package/dist/db/dataset.d.ts +15 -0
- package/dist/db/dataset.d.ts.map +1 -0
- package/dist/db/dataset.js +168 -0
- package/dist/db/dataset.js.map +1 -0
- package/dist/db/schema.d.ts +11 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +48 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/domain/repository.d.ts +11 -5
- package/dist/domain/repository.d.ts.map +1 -1
- package/dist/domain/repository.js +38 -58
- package/dist/domain/repository.js.map +1 -1
- package/dist/index.js +15 -14
- package/dist/index.js.map +1 -1
- package/dist/schemas/tools.d.ts +4 -4
- package/dist/server.js +1 -1
- package/dist/tools/consultar-bula.d.ts +10 -0
- package/dist/tools/consultar-bula.d.ts.map +1 -1
- package/dist/tools/consultar-bula.js +41 -23
- package/dist/tools/consultar-bula.js.map +1 -1
- package/dist/tools/listar-apresentacoes.d.ts +7 -0
- package/dist/tools/listar-apresentacoes.d.ts.map +1 -1
- package/dist/tools/listar-apresentacoes.js +26 -8
- package/dist/tools/listar-apresentacoes.js.map +1 -1
- package/dist/tools/shared.d.ts +20 -11
- package/dist/tools/shared.d.ts.map +1 -1
- package/dist/tools/shared.js +50 -10
- package/dist/tools/shared.js.map +1 -1
- package/dist/utils/http.d.ts +12 -33
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/http.js +15 -167
- package/dist/utils/http.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function getDbPath(): string;
|
|
2
|
+
export type BootstrapResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
action: "downloaded" | "up_to_date" | "skipped_offline";
|
|
5
|
+
version: string;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
reason: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function ensureDataset(): Promise<BootstrapResult>;
|
|
11
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAoCA,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAuDD,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,YAAY,GAAG,YAAY,GAAG,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtF;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,wBAAsB,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC,CAwE9D"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { AwsClient } from "aws4fetch";
|
|
7
|
+
const DATASET = "anvisa-bulario";
|
|
8
|
+
const BUCKET = "mcpassure-datasets";
|
|
9
|
+
const MANIFEST_KEY = `bulario/latest/manifest.json`;
|
|
10
|
+
function getDataDir() {
|
|
11
|
+
return process.platform === "win32"
|
|
12
|
+
? join(process.env.APPDATA ?? homedir(), "mcpassure", DATASET)
|
|
13
|
+
: join(process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), "mcpassure", DATASET);
|
|
14
|
+
}
|
|
15
|
+
export function getDbPath() {
|
|
16
|
+
return process.env.MCPASSURE_DB_PATH ?? join(getDataDir(), "bulario.db");
|
|
17
|
+
}
|
|
18
|
+
function getLocalManifestPath() {
|
|
19
|
+
return join(getDataDir(), "manifest.json");
|
|
20
|
+
}
|
|
21
|
+
function log(msg) {
|
|
22
|
+
process.stderr.write(`[bootstrap] ${msg}\n`);
|
|
23
|
+
}
|
|
24
|
+
async function fetchManifest(client, endpoint) {
|
|
25
|
+
const url = `${endpoint}/${BUCKET}/${MANIFEST_KEY}`;
|
|
26
|
+
const resp = await client.fetch(url);
|
|
27
|
+
if (!resp.ok) {
|
|
28
|
+
throw new Error(`HTTP ${resp.status} ao buscar manifest em ${url}`);
|
|
29
|
+
}
|
|
30
|
+
return (await resp.json());
|
|
31
|
+
}
|
|
32
|
+
async function downloadAndVerify(client, endpoint, manifest, targetPath) {
|
|
33
|
+
const url = `${endpoint}/${manifest.artifact.bucket}/${manifest.artifact.key}`;
|
|
34
|
+
const tmp = `${targetPath}.download`;
|
|
35
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
36
|
+
log(`Baixando ${url} (${(manifest.artifact.size_bytes / 1024 / 1024).toFixed(1)} MB)...`);
|
|
37
|
+
const resp = await client.fetch(url);
|
|
38
|
+
if (!resp.ok) {
|
|
39
|
+
throw new Error(`HTTP ${resp.status} ao baixar artifact ${url}`);
|
|
40
|
+
}
|
|
41
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
42
|
+
if (buf.length !== manifest.artifact.size_bytes) {
|
|
43
|
+
throw new Error(`Tamanho inesperado. Esperado ${manifest.artifact.size_bytes}, recebido ${buf.length}.`);
|
|
44
|
+
}
|
|
45
|
+
const hash = createHash("sha256").update(buf).digest("hex");
|
|
46
|
+
if (hash.toLowerCase() !== manifest.artifact.sha256.toLowerCase()) {
|
|
47
|
+
throw new Error(`Checksum SHA-256 não bate. Esperado ${manifest.artifact.sha256}, recebido ${hash}.`);
|
|
48
|
+
}
|
|
49
|
+
await writeFile(tmp, buf);
|
|
50
|
+
await rename(tmp, targetPath);
|
|
51
|
+
log(`Download concluído. SHA-256 validado.`);
|
|
52
|
+
}
|
|
53
|
+
export async function ensureDataset() {
|
|
54
|
+
const dbPath = getDbPath();
|
|
55
|
+
const manifestPath = getLocalManifestPath();
|
|
56
|
+
const dbExists = existsSync(dbPath);
|
|
57
|
+
const accessKey = process.env.MCPASSURE_R2_ACCESS_KEY_ID;
|
|
58
|
+
const secretKey = process.env.MCPASSURE_R2_SECRET_ACCESS_KEY;
|
|
59
|
+
const endpoint = process.env.MCPASSURE_R2_ENDPOINT;
|
|
60
|
+
if (!accessKey || !secretKey || !endpoint) {
|
|
61
|
+
if (dbExists) {
|
|
62
|
+
log("Credenciais R2 ausentes — usando cache local existente.");
|
|
63
|
+
return { ok: true, action: "skipped_offline", version: "local" };
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
reason: "Cache local inexistente e credenciais R2 ausentes. " +
|
|
68
|
+
"Configure MCPASSURE_R2_ACCESS_KEY_ID, MCPASSURE_R2_SECRET_ACCESS_KEY e MCPASSURE_R2_ENDPOINT, " +
|
|
69
|
+
"ou execute `npm run sync` para popular o dataset local.",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const client = new AwsClient({
|
|
73
|
+
accessKeyId: accessKey,
|
|
74
|
+
secretAccessKey: secretKey,
|
|
75
|
+
service: "s3",
|
|
76
|
+
region: "auto",
|
|
77
|
+
});
|
|
78
|
+
let remoteManifest;
|
|
79
|
+
try {
|
|
80
|
+
remoteManifest = await fetchManifest(client, endpoint);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
84
|
+
if (dbExists) {
|
|
85
|
+
log(`Falha ao buscar manifest remoto (${reason}). Usando cache local.`);
|
|
86
|
+
return { ok: true, action: "skipped_offline", version: "stale" };
|
|
87
|
+
}
|
|
88
|
+
return { ok: false, reason: `Sem cache e sem rede: ${reason}` };
|
|
89
|
+
}
|
|
90
|
+
if (dbExists && existsSync(manifestPath)) {
|
|
91
|
+
try {
|
|
92
|
+
const localManifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
93
|
+
if (localManifest.version === remoteManifest.version) {
|
|
94
|
+
return { ok: true, action: "up_to_date", version: localManifest.version };
|
|
95
|
+
}
|
|
96
|
+
log(`Versão local (${localManifest.version}) difere de remota (${remoteManifest.version}). Atualizando.`);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
log("Manifest local corrompido. Re-baixando.");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
await downloadAndVerify(client, endpoint, remoteManifest, dbPath);
|
|
104
|
+
await writeFile(manifestPath, JSON.stringify(remoteManifest, null, 2));
|
|
105
|
+
return { ok: true, action: "downloaded", version: remoteManifest.version };
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
109
|
+
const tmp = `${dbPath}.download`;
|
|
110
|
+
if (existsSync(tmp)) {
|
|
111
|
+
await unlink(tmp).catch(() => { });
|
|
112
|
+
}
|
|
113
|
+
if (dbExists) {
|
|
114
|
+
log(`Falha no download (${reason}). Mantendo cache anterior.`);
|
|
115
|
+
return { ok: true, action: "skipped_offline", version: "stale" };
|
|
116
|
+
}
|
|
117
|
+
return { ok: false, reason };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config.ts — v2.0
|
|
3
|
+
*
|
|
4
|
+
* Configuração simplificada. O dataset agora é gerenciado pelo bootstrap.ts (R2)
|
|
5
|
+
* ou pelo script sync.ts (CSV direto da ANVISA).
|
|
6
|
+
*
|
|
7
|
+
* Paths migrados:
|
|
8
|
+
* ~/.local/share/mcpassure-anvisa/ → ~/.local/share/mcpassure/anvisa-bulario/
|
|
9
|
+
* %APPDATA%/mcpassure-anvisa/ → %APPDATA%/mcpassure/anvisa-bulario/
|
|
10
|
+
*/
|
|
1
11
|
export type Config = {
|
|
2
|
-
cachePath: string;
|
|
3
|
-
maxRetries: number;
|
|
4
|
-
baseDelayMs: number;
|
|
5
|
-
requestTimeoutMs: number;
|
|
6
|
-
anvisaBaseUrl: string;
|
|
7
12
|
degradedThresholdDays: number;
|
|
8
|
-
statusPageEnabled: boolean;
|
|
9
|
-
statusPageUrl: string;
|
|
10
13
|
};
|
|
11
14
|
export declare function loadConfig(): Config;
|
|
12
15
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,MAAM,GAAG;IACnB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,wBAAgB,UAAU,IAAI,MAAM,CAOnC"}
|
package/dist/config.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* config.ts — v2.0
|
|
3
|
+
*
|
|
4
|
+
* Configuração simplificada. O dataset agora é gerenciado pelo bootstrap.ts (R2)
|
|
5
|
+
* ou pelo script sync.ts (CSV direto da ANVISA).
|
|
6
|
+
*
|
|
7
|
+
* Paths migrados:
|
|
8
|
+
* ~/.local/share/mcpassure-anvisa/ → ~/.local/share/mcpassure/anvisa-bulario/
|
|
9
|
+
* %APPDATA%/mcpassure-anvisa/ → %APPDATA%/mcpassure/anvisa-bulario/
|
|
10
|
+
*/
|
|
3
11
|
export function loadConfig() {
|
|
4
12
|
return {
|
|
5
|
-
|
|
6
|
-
path.join(os.homedir(), ".cache", "mcpassure-anvisa", "cache.db"),
|
|
7
|
-
maxRetries: Number.parseInt(process.env.MCPASSURE_MAX_RETRIES ?? "3", 10),
|
|
8
|
-
baseDelayMs: Number.parseInt(process.env.MCPASSURE_BASE_DELAY_MS ?? "1000", 10),
|
|
9
|
-
requestTimeoutMs: Number.parseInt(process.env.MCPASSURE_REQUEST_TIMEOUT_MS ?? "10000", 10),
|
|
10
|
-
anvisaBaseUrl: process.env.MCPASSURE_ANVISA_BASE_URL ?? "https://consultas.anvisa.gov.br",
|
|
11
|
-
degradedThresholdDays: Number.parseInt(process.env.MCPASSURE_DEGRADED_THRESHOLD_DAYS ?? "30", 10),
|
|
12
|
-
statusPageEnabled: process.env.MCPASSURE_STATUS_HEARTBEAT === "true",
|
|
13
|
-
statusPageUrl: process.env.MCPASSURE_STATUS_PAGE_URL ??
|
|
14
|
-
"https://status.mcpassure.com.br/api/v1/heartbeat/anvisa-bulario",
|
|
13
|
+
degradedThresholdDays: Number.parseInt(process.env.MCPASSURE_DEGRADED_THRESHOLD_DAYS ?? "7", 10),
|
|
15
14
|
};
|
|
16
15
|
}
|
|
17
16
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,qBAAqB,EAAE,MAAM,CAAC,QAAQ,CACpC,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,GAAG,EACpD,EAAE,CACH;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Apresentacao, BulaLink, BularioSource, MedicamentoDetalhes, MedicamentoResumo, SearchByClasseTerapeuticaParams, SearchByNameParams, SearchByPrincipalAtivoParams, SearchByTarjaParams } from "../sources/types.js";
|
|
2
|
+
export declare class BularioDatasetSource implements BularioSource {
|
|
3
|
+
readonly name = "anvisa_dados_abertos_sqlite";
|
|
4
|
+
private readonly db;
|
|
5
|
+
constructor(dbPath: string);
|
|
6
|
+
searchByName(params: SearchByNameParams): Promise<MedicamentoResumo[]>;
|
|
7
|
+
searchByPrincipalAtivo(params: SearchByPrincipalAtivoParams): Promise<MedicamentoResumo[]>;
|
|
8
|
+
searchByClasseTerapeutica(params: SearchByClasseTerapeuticaParams): Promise<MedicamentoResumo[]>;
|
|
9
|
+
searchByTarja(params: SearchByTarjaParams): Promise<MedicamentoResumo[]>;
|
|
10
|
+
getDetalhes(numProcesso: string): Promise<MedicamentoDetalhes>;
|
|
11
|
+
getApresentacoes(numProcesso: string): Promise<Apresentacao[]>;
|
|
12
|
+
getBulaLink(_idBulaProtegido: string): Promise<BulaLink>;
|
|
13
|
+
close(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=dataset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/db/dataset.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,+BAA+B,EAC/B,kBAAkB,EAClB,4BAA4B,EAC5B,mBAAmB,EAEpB,MAAM,qBAAqB,CAAC;AA+D7B,qBAAa,oBAAqB,YAAW,aAAa;IACxD,QAAQ,CAAC,IAAI,iCAAiC;IAC9C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,EAAE,MAAM;IAK1B,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAgBtE,sBAAsB,CAAC,MAAM,EAAE,4BAA4B,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAgB1F,yBAAyB,CAAC,MAAM,EAAE,+BAA+B,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAgBhG,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAwCxE,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkB9D,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAiC9D,WAAW,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKxD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAIvB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
// ── Tarja normalisation ───────────────────────────────────────────────────────
|
|
3
|
+
// v2.0: CATEGORIA_REGULATORIA no CSV não mapeia diretamente para LIVRE/VERMELHA/PRETA.
|
|
4
|
+
// As categorias reais do CSV são: "Similar", "Novo", "Genérico", "BAIXO RISCO", etc.
|
|
5
|
+
// O campo tarja (da Portaria 344/98) NÃO está disponível no CSV de dados abertos.
|
|
6
|
+
// Mapeamos heuristicamente pelo tipo de produto e categoria para fins de filtragem.
|
|
7
|
+
const TARJA_KEYWORDS = [
|
|
8
|
+
{ pattern: /psicotr[oó]pic|entorpecente|controle especial/i, tarja: "PRETA" },
|
|
9
|
+
{ pattern: /antimicrobiano|antibiótico|antibi[oó]tic/i, tarja: "VERMELHA" },
|
|
10
|
+
{ pattern: /baixo risco|isento/i, tarja: "LIVRE" },
|
|
11
|
+
];
|
|
12
|
+
function inferTarja(row) {
|
|
13
|
+
const text = [row.categoria_regulatoria, row.classe_terapeutica].filter(Boolean).join(" ");
|
|
14
|
+
for (const { pattern, tarja } of TARJA_KEYWORDS) {
|
|
15
|
+
if (pattern.test(text))
|
|
16
|
+
return tarja;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function rowToResumo(row) {
|
|
21
|
+
return {
|
|
22
|
+
numProcesso: row.numero_processo ?? row.numero_registro ?? String(row.rowid),
|
|
23
|
+
nomeProduto: row.nome_produto,
|
|
24
|
+
empresa: row.empresa ?? "",
|
|
25
|
+
dataAtualizacao: row.data_finalizacao ?? undefined,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function rowToDetalhes(row) {
|
|
29
|
+
return {
|
|
30
|
+
numProcesso: row.numero_processo ?? row.numero_registro ?? String(row.rowid),
|
|
31
|
+
nomeProduto: row.nome_produto,
|
|
32
|
+
empresa: row.empresa ?? "",
|
|
33
|
+
dataAtualizacao: row.data_finalizacao ?? undefined,
|
|
34
|
+
tarja: inferTarja(row),
|
|
35
|
+
classesTerapeuticas: row.classe_terapeutica ? [row.classe_terapeutica] : undefined,
|
|
36
|
+
principioAtivo: row.principio_ativo ?? undefined,
|
|
37
|
+
numeroRegistro: row.numero_registro ?? undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// ── BularioDatasetSource ──────────────────────────────────────────────────────
|
|
41
|
+
export class BularioDatasetSource {
|
|
42
|
+
name = "anvisa_dados_abertos_sqlite";
|
|
43
|
+
db;
|
|
44
|
+
constructor(dbPath) {
|
|
45
|
+
this.db = new Database(dbPath, { readonly: true });
|
|
46
|
+
this.db.pragma("journal_mode = WAL");
|
|
47
|
+
}
|
|
48
|
+
searchByName(params) {
|
|
49
|
+
const { nome, pagina = 1, count = 10 } = params;
|
|
50
|
+
const offset = (pagina - 1) * count;
|
|
51
|
+
const term = `%${nome}%`;
|
|
52
|
+
const rows = this.db
|
|
53
|
+
.prepare(`SELECT rowid, * FROM medicamentos
|
|
54
|
+
WHERE nome_produto LIKE ? COLLATE NOCASE
|
|
55
|
+
LIMIT ? OFFSET ?`)
|
|
56
|
+
.all(term, count, offset);
|
|
57
|
+
return Promise.resolve(rows.map(rowToResumo));
|
|
58
|
+
}
|
|
59
|
+
searchByPrincipalAtivo(params) {
|
|
60
|
+
const { principioAtivo, pagina = 1, count = 10 } = params;
|
|
61
|
+
const offset = (pagina - 1) * count;
|
|
62
|
+
const term = `%${principioAtivo}%`;
|
|
63
|
+
const rows = this.db
|
|
64
|
+
.prepare(`SELECT rowid, * FROM medicamentos
|
|
65
|
+
WHERE principio_ativo LIKE ? COLLATE NOCASE
|
|
66
|
+
LIMIT ? OFFSET ?`)
|
|
67
|
+
.all(term, count, offset);
|
|
68
|
+
return Promise.resolve(rows.map(rowToResumo));
|
|
69
|
+
}
|
|
70
|
+
searchByClasseTerapeutica(params) {
|
|
71
|
+
const { classeTerapeutica, pagina = 1, count = 10 } = params;
|
|
72
|
+
const offset = (pagina - 1) * count;
|
|
73
|
+
const term = `%${classeTerapeutica}%`;
|
|
74
|
+
const rows = this.db
|
|
75
|
+
.prepare(`SELECT rowid, * FROM medicamentos
|
|
76
|
+
WHERE classe_terapeutica LIKE ? COLLATE NOCASE
|
|
77
|
+
LIMIT ? OFFSET ?`)
|
|
78
|
+
.all(term, count, offset);
|
|
79
|
+
return Promise.resolve(rows.map(rowToResumo));
|
|
80
|
+
}
|
|
81
|
+
searchByTarja(params) {
|
|
82
|
+
const { tarja, pagina = 1, count = 10 } = params;
|
|
83
|
+
const offset = (pagina - 1) * count;
|
|
84
|
+
// Heuristic tarja mapping — see inferTarja above
|
|
85
|
+
let whereClause;
|
|
86
|
+
let _bindValue;
|
|
87
|
+
if (tarja === "PRETA") {
|
|
88
|
+
whereClause =
|
|
89
|
+
"(classe_terapeutica LIKE ? OR categoria_regulatoria LIKE ?) " +
|
|
90
|
+
"AND (classe_terapeutica LIKE '%PSICOTR%' OR classe_terapeutica LIKE '%ENTORP%' OR " +
|
|
91
|
+
"classe_terapeutica LIKE '%CONTROLE ESPECIAL%')";
|
|
92
|
+
_bindValue = "%";
|
|
93
|
+
}
|
|
94
|
+
else if (tarja === "VERMELHA") {
|
|
95
|
+
whereClause =
|
|
96
|
+
"(classe_terapeutica LIKE '%ANTIMICROBIANO%' OR classe_terapeutica LIKE '%ANTIBI%' " +
|
|
97
|
+
"OR categoria_regulatoria IN ('Similar', 'Novo', 'Genérico', 'Biológico')) " +
|
|
98
|
+
"AND (classe_terapeutica NOT LIKE '%PSICOTR%')";
|
|
99
|
+
_bindValue = "%";
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// LIVRE — baixo risco
|
|
103
|
+
whereClause =
|
|
104
|
+
"categoria_regulatoria LIKE '%BAIXO RISCO%' OR categoria_regulatoria LIKE '%ISENTO%'";
|
|
105
|
+
_bindValue = "%";
|
|
106
|
+
}
|
|
107
|
+
let rows;
|
|
108
|
+
if (tarja === "VERMELHA" || tarja === "PRETA") {
|
|
109
|
+
rows = this.db
|
|
110
|
+
.prepare(`SELECT rowid, * FROM medicamentos WHERE ${whereClause} LIMIT ? OFFSET ?`)
|
|
111
|
+
.all(count, offset);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
rows = this.db
|
|
115
|
+
.prepare(`SELECT rowid, * FROM medicamentos WHERE ${whereClause} LIMIT ? OFFSET ?`)
|
|
116
|
+
.all(count, offset);
|
|
117
|
+
}
|
|
118
|
+
return Promise.resolve(rows.map(rowToResumo));
|
|
119
|
+
}
|
|
120
|
+
getDetalhes(numProcesso) {
|
|
121
|
+
const row = (this.db
|
|
122
|
+
.prepare(`SELECT rowid, * FROM medicamentos
|
|
123
|
+
WHERE numero_processo = ? OR numero_registro = ?
|
|
124
|
+
LIMIT 1`)
|
|
125
|
+
.get(numProcesso, numProcesso) ?? null);
|
|
126
|
+
if (!row) {
|
|
127
|
+
return Promise.reject(new Error(`Medicamento não encontrado para numProcesso: ${numProcesso}`));
|
|
128
|
+
}
|
|
129
|
+
return Promise.resolve(rowToDetalhes(row));
|
|
130
|
+
}
|
|
131
|
+
getApresentacoes(numProcesso) {
|
|
132
|
+
// O CSV de dados abertos não contém apresentações detalhadas.
|
|
133
|
+
// Retornamos a categoria regulatória como informação disponível.
|
|
134
|
+
const row = (this.db
|
|
135
|
+
.prepare(`SELECT rowid, * FROM medicamentos
|
|
136
|
+
WHERE numero_processo = ? OR numero_registro = ?
|
|
137
|
+
LIMIT 1`)
|
|
138
|
+
.get(numProcesso, numProcesso) ?? null);
|
|
139
|
+
if (!row)
|
|
140
|
+
return Promise.resolve([]);
|
|
141
|
+
const apresentacoes = [];
|
|
142
|
+
if (row.categoria_regulatoria) {
|
|
143
|
+
apresentacoes.push({
|
|
144
|
+
descricao: `Categoria: ${row.categoria_regulatoria}`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (row.situacao_registro) {
|
|
148
|
+
apresentacoes.push({
|
|
149
|
+
descricao: `Situação: ${row.situacao_registro}`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (row.principio_ativo) {
|
|
153
|
+
apresentacoes.push({
|
|
154
|
+
descricao: `Princípio Ativo: ${row.principio_ativo}`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return Promise.resolve(apresentacoes);
|
|
158
|
+
}
|
|
159
|
+
getBulaLink(_idBulaProtegido) {
|
|
160
|
+
// Não disponível no CSV de dados abertos (v2.0 — texto completo em v2.1 via Worker)
|
|
161
|
+
return Promise.resolve({ id: _idBulaProtegido });
|
|
162
|
+
}
|
|
163
|
+
close() {
|
|
164
|
+
this.db.close();
|
|
165
|
+
return Promise.resolve();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=dataset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../src/db/dataset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema SQLite para o dataset ANVISA Dados Abertos — Medicamentos
|
|
3
|
+
* Fonte: https://dados.anvisa.gov.br/dados/DADOS_ABERTOS_MEDICAMENTOS.csv
|
|
4
|
+
* Colunas CSV (separador `;`, encoding Latin1/ISO-8859-1):
|
|
5
|
+
* TIPO_PRODUTO; NOME_PRODUTO; DATA_FINALIZACAO_PROCESSO; CATEGORIA_REGULATORIA;
|
|
6
|
+
* NUMERO_REGISTRO_PRODUTO; DATA_VENCIMENTO_REGISTRO; NUMERO_PROCESSO;
|
|
7
|
+
* CLASSE_TERAPEUTICA; EMPRESA_DETENTORA_REGISTRO; SITUACAO_REGISTRO; PRINCIPIO_ATIVO
|
|
8
|
+
*/
|
|
9
|
+
export declare const SCHEMA_SQL = "\nPRAGMA journal_mode=WAL;\n\nCREATE TABLE IF NOT EXISTS medicamentos (\n rowid INTEGER PRIMARY KEY AUTOINCREMENT,\n tipo_produto TEXT,\n nome_produto TEXT NOT NULL,\n data_finalizacao TEXT,\n categoria_regulatoria TEXT,\n numero_registro TEXT,\n data_vencimento TEXT,\n numero_processo TEXT,\n classe_terapeutica TEXT,\n empresa TEXT,\n situacao_registro TEXT,\n principio_ativo TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_nome ON medicamentos(nome_produto COLLATE NOCASE);\nCREATE INDEX IF NOT EXISTS idx_principio ON medicamentos(principio_ativo COLLATE NOCASE);\nCREATE INDEX IF NOT EXISTS idx_classe ON medicamentos(classe_terapeutica COLLATE NOCASE);\nCREATE INDEX IF NOT EXISTS idx_empresa ON medicamentos(empresa COLLATE NOCASE);\nCREATE INDEX IF NOT EXISTS idx_num_processo ON medicamentos(numero_processo);\nCREATE INDEX IF NOT EXISTS idx_situacao ON medicamentos(situacao_registro);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS medicamentos_fts USING fts5(\n nome_produto,\n principio_ativo,\n classe_terapeutica,\n content='medicamentos',\n content_rowid='rowid'\n);\n\nCREATE TABLE IF NOT EXISTS dataset_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n";
|
|
10
|
+
export declare const SCHEMA_VERSION = "2";
|
|
11
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,UAAU,4vCAqCtB,CAAC;AAEF,eAAO,MAAM,cAAc,MAAM,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema SQLite para o dataset ANVISA Dados Abertos — Medicamentos
|
|
3
|
+
* Fonte: https://dados.anvisa.gov.br/dados/DADOS_ABERTOS_MEDICAMENTOS.csv
|
|
4
|
+
* Colunas CSV (separador `;`, encoding Latin1/ISO-8859-1):
|
|
5
|
+
* TIPO_PRODUTO; NOME_PRODUTO; DATA_FINALIZACAO_PROCESSO; CATEGORIA_REGULATORIA;
|
|
6
|
+
* NUMERO_REGISTRO_PRODUTO; DATA_VENCIMENTO_REGISTRO; NUMERO_PROCESSO;
|
|
7
|
+
* CLASSE_TERAPEUTICA; EMPRESA_DETENTORA_REGISTRO; SITUACAO_REGISTRO; PRINCIPIO_ATIVO
|
|
8
|
+
*/
|
|
9
|
+
export const SCHEMA_SQL = `
|
|
10
|
+
PRAGMA journal_mode=WAL;
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS medicamentos (
|
|
13
|
+
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
14
|
+
tipo_produto TEXT,
|
|
15
|
+
nome_produto TEXT NOT NULL,
|
|
16
|
+
data_finalizacao TEXT,
|
|
17
|
+
categoria_regulatoria TEXT,
|
|
18
|
+
numero_registro TEXT,
|
|
19
|
+
data_vencimento TEXT,
|
|
20
|
+
numero_processo TEXT,
|
|
21
|
+
classe_terapeutica TEXT,
|
|
22
|
+
empresa TEXT,
|
|
23
|
+
situacao_registro TEXT,
|
|
24
|
+
principio_ativo TEXT
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_nome ON medicamentos(nome_produto COLLATE NOCASE);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_principio ON medicamentos(principio_ativo COLLATE NOCASE);
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_classe ON medicamentos(classe_terapeutica COLLATE NOCASE);
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_empresa ON medicamentos(empresa COLLATE NOCASE);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_num_processo ON medicamentos(numero_processo);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_situacao ON medicamentos(situacao_registro);
|
|
33
|
+
|
|
34
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS medicamentos_fts USING fts5(
|
|
35
|
+
nome_produto,
|
|
36
|
+
principio_ativo,
|
|
37
|
+
classe_terapeutica,
|
|
38
|
+
content='medicamentos',
|
|
39
|
+
content_rowid='rowid'
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
CREATE TABLE IF NOT EXISTS dataset_meta (
|
|
43
|
+
key TEXT PRIMARY KEY,
|
|
44
|
+
value TEXT NOT NULL
|
|
45
|
+
);
|
|
46
|
+
`;
|
|
47
|
+
export const SCHEMA_VERSION = "2";
|
|
48
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCzB,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CacheStore } from "../cache/types.js";
|
|
2
1
|
import type { Apresentacao, BulaLink, BularioSource, MedicamentoDetalhes, MedicamentoResumo, SearchByClasseTerapeuticaParams, SearchByNameParams, SearchByPrincipalAtivoParams, SearchByTarjaParams } from "../sources/types.js";
|
|
3
2
|
export type Meta = {
|
|
4
3
|
data_da_base: string;
|
|
@@ -30,11 +29,19 @@ export interface IBularioRepository {
|
|
|
30
29
|
getApresentacoes(numProcesso: string): Promise<ResponseWithMeta<Apresentacao[]>>;
|
|
31
30
|
getBulaLink(idBulaProtegido: string): Promise<ResponseWithMeta<BulaLink>>;
|
|
32
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* BularioRepository v2.0
|
|
34
|
+
*
|
|
35
|
+
* Accesses the ANVISA dataset directly via BularioDatasetSource (SQLite).
|
|
36
|
+
* The old multi-source + cache pattern is replaced by a single SQLite source.
|
|
37
|
+
* _meta.modo is always "cache_local" (data is pre-synced locally).
|
|
38
|
+
*/
|
|
33
39
|
export declare class BularioRepository implements IBularioRepository {
|
|
34
|
-
private readonly
|
|
35
|
-
private readonly sources;
|
|
40
|
+
private readonly source;
|
|
36
41
|
private readonly degradedThresholdDays;
|
|
37
|
-
|
|
42
|
+
private readonly dataBase;
|
|
43
|
+
constructor(source: BularioSource, degradedThresholdDays?: number);
|
|
44
|
+
private buildResponse;
|
|
38
45
|
searchByName(params: SearchByNameParams): Promise<ResponseWithMeta<MedicamentoResumo[]>>;
|
|
39
46
|
searchByPrincipalAtivo(params: SearchByPrincipalAtivoParams): Promise<ResponseWithMeta<MedicamentoResumo[]>>;
|
|
40
47
|
searchByClasseTerapeutica(params: SearchByClasseTerapeuticaParams): Promise<ResponseWithMeta<MedicamentoResumo[]>>;
|
|
@@ -42,6 +49,5 @@ export declare class BularioRepository implements IBularioRepository {
|
|
|
42
49
|
getDetalhes(numProcesso: string): Promise<ResponseWithMeta<MedicamentoDetalhes>>;
|
|
43
50
|
getApresentacoes(numProcesso: string): Promise<ResponseWithMeta<Apresentacao[]>>;
|
|
44
51
|
getBulaLink(idBulaProtegido: string): Promise<ResponseWithMeta<BulaLink>>;
|
|
45
|
-
private _withCache;
|
|
46
52
|
}
|
|
47
53
|
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/domain/repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/domain/repository.ts"],"names":[],"mappings":"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"}
|