milos106/icovazby

GitHub: milos106/icovazby

聚合捷克多个公共注册数据源的企业尽职调查平台,提供风险评分、关联关系图谱发现及 PDF 报告生成功能。

Stars: 0 | Forks: 0

# IČO 关联 [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) [![Node 20+](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org/) ⚠ **按原样提供,无任何担保。** 本应用仅聚合公开数据——如需作出具有法律约束力的决定,请务必核实主要来源。维护者对基于本应用输出结果所作出的决定不承担任何责任。 ## 功能特性 | 模块 | 功能描述 | |---|---| | **🛡️ 企业画像** | 输入 IČO 或名称 → 🟢🟡🔴 风险徽章 + 审查发现 + 身份信息 + DPH + 董事 + OR + UBO + 补贴 + 合同 + 处罚 + 破产记录 + JERRS + 营业执照。支持状态持久化的折叠卡片。 | | **🔍 揭示 Holding** | 针对 a.s./s.r.o. 自动触发 — 通过 OR 门户的共享董事及股东进行 BFS 搜索。可穿透至第 2 层级查找子公司。 | | **🌐 关系网络图谱** | 输入 2–50 个 IČO → 找出在多家公司任职的人员 + 生成 Mermaid 图表。可选包含历史关联(代持人检测)。 | | **🔗 人员关联** | 点击董事 → 查看其所有关联公司(从逐步构建的本地“人员→公司”索引中提取)。 | | **🏢 地址搜索** | 虚拟办公室检测(超过 50 家公司 = ⚠️,超过 500 家 = 🚨)。 | | **📄 PDF 尽职调查** | `/report/:ico` → 可打印的 HTML 页面并支持自动打印,可保存为 PDF 交付物。 | | **🔔 邮件提醒** | 订阅定期检查法定代表人 / 破产 / 注销状态的功能。 | | **🚀 演示路由** | `/demo/26185610` 和 `/demo/45274649` — 无需 token,已预缓存,适用于着陆页。 | | **导出至计费系统** | 支持 Fakturoid / iDoklad / Pohoda JSON 格式。 | | **历史记录与收藏** | 基于 LocalStorage,无需后端。支持分享带有 `?ico=…` 参数的 URL。 | | **深色模式** | 系统自适应 + 手动切换,状态持久化。 | | **🤖 自动化增量采集** | systemd timer — 每小时从 ARES 新增约 20 家公司(针对所有权缓存中的孤立母公司 + 关键词轮换)。资产库会自动增长。 | | **🔄 每周刷新** | systemd timer — 每周日 UTC 3:00 重新抓取最旧的 2000 家公司,捕获法定代表人和所有者的变更信息。 | ## 技术栈 - **后端:** Fastify (TS)、zod、undici、p-retry、p-limit、lru-cache、**Resend**(邮件提醒)/ nodemailer(备选方案)— 无需数据库(仅使用 JSON 文件存储资产库和订阅者信息)。 - **前端:** 原生 HTML + Tailwind CDN + Alpine.js + Mermaid 11 + Inter 字体 — 无需构建步骤。 - **持久化:** `persons-index.json`(覆盖 16k+ 公司时约 5 MB),采用自定义 schema v3 结构:subjects + persons + ownership.byParent — 实现非规范化索引以支持 O(1) 复杂度的 Holding 发现。 - **数据:** 来自捷克公共注册处的 REST API。无代理、无爬虫抓取、无 AI 中间层。 ## 本地运行 ``` git clone https://github.com//icovazby.git cd icovazby npm install cp .env.example .env # 在 .env 中填写 HLIDAC_API_TOKEN(可选) npm run build npm start ``` 打开 **http://127.0.0.1:3000**。 开发环境热重载:`npm run dev`。 ## 配置 (环境变量) | 变量名 | 默认值 | 描述 | |---|---|---| | `PORT` | `3000` | 监听端口 | | `HOST` | `127.0.0.1` | 绑定地址。如需局域网访问请设置为 `0.0.0.0`。 | | `RATE_LIMIT_PER_MIN` | `60` | 基于单 IP 的 HTTP 请求速率限制 | | `RATE_LIMIT_HEAVY_PER_MIN` | `10` | 针对 `/api/holding/discover` + `/api/cross-persons`(高负载端点)的限制 | | `DD_CACHE_TTL_MS` | `86400000` | DD 和 VR 的 LRU cache TTL (24小时) | | `HOLDING_CONCURRENCY` | `3` | Holding 发现过程中的并发上游请求数 | | `ARES_RATE_PER_SECOND` | `5` | 针对 ARES 上游的令牌桶速率限制。请保持 ≤ 8。 | | `ARES_TIMEOUT_MS` | `15000` | ARES 请求超时时间 | | `ARES_RETRIES` | `3` | 重试次数预算 | | `HLIDAC_API_TOKEN` | _(可选)_ | 若不配置,将不显示 Hlídač státu (HS) 相关板块。需在 hlidacstatu.cz/api 自行申请。 | | `RESEND_API_KEY` | _(可选)_ | Resend (resend.com) 用于邮件提醒的 API token。推荐方式。若不配置将降级使用 SMTP。 | | `RESEND_FROM` | _(可选)_ | `noreply@tvuj-domain.cz` — 经 Resend 验证的发送域名。 | | `SMTP_HOST` / `SMTP_USER` / `SMTP_PASS` | _(可选)_ | Nodemailer 备选方案。若既无 Resend 也无 SMTP 配置,邮件内容将仅输出至控制台。 | | `ALERTS_CHECK_MIN` | `360` | 订阅检查时间间隔(分钟,默认 6 小时) | | `ARES_WEB_DATA_DIR` | `./data` | `persons-index.json`(资产库 + 所有权缓存)的存放路径。 | | `DRIP_PER_RUN` | `20` | 单次增量采集运行时新增的公司数量。 | | `REFRESH_BATCH` | `2000` | 每周刷新任务中,重新抓取最旧公司的数量。 | | `LOG_LEVEL` | `info` | Pino 日志级别 | ## 宏观架构 ``` ┌─────────────┐ HTTP ┌────────────────────────────────────┐ │ Browser │ ────────▶ │ Fastify (src/server.ts) │ │ Alpine.js │ │ ├── rate-limit (per-IP, scoped) │ └─────────────┘ │ ├── LRU cache (24h pro DD/VR) │ │ └── per-request HS token (ALS) │ └──┬───────┬───────┬─────────┬───────┘ │ │ │ │ ┌──▼──┐ ┌──▼──┐ ┌──▼──┐ ┌───▼────┐ │ARES │ │ VR │ │ HS │ │ ADIS / │ │MFČR │ │MSp │ │tkn │ │ČNB/EU │ └─────┘ └─────┘ └─────┘ └────────┘ ``` - **`src/services.ts`** — 纯业务逻辑,无框架依赖。 - **`src/holding/discover.ts`** — 针对公司间关系图谱进行 BFS 搜索,支持两种边界类型。 - **`src/graph/crossCompanyPersons.ts`** — Mermaid 图表构建器。 - **`src/persons_index/store.ts`** — 本地“人员→公司”缓存 + 资产主体清单。 - **`src/alerts/`** — 订阅 → 差异快照对比 → SMTP 发送。 - **`src/report/html.ts`** — 用于 PDF 导出的可打印 HTML 生成。 - **`src/cache.ts`** — LRU 装饰器。 ## REST API (部分精选) | 端点 | 功能描述 | |---|---| | `GET /healthz` | 存活探测 + 缓存状态 + 集成标志位 | | `GET /api/dd/:ico` | 完整的 DD 报告(24小时缓存) | | `GET /api/vr/:ico` | OR 详情(24小时缓存) | | `GET /report/:ico` | **用于生成 PDF 的可打印 HTML 报告** | | `GET /demo/:ico` | **无 token 的演示模式**(仅限预设的 IČO) | | `POST /api/holding/discover` | 请求体: `{ ico, depth?, maxIcos? }` → 查找子公司 | | `POST /api/cross-persons` | 请求体: `{ icos[], includeHistorical? }` → 关联人员 + Mermaid 图谱 | | `POST /api/alerts/subscribe` | 请求体: `{ email, ico }` → 发送确认邮件 | | `GET /api/alerts/verify/:token` | 激活订阅 | | `DELETE /api/alerts/:id` | 退订 | 详细列表请执行:`grep "app\\.\\(get\\|post\\|delete\\)" src/server.ts`。 ## 数据来源与许可协议 | 数据来源 | 许可协议 | 商业用途 | 署名要求 | |---|---|---|---| | **ARES** (MFČR) | CC BY 4.0 | ✅ | “Source: ARES, MFČR" | | **公开登记册 (OR)** | Z. č. 304/2013 Sb. | ✅ | “Source: VR, MSp ČR" | | **ADIS** | § 96a z. o DPH | ✅ | “Source: MFČR ADIS" | | **Hlídač státu** | CC BY 3.0 CZ | ✅ (需署名) | ⚠ 必须包含指向 hlidacstatu.cz 的有效链接 | | **ISIR** | § 419 z. č. 182/2006 Sb. | ✅ (在限制下) | “Source: ISIR / MSp ČR" | | **ČNB JERRS / 汇率** | nař. vlády 425/2016 Sb. | ✅ | “Source: ČNB" | | **EU Consolidated Sanctions** | Commission Decision 2011/833/EU | ✅ | “Source: EU Commission" | 应用会在页脚及相关章节自动渲染所有的署名声明。 ## GDPR 合规 输出结果可能包含根据 GDPR 第 6(1)(e) 条合法公开的个人数据(如董事姓名、出生日期)。**如果您选择存储或进一步处理这些结果,您将成为个人数据的控制者**,并需自行承担相关义务(制定隐私政策、确立法律依据、保障数据主体权利及设定数据留存期限)。 本软件的特性: - **不记录请求体 (Request body)。** - **不会在持久化存储中缓存 DD 结果**(仅存在于内存中的 LRU cache,24 小时后过期,且随进程重启而清除)。 - **仅存储**邮件订阅者信息至 `data/subscriptions.json`(前提是您启用了提醒功能)。订阅者可通过 `DELETE /api/alerts/:id` 行使删除权。 ## 商标 / 品牌政策 **“IČO vazby”** 名称、Logo 及 `icovazby.cz` 域名自 2026 年起即被作者作为项目品牌公开使用。您可以在 AGPL-3.0 协议下 Fork 代码并运营您自己的实例,但**严禁**将“ IČO vazby”或容易引起混淆的变体(如“ICO vazby”、“IČOvazby”、“IcoVazby”)用于可能产生混淆的衍生服务。请在 Fork 时选择其他名称(如“RegistryCheck CZ”、“FirmaScan”)。品牌权利独立于源代码的 AGPL 权利——受相关法律(如名称保护、反不正当竞争相关条款)保护,即使未注册正式商标。 ## 代码许可协议 — AGPL-3.0 本项目基于 **GNU Affero General Public License v3.0 or later** ([LICENSE](./LICENSE)) 授权。 **这意味着:** - ✅ 您可以免费使用、修改、分发。 - ✅ 可作为企业内部工具部署。 - ⚠ **如果您将修改后的版本作为网络服务提供给第三方,则必须公开您修改部分的源代码**(AGPL SaaS 条款)。 - ⚠ 衍生作品必须同样采用 AGPL-3.0 协议。 **商业授权:** 版权持有者(原作者)可提供付费的替代(闭源)商业授权。联系方式:请参阅 `SECURITY.md`。 数据许可(CC BY 4.0 ARES, CC BY 3.0 HS, …)与代码许可协议**相互独立**。 ## 上游 API 合理使用规范 | 数据来源 | 限制 | 本项目的防护措施 | |---|---|---| | ARES | 每用户 500/分钟 (MFČR) | `ARES_RATE_PER_SECOND=5` (= 300/分钟) + LRU cache | | Hlídač státu | 基于 token 限制 (由用户自行申请) | 通过 `X-Hlidac-Token` header 传递单次请求 token | | VR 门户 (justice) | 无明确限制 | `HOLDING_CONCURRENCY=3` + LRU cache | | ISIR | 每天 3000 次,每分钟 50 次 | Cache + p-retry | 若进行公开部署,**强烈建议置于配备 WAF 的反向代理之后**(Cloudflare 免费版即可满足需求)。 ## 测试 ``` npm test # vitest, mock klient node tests/e2e.playwright.mjs # E2E proti běžícímu serveru ``` ## 安全性 有关漏洞披露信息,请参阅 [URITY.md](./SECURITY.md)。 ## 状态 **`v0.4.1`** — 索引化后端 + 自动化增长: - **所有权缓存** (`persons_index.ownership.byParent`) — 非规范化的“母公司 → 子公司”索引,从 `akcionari[]` (a.s.) 和 `spolecnici[]` (s.r.o.) 中提取填充。Holding 发现耗时降至 1-2 秒(原为 30 秒)。 - **通过 systemd timer 实现的自动化增量采集与每周刷新。** 新用户可在 1 小时内引导建立资产库,数周内即可实现全面覆盖。 - **支持 Resend 邮件服务**,并带有 SMTP 降级方案(符合欧盟区域 GDPR 规范,每月免费 3000 封)。 - **人员索引中的历史成员记录** — 现可通过设置 `includeHistorical=true` 检索到前任法定代表人。 - **跨公司人员关系自动扩展** — 在“关系网络图谱”中输入 1 个 IČO → 后端将通过人员索引中的法定代表人信息自动扩展至最多 20 个关联节点。杜绝空图谱现象。 **`v0.4`** — 扩展了 Holding 发现功能:深度预置数据,引导建立包含约 16,700 家公司的资产库,Agroert Holding 5 家以上子公司(包含 ZZN Polabí),自动检测 OSVČ 类型的法定代表人,UI 新增 `includeHistorical` 复选框,采用 Cloudflare DNS。 **`v0.3`** — 基础可用版本 (MVP),具备生产级安全加固(速率限制、缓存、p-limit),包含 3 项核心交付功能(PDF、演示、邮件提醒),首个基于 AGPL-3.0 的开源版本发布。
标签:GNU通用公共许可证, MITM代理, Node.js, 企业背景调查, 合规审查, 后端开发, 商业情报, 图数据, 数据聚合, 特征检测, 风险评分