undp/undp-national-carbon-registry
GitHub: undp/undp-national-carbon-registry
UNDP开发的国家级碳信用登记系统,帮助各国建立符合《巴黎协定》要求的碳市场基础设施,实现碳减排项目全生命周期管理与碳信用追踪。
Stars: 87 | Forks: 75




[](https://www.sparkblue.org/group/keeping-track-digital-public-goods-paris-agreement)
[](https://app.digitalpublicgoods.net/a/10403)
# 国家碳信用登记处(最新发布)
# 关于
国家碳信用登记处 (v2.0) 是由 UNDP 开发的开源工具包,旨在帮助各国开发国家登记系统,以满足《巴黎协定》第六条的要求。
UNDP 在此 Github 上托管并维护着一个免费的标准代码库,具备基础功能特性。各国可以自定义并部署其版本的登记系统,使其满足本国要求,并与其他国家和国际系统对接。使用开源代码有助于降低成本、避免重复开发,并确保与现有系统的兼容性,从而简化国内碳市场的建立。
作为《巴黎协定》的数字化实施手段,国家碳登记处能够追踪减排活动产生的碳信用交易。任何国家都可以自定义并部署本地版本的登记系统,然后将其与其他国家和国际登记系统、MRV 系统等进行连接。
该系统持续提供以下核心功能:
- **用户与组织管理:** 系统支持诸如指定国家主管部门 (DNA)、项目开发者 (PD) 和独立认证机构 (IC) 等角色,每个角色均具有 Admin、Manager 或 Viewer 访问权限。用户可以注册、登录和重置密码。组织由 DNA 管理员或 root 用户创建并审批,并带有状态管理功能。
- **项目生命周期:** 项目需经历以下阶段:提交初始通报表、提交项目设计文件、提交验证报告以及最终授权。每个步骤都需要 DNA 或 IC 的批准,并伴有明确的状态和自动通知。随着监测和核查报告的提交与审批,项目将根据获批授权时的数量获得相应的碳信用额度。
- **信用转移与注销:** 已发放的信用可以转移给其他获批的组织,或者自愿注销或通过跨境流程注销。转移和注销需要 DNA 的批准。所有操作均记录在详细的表格中并更新状态。
- **仪表盘与报告:**
仪表盘展示系统整体统计数据,包括所有相关项目和信用详情。用户还可以在项目详情概览页面访问全面的项目信息。这包括一个活动时间表,它清晰地记录了利益相关者执行的所有操作的审计轨迹,从而确保整个项目生命周期内的透明度和可追溯性。
此外,系统支持约定电子格式 (AEF) 报告,允许对授权、发放、转移和注销等数据进行结构化报告,以确保国际合规性和数据标准化。
## 目录
* [关于](#about)
* [标准与许可证](#standards)
* [更新日志](#changelog)
* [功能与用户流程](#userflow)
* [演示](#demo)
* [架构](#architecture)
* [项目结构](#structure)
* [自定义框架与可扩展性](#customization)
* [以容器方式运行](#container)
* [在本地运行服务](#local-development)
* [在云端运行服务](#cloud)
* [用户引导](#user)
* [Web 前端](#frontend)
* [本地化](#localization)
* [API](#api)
* [状态页](#status)
* [治理与支持](#support)
* [贡献](./CONTRIBUTING.md)
* [社区指南](./COMMUNITY.md)
* [安全与负责任的披露政策](./SECURITY.md)
## 标准与许可证
此代码库遵循数字公共物品标准:https://digitalpublicgoods.net/standard/ 它是按照数字发展原则构建的:https://digitalprinciples.org/
该工具由 UNDP 开发和维护,并根据 GNU Affero General Public License (AGPL-3.0) 获得许可,允许免费使用、修改和共享该软件。
我们恳请用户通过联系 digital4planet@undp.org 告知我们您的使用情况,因为这有助于我们追踪该工具的影响力并指导未来的改进。
根据 AGPL-3.0 的规定,对代码的任何修改都必须通过在 GitHub 上创建新分支的方式向公众公开。在不遵守 AGPL-3.0 指南的情况下,不得将本软件重新授权在更严格的条款下。开发者在重新提交代码之前,可以对任何敏感或可识别的数据(自定义内容)进行匿名化或移除处理。
## 更新日志
[了解最新的改进。](./CHANGES.md)
## 功能与用户流程
每个国家都有独特的碳市场政策、流程和治理结构,需要根据本地需求自定义碳登记处。
开源代码(演示版本)包含大多数国家都会需要的以下通用步骤(功能)。
- **初始申请阶段**:旨在减少或消除碳排放的项目在登记系统注册,并被分配一个独立认证机构。
- **项目授权**:在项目设计文件 (PDD) 审查完毕后,该项目将被正式授权并记录在登记处的账本中。
- **实施阶段**:项目一旦实施即受到监测,并报告减排量。经过核查后,可以发放碳信用并进行序列化。
- **信用转移/注销**:已发放的信用可以在国内或国际上进行交易。可以在登记系统内追踪、注销或取消信用,从而确保正确的所有权转移并防止重复计算。
该软件的核心功能包括:
## 演示站点
位于 https://www.demo.carbreg.org/login 的演示站点展示了适用于您所在国家/地区的碳登记处的基本功能。请联系 UNDP DPG 团队,申请演示讲解并要求被添加到演示站点的用户列表中。
## 系统架构
UNDP 碳登记处基于面向服务的架构 (SOA)。下图展示了系统中的基本组件。

### **系统服务**
#### _国家级服务_
对与以下功能相关的用户(DNA、项目开发者/认证机构)API 请求进行身份验证、校验并受理:
- 用户和公司的 CRUD 操作。
- 用户身份验证。
- 项目生命周期管理。
- 信用生命周期管理。
该服务支持水平扩展,状态保存在以下位置:
- 文件存储。
- 操作数据库。
- 账本数据库。
#### _分析服务_
提供所有系统分析功能。使用操作数据库生成所有统计数据。
支持水平扩展。
#### _复制器服务_
将账本数据库事件异步复制到操作数据库中。在复制过程中,它会向数据中注入附加信息以供查询使用(例如:位置信息)。
目前支持 QLDB 和 PostgresSQL 账本。通过实现[复制器接口](./backend/services/src/ledger-replicator/replicator-interface.service.ts)可以支持更多的账本复制器。
根据 `LEDGER_TYPE` 环境变量选择复制器。支持的类型有 `QLDB`,`PGSQL(默认)`。
### **序列号生成与追踪**
UNDP 演示登记处将为每个用于信用发放的项目生成并记录一个唯一的项目 ID,其中每笔信用都将获得一个唯一的信用 ID(序列号)。信用 ID(序列号)格式符合 UNFCCC 关于 ITMO ID 格式的指南,如第 6/CMA.4 号决定第 17 段所述。这确保了系统默认设计为按照 UNFCCC 标准生成 ITMO ID。
#### _项目授权_
为项目创建一个唯一的项目标识符。它由序列号格式的项目 ID 部分组成。
示例:CA0004-VU-CH-356 #### _信用发放_ #### _信用转移或注销_ - 当发生整块转移时,信用块的所有权会相应改变。两家公司的信用余额都应进行更新以反映所有权的变更。
示例:从 CA0004-VU-CH-356-1-3000-2023 块转移 3000 个信用。
交易前:CA0004-VU-CH-356-1-3000-2023 : 所有者 1
交易后:CA0004-VU-CH-356-1-3000-2023 : 所有者 2 - 当发生部分块转移时,当前所有者始终保留第一个序列号块,并让出最后一个序列号块。
示例:从 CA0004-VU-CH-356-1-3000-2023 块转移 1000 个信用。
交易前:CA0004-VU-CH-356-1-3000-2023 : 所有者 1
交易后:CA0004-VU-CH-356-1-2000-2023 : 所有者 1 和 CA0004-VU-CH-356-2001-3000-2023 : 所有者 2 ### **部署** 系统服务可以通过 2 种方式部署。 - **作为容器** - 每个服务边界都被容器化到 docker 容器中,可以部署在任何容器编排服务上。[请参考 Docker Compose 文件](./docker-compose.yml) - **作为函数** - 每个服务边界被封装为一个函数 (Serverless),并托管在任何 Function As A Service (FaaS) 技术栈上。[请参考 Serverless 配置文件](./backend/services/serverless.yml) ### **外部服务提供商** 所有外部服务均通过通用接口进行访问。这将把系统实现与外部服务解耦,并实现向多个服务的可扩展性。 **地理位置服务** 目前已实现 2 种选项。 1. 基于文件的方法。用户必须手动添加带有地理坐标的区域。[示例文件](./backend/services/regions.csv)。要应用新的文件更改,需要重启 replicator 服务。 2. [Mapbox](https://mapbox.com)。通过 Mapbox API 动态查询地理坐标。 可以通过实现[位置接口](./backend/services/src/shared/location/location.interface.ts)来添加更多选项。 通过环境变量 `LOCATION_SERVICE` 进行切换。支持的类型有 `MAPBOX`,`FILE(默认)` **文件服务** 为静态文件托管实现了 2 种选项。 1. 使用本地存储和容器卷的 NestJS 静态文件托管。 2. AWS S3 文件存储。 可以通过实现[文件处理程序接口](./backend/services/src/shared/file-handler/filehandler.interface.ts)来添加更多选项。 通过环境变量 `FILE_SERVICE` 进行切换。支持的类型有 `S3`,`LOCAL(默认)` ### **数据库架构** 使用主/从数据库架构来存储碳项目和账户余额。 账本数据库是主数据库。在单个事务中添加/更新项目并更新账户余额。目前仅针对 AWS QLDB 实现。 操作数据库是从数据库。通过数据流从主数据库最终复制到此。基于 PostgresSQL 实现。 **为什么采用双数据库方案?** **为什么需要账本数据库?** 1. 不可篡改且透明 - 追踪并维护每个碳项目和信用变更的有序历史记录。 2. 数据完整性(由第三方进行加密验证)。 3. 核对碳信用和公司账户余额。 **账本数据库接口** 用户和公司管理采用单一数据库方法。 ### **账本布局** 碳登记处包含 2 个账本表。 1. 项目账本 - 包含所有的项目和信用交易。 2. 信用块账本 (Credit) - 包含信用块、交易和所有权。 下图演示了项目创建、授权、发放和转移过程的账本行为。蓝色的文档图标代表账本中的单个数据块。  ### **身份验证** - JWT 身份验证 - 所有端点均基于角色权限。 - API Key 身份验证 - 用于 MRV 系统连接。 ## 项目结构 ``` . ├── .github # CI/CD [Github Actions files] ├── deployment # Declarative configuration files for initial resource creation and setup [AWS Cloudformation] ├── backend # System service implementation ├── services # Services implementation [NestJS application] ├── src ├── national-api # National API [NestJS module] ├── stats-api # Statistics API [NestJS module] ├── ledger-replicator # Blockchain Database data replicator [QLDB to Postgres] ├── libs ├── core # System and database configurations ├── shared # Shared resources [NestJS module] ├── serverless.yml # Service deployment scripts [Serverless + AWS Lambda] ├── web # System web frontend implementation [ReactJS] ├── .gitignore ├── docker-compose.yml # Docker container definitions └── README.md ``` ## 自定义框架与可扩展性 该登记处的设计使得部署能够适应不同的国家框架、市场设计和运营需求。以下描述了该系统如何以与具体实现无关的方式支持自定义和扩展。 ### 1. 功能自定义 核心业务逻辑可以进行调整以反映国家或地区的要求: - **工作流与审批流程:** 项目生命周期阶段、授权步骤和审批链(例如:指定国家主管部门、认证机构、项目开发者)可以配置或扩展,以匹配本地的治理和决策规则。 - **行业与分类逻辑:** 行业分类、行业范围、减缓类型和相关分类法可以进行调整,以便项目和信用与国家或国际分类框架保持一致。 - **登记规则:** 管信用发放、转移、注销和取消的规则(包括验证和业务检查)可以进行调整,以反映不同的市场设计和合规要求。 通过共享的领域逻辑、可配置的枚举和服务接口支持自定义,允许替代实现而无需更改核心应用程序流程。 ### 2. UI 与配置自定义 用户界面和表现层可以针对不同的部署进行调整: - **受控词汇表与下拉菜单:** 行业、减缓类型、文档类型、状态和其他固定列表的选项由枚举和配置驱动。更新这些数据源可以使下拉菜单和选择字段反映国家或特定部署的术语和值,而无需更改核心 UI 组件。 - **品牌化:** Logo、配色方案和关键标签可以通过配置和资产替换进行更改。主题颜色、主要品牌元素和面向公众的文本可以与国家或机构的品牌保持一致。 - **表单与数据字段:** 表单定义、字段标签、验证规则以及可选与必填字段可以扩展或重新配置,以便数据收集满足本地的报告和监管需求,同时在需要互操作性的地方保留底层数据模型。 本地化(参见 [本地化](#localization))支持多种语言,并且可以通过为核心应用程序和自定义标签添加新的翻译命名空间来进行扩展。 ### 3. 模块可扩展性 系统支持以模块化的方式添加和组合功能: - **新功能:** 新特性可以作为独立的模块或服务添加,在运行时进行注册(例如:通过环境变量或部署配置),并在需要时与现有的 API 和前端集成。 - **扩展现有模块:** 现有模块(例如:national API、analytics、replicator、数据导入)的结构允许通过添加额外的处理程序、可选步骤或定义接口的可插拔实现来增加新行为。 - **可选组件:** 可选功能(例如:分析、外部数据导入、验证支持或与保障相关的模块)可以根据部署情况启用或禁用。代码库使用接口和依赖注入,以便可以在不更改核心服务的情况下替换或省略可选组件。 关于集成和列出模块集成的文档保存在代码库中(例如:在 `modules/` 下)。通过实现相关接口(例如:账本复制器、位置服务、文件处理程序、数据导入器),可以以一致的方式添加新的后端或集成。 ### 4. 数据集成与互操作性 ### 5. 配置文件与自定义点 代码库中主要的自定义切入点组织如下: | 领域 | 位置 / 描述 | |------|------------------------| | **前端配置** | `web/src/Config/` — API 基础 URL、主题颜色、路由。 | | **主题与品牌化** | `web/src/Config/colorConfigs.ts`, `web/src/Styles/` (SCSS 变量和主题文件), `web/public/` (logo、favicon、字体)。 | | **受控词汇表 (UI)** | `web/src/Definitions/Enums/` — 行业、减缓类型、角色、状态和其他下拉菜单的枚举。 | | **后端枚举与常量** | `backend/services/libs/shared/src/enum/`, `backend/services/libs/shared/src/constants/` — 服务端词汇表和常量。 | | **DTO 与验证** | `backend/services/libs/shared/src/dto/` — 影响 API 契约和表单行为的请求/响应结构与验证规则。 | | **参考数据** | `backend/services/countries.json`, `backend/services/regions.csv` (或等效路径) — 设置和位置服务使用的国家和地理区域。 | | **服务选择** | 环境变量 (例如 `RUN_MODULE`, `LEDGER_TYPE`, `LOCATION_SERVICE`, `FILE_SERVICE`) — 激活哪些模块和实现。 | | **部署与基础设施** | `docker-compose.yml`, `deployment/`, `backend/services/serverless.yml` — 服务组合和云/部署配置。 | | **本地化** | `web/public/locales/` — 每种语言和命名空间的翻译文件。 | Schema 定义、实体和视图定义以及账本接口位于 `backend/services/libs/shared/src/` 下(entities, view-entities, ledger-db 等)并定义了核心数据模型;可以通过配置包或使用这些接口的附加模块引入扩展或针对特定国家的覆盖配置。 ### 6. 开发者指南 自定义或扩展登记系统的开发者可以采用以下方法: - **为国家或部署创建配置包:** 将所有特定于部署的设置集中在一个地方:复制或扩展相关的配置文件(例如:从 `web/src/Config/`)、枚举(前端和后端)、参考数据(国家、地区)和环境变量。可选择使用专用文件夹或分支存放“X 国配置”,仅覆盖这些文件,保持代码库的其余部分不变。记录所选的国家代码、默认语言以及任何功能开关或已禁用的模块。 - **注册新模块或覆盖默认设置:** 要添加新的可选模块(例如:新的数据导入器或分析提供商),请在后端实现相应的接口(例如:importer, replicator, location, file-handler),在相关模块(例如:replicator 或 data-importer)中注册它,并通过 `RUN_MODULE` 或等效的环境配置启用它。要覆盖默认行为,请提供同一接口的新实现,并通过相应的环境变量(例如:`LOCATION_SERVICE`, `FILE_SERVICE`)选择它。 - **贡献新的自定义功能:** 添加新的自定义切入点(例如:新的配置文件、枚举集或功能标志)时,请将其保留在上述位置(Config, Enums, constants, 参考数据或部署 config)。优先使用配置和接口,而不是硬编码分支;在 README 或专门的文档文件中记录新选项,如果引入了新的自定义类别,请更新本节。 ## 以容器方式运行服务 - 根据需要更新 [docker compose 文件](./docker-compose.yml) 环境变量。 - 目前使用环境变量 `IS_EMAIL_DISABLED` 禁用了所有电子邮件。当禁用电子邮件时,邮件负载将被打印到控制台上。用户账户密码需要从此控制台日志中提取。对于 root 用户账户,请在 national 容器内搜索以 `Password (temporary)` 开头的日志行 (`docker logs -f undp-carbon-registry-national-1`)。 - 添加/更新以下环境变量以启用电子邮件功能。 - `IS_EMAIL_DISABLED`=false - `SOURCE_EMAIL` (发件人电子邮件地址) - `SMTP_ENDPOINT` - `SMTP_USERNAME` - `SMTP_PASSWORD` - 使用 `DB_PASSWORD` 环境变量更改 PostgresSQL 数据库密码 - 通过更新环境变量 `ROOT EMAIL` 来配置系统 root 账户电子邮件。如果启用了电子邮件服务,在首次启动 docker 时,此电子邮件地址将收到一封包含 root 用户密码的新电子邮件。 - 默认情况下,前端不会在仪表盘和项目视图上显示地图图像。要启用它们,请将 web 容器中的 `REACT_APP_MAP_TYPE` 环境变量更新为 `Mapbox`,并添加带有 [MapBox 公共访问令牌](https://docs.mapbox.com/help/tutorials/get-started-tokens-api/) 的新环境变量 `REACT_APP_MAPBOXGL_ACCESS_TOKEN`。 - 添加用户数据 - 更新 [organisations.csv](./organisations.csv) 文件以添加组织。 - 更新 [users.csv](./users.csv) 文件以添加用户。 - 更新文件时,请保留表头,并将现有的虚拟数据替换为您的数据。 - 每次 docker 重启时,这些用户和公司都会添加到系统中。 - 运行 `docker-compose up -d --build`。这将构建并启动以下服务的容器: - PostgresDB 容器 - National service - Analytics service - Replicator service - 带有 Nginx 的 React Web 服务器。 - Web 前端位于 http://localhost:3030/ - API 端点: - http://localhost:3000/national#/ - http://localhost:3100/stats#/ ## 本地开发 - 在本地设置 postgreSQL 并创建一个新数据库。 - 在 .env.local 文件中更新以下数据库配置(如果文件不存在,请新建一个 .env.local) - DB_HOST (默认 localhost) - DB_PORT (默认 5432) - DB_USER (默认 root) - DB_PASSWORD - DB_NAME (默认 carbondbdev) - 切换到目录 `cd backend/service` - 运行 `yarn run sls:install ` - 初始用户数据设置 `serverless invoke local --stage=local --function setup --data '{"rootEmail": "","systemCountryCode": "", "name": "", "logoBase64": ""}'`
- 通过执行 `sls offline --stage=local` 启动所有服务
- 现在所有系统服务都已启动并运行。Swagger 文档可在 `http://localhost:3000/local/national` 获取
## 在 AWS 云上部署系统
- 执行以下命令以在 AWS 上创建所有必需的资源。
aws cloudformation deploy --template-file ./deployment/aws-formation.yml --stack-name carbon-registry-basic --parameter-overrides EnvironmentName= DBPassword= --capabilities CAPABILITY_NAMED_IAM
- 设置以下 Github Secrets 以启用 CI/CD
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- 手动运行它以立即部署所有 lambda 服务。它将创建 2 个 lambda 层和以下 lambda 函数:
- national-api:处理所有碳登记系统用户和程序的创建。由外部 http 请求触发。
- replicator:将账本数据库条目复制到 Postgres 数据库中用于分析。由 Kinesis 数据流上的新记录触发。
- setup:用于添加初始系统用户数据的函数。
- 通过执行以下命令调用 setup lambda 函数,在系统中创建初始用户数据
aws lambda invoke \
--function-name carbon-registry-services-dev-setup --cli-binary-format raw-in-base64-out\
--payload '{"rootEmail": "","systemCountryCode": "", "name": "", "logoBase64": ""}' \
response.json
## 外部连接
### UNDP 的 ITMO 平台
1. 碳登记处每天进行调用以检索 ITMO 平台的项目。
2. 当项目在 ITMO 平台上获得授权时,将在碳登记系统中创建项目。
3. 当项目在 ITMO 平台上获得信用发放时,碳登记处将进行更新。
#### 生命周期

#### 项目创建与授权
- ITMO 平台中的项目授权由以下事件名称标识:“ITMO-Design Document (DD) & Validation Report / Upload on National Public Registry”。
- 如果公司税号在碳登记系统中不存在,则将在碳登记系统中创建该公司。
- 创建项目时:
- 项目以“Pending”状态创建
- 预估信用额度默认设为 100
- 公司比例默认设为 100%
- 为项目生成的序列号与碳登记系统中的任何其他项目相同。
- 从 ITMO 平台检索并在碳登记系统中创建的项目,可以像碳登记系统中的任何其他项目一样,由 DNA 用户进行授权/拒绝。
- 当项目获得授权时,授权的信用额度将是上述的默认预估信用额度。可以像碳登记系统中的任何其他项目一样,由 DNA 用户为该项目发放信用。
#### 信用发放
#### 字段映射
公司
| **碳登记系统中的名称** | **碳登记系统中是否必填** | **ITMO 平台中的名称** |
| --- | --- | --- |
| Tax ID (_taxId_) | 是 | company |
| Name (_name_) | 是 | company |
| Email (_email_) | 是 | 默认设置 : nce.digital+[_organisation_]@undp.org |
| Phone Number (_phoneNo_) | 是 | 默认设置 : 00 |
| Website | | |
| Address | | 默认设置 : Country if the Registry |
| Logo | | |
| Country (_country_) | | 默认设置 : Country of the Registry |
| Role (_companyRole_) | 是 | 默认设置 : ProgrammeDeveloper |
用户 | 碳登记系统中的名称 | 碳登记系统中是否必填 | ITMO 平台中的名称 | | --- | --- | --- | | Email (_email_) | 是 | 默认设置 : nce.digital+[_organisation_]@undp.org | | Role (_role_) | 是 | 默认设置 : Admin | | Phone Number (_phoneNo_) | | 默认设置 : 00 |
项目 | **碳登记系统中的名称** | **碳登记系统中是否必填** | **ITMO 平台中的名称** | | --- | --- | --- | | Project Name (title) | 是 | Name | | External ID (externalId) | 是 | id | | Credit Issuance Serial Number | | | | Current Status | | 默认设置 : Pending | | Applicant Type | | 默认设置 : Project Developer | | Sector (_sector_) | 是 | [行业](#itmo-sector-mapping) | Sectoral Scope (_sectoralScope_) | 是 | [行业](#itmo-sector-mapping)| | Project Start Date (_startTime_) | 是 | createdAt | | Project End Date (_endTime_) | 是 | createdAt + 10 年 | | Geographical Location (Regional) (_geographicalLocation_) | 是 | country _(名称未注明为 ISO3 或实际名称)_ | | Buyer Country Eligibility | | | | Project Cost (USD) (_programmeCostUSD_) | 是 | 默认设置 : Null | | Financing Type | | | | Grant Equivalent Amount | | | | Carbon Price (Dollars per ton) | | | | Company | | company | | Company Tax ID (_proponentTaxVatId_) | 是 | company | | Company Percentage (_proponentPercentage_) | 是 | 默认设置 : 100% | | Type of Mitigation Action/Activity (_typeOfMitigation_) | 是 | [行业](#itmo-sector-mapping) | | GHGs Covered (_greenHouseGasses_) | 是 | 默认设置 : CO2 | | Credits Authorised | | 默认设置 : 100 | | Credits Issued | | 默认设置 : 10 | | Credits Transferred | | | | Credits Frozen | | | | Credits Retired | | | | Credits authorised for international transfer and use (Total cumulative maximum amount of Mitigation Outcomes for which international transfer and use is authorized) | | | | Crediting Period (years) | | | | Project Materials | | Files \* | | Project Materials | | Files \* | | **Credit Calculation Fields / Mitigation Type Calculation** | | | | **Agriculture** | | | | Land Area | | | | Land Area Unit | | | | **Solar** | | | | energy generation | | | | energy generation unit | | | | consumer group | | | #### ITMO 行业映射 | ITMO Sector Field Value | Sector | Sectoral Scope | Type Of Mitigation | | ----------------------- | ----------- | ------------------- | ------------------- | | energy-distribution | Energy | Energy Distribution | Energy Distribution | | agriculture | Agriculture | Agriculture | Agriculture | | energy-industries | Energy | Energy Industry | EE Industry | | Default | Other | Energy Industry | EE Industry | #### 假设 - 项目预估信用额度为 100。 - 项目发放的信用额度始终为 10。 #### Docker 集成设置 1. 将 `data-importer` 以逗号分隔追加到 `docker-compose` 文件 `replicator` 服务的 `RUN_MODULE` 环境变量中。 2. 更新 `docker-compose` 文件 `replicator` 服务中的以下环境变量。 - ITMO_API_KEY - ITMO_EMAIL - ITMO_PASSWORD - ITMO_ENDPOINT 3. 每次重启 docker 时都会导入项目。 ## 用户引导与权限模型 ### 用户角色 系统预定义的用户角色如下: - Root - 公司级别(DNA、项目和认证公司属于此级别) - Admin - Manager - View Only ### 用户引导流程 1. 系统设置完成后,系统将拥有一个与设置邮箱对应的 Root 用户(整个系统仅有一个 Root 用户)。 2. Root 用户负责创建 DNA 实体以及该 DNA 的 Admin。 3. DNA Admin 负责创建其他公司以及各公司的 Admin。 4. 公司的 Admin 有权向本公司添加其余用户(Admin、Managers、View Only Users)。 5. 将用户添加到系统后,应向用户发送一封包含登录密码的确认电子邮件。 ### 用户管理 所有 CRUD 操作均可按照下表执行: | Company Role | New User Role | Authorized User Roles (Company) | | ----------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------- | | DNA | Root | 除了默认系统用户外无法创建新用户,且可以管理系统中的所有用户 | | DNA | Admin
Manager
View Only | Root
Admin(DNA) | | All other Company Roles | Admin
Manager
View Only | Root
Admin(DNA)
Admin(Company) | - 除角色和电子邮件外,所有用户都可以编辑自己的用户账户。 - 用户不允许从系统中删除自己的账户。 ### Web 前端 Web 前端使用 ReactJS 框架实现。有关更多信息,请参考 [React 应用入门](./web/README.md)。 ### 本地化 - 语言(当前):英语 - 语言(进行中):法语。西班牙语 有关添加新语言翻译文件的信息,请参考[此处](./web/public/locales/i18n/README.md)。 ### 应用程序编程接口 (API) 如需集成,请通过 Swagger 参考RESTful Web API 文档。访问地址: - National API: api.APP_URL/national - Status API: api.APP_URL/stats ### 资源要求 | 资源 | 最低要求 | 推荐配置 | | :------- | -------------------------------------------------: | ----------: | | 内存 | 4 GB | 8 GB | | CPU | 4 核 | 4 核 | | 存储 | 20 GB | 50 GB | | 操作系统 | Linux
Windows Server 2016 及更高版本。 | | 注意:上述资源要求是针对每个微服务的单个实例而言的。
#### _项目授权_
为项目创建一个唯一的项目标识符。它由序列号格式的项目 ID 部分组成。示例:CA0004-VU-CH-356 #### _信用发放_ #### _信用转移或注销_ - 当发生整块转移时,信用块的所有权会相应改变。两家公司的信用余额都应进行更新以反映所有权的变更。
示例:从 CA0004-VU-CH-356-1-3000-2023 块转移 3000 个信用。
交易前:CA0004-VU-CH-356-1-3000-2023 : 所有者 1
交易后:CA0004-VU-CH-356-1-3000-2023 : 所有者 2 - 当发生部分块转移时,当前所有者始终保留第一个序列号块,并让出最后一个序列号块。
示例:从 CA0004-VU-CH-356-1-3000-2023 块转移 1000 个信用。
交易前:CA0004-VU-CH-356-1-3000-2023 : 所有者 1
交易后:CA0004-VU-CH-356-1-2000-2023 : 所有者 1 和 CA0004-VU-CH-356-2001-3000-2023 : 所有者 2 ### **部署** 系统服务可以通过 2 种方式部署。 - **作为容器** - 每个服务边界都被容器化到 docker 容器中,可以部署在任何容器编排服务上。[请参考 Docker Compose 文件](./docker-compose.yml) - **作为函数** - 每个服务边界被封装为一个函数 (Serverless),并托管在任何 Function As A Service (FaaS) 技术栈上。[请参考 Serverless 配置文件](./backend/services/serverless.yml) ### **外部服务提供商** 所有外部服务均通过通用接口进行访问。这将把系统实现与外部服务解耦,并实现向多个服务的可扩展性。 **地理位置服务** 目前已实现 2 种选项。 1. 基于文件的方法。用户必须手动添加带有地理坐标的区域。[示例文件](./backend/services/regions.csv)。要应用新的文件更改,需要重启 replicator 服务。 2. [Mapbox](https://mapbox.com)。通过 Mapbox API 动态查询地理坐标。 可以通过实现[位置接口](./backend/services/src/shared/location/location.interface.ts)来添加更多选项。 通过环境变量 `LOCATION_SERVICE` 进行切换。支持的类型有 `MAPBOX`,`FILE(默认)` **文件服务** 为静态文件托管实现了 2 种选项。 1. 使用本地存储和容器卷的 NestJS 静态文件托管。 2. AWS S3 文件存储。 可以通过实现[文件处理程序接口](./backend/services/src/shared/file-handler/filehandler.interface.ts)来添加更多选项。 通过环境变量 `FILE_SERVICE` 进行切换。支持的类型有 `S3`,`LOCAL(默认)` ### **数据库架构** 使用主/从数据库架构来存储碳项目和账户余额。 账本数据库是主数据库。在单个事务中添加/更新项目并更新账户余额。目前仅针对 AWS QLDB 实现。 操作数据库是从数据库。通过数据流从主数据库最终复制到此。基于 PostgresSQL 实现。 **为什么采用双数据库方案?** **为什么需要账本数据库?** 1. 不可篡改且透明 - 追踪并维护每个碳项目和信用变更的有序历史记录。 2. 数据完整性(由第三方进行加密验证)。 3. 核对碳信用和公司账户余额。 **账本数据库接口** 用户和公司管理采用单一数据库方法。 ### **账本布局** 碳登记处包含 2 个账本表。 1. 项目账本 - 包含所有的项目和信用交易。 2. 信用块账本 (Credit) - 包含信用块、交易和所有权。 下图演示了项目创建、授权、发放和转移过程的账本行为。蓝色的文档图标代表账本中的单个数据块。  ### **身份验证** - JWT 身份验证 - 所有端点均基于角色权限。 - API Key 身份验证 - 用于 MRV 系统连接。 ## 项目结构 ``` . ├── .github # CI/CD [Github Actions files] ├── deployment # Declarative configuration files for initial resource creation and setup [AWS Cloudformation] ├── backend # System service implementation ├── services # Services implementation [NestJS application] ├── src ├── national-api # National API [NestJS module] ├── stats-api # Statistics API [NestJS module] ├── ledger-replicator # Blockchain Database data replicator [QLDB to Postgres] ├── libs ├── core # System and database configurations ├── shared # Shared resources [NestJS module] ├── serverless.yml # Service deployment scripts [Serverless + AWS Lambda] ├── web # System web frontend implementation [ReactJS] ├── .gitignore ├── docker-compose.yml # Docker container definitions └── README.md ``` ## 自定义框架与可扩展性 该登记处的设计使得部署能够适应不同的国家框架、市场设计和运营需求。以下描述了该系统如何以与具体实现无关的方式支持自定义和扩展。 ### 1. 功能自定义 核心业务逻辑可以进行调整以反映国家或地区的要求: - **工作流与审批流程:** 项目生命周期阶段、授权步骤和审批链(例如:指定国家主管部门、认证机构、项目开发者)可以配置或扩展,以匹配本地的治理和决策规则。 - **行业与分类逻辑:** 行业分类、行业范围、减缓类型和相关分类法可以进行调整,以便项目和信用与国家或国际分类框架保持一致。 - **登记规则:** 管信用发放、转移、注销和取消的规则(包括验证和业务检查)可以进行调整,以反映不同的市场设计和合规要求。 通过共享的领域逻辑、可配置的枚举和服务接口支持自定义,允许替代实现而无需更改核心应用程序流程。 ### 2. UI 与配置自定义 用户界面和表现层可以针对不同的部署进行调整: - **受控词汇表与下拉菜单:** 行业、减缓类型、文档类型、状态和其他固定列表的选项由枚举和配置驱动。更新这些数据源可以使下拉菜单和选择字段反映国家或特定部署的术语和值,而无需更改核心 UI 组件。 - **品牌化:** Logo、配色方案和关键标签可以通过配置和资产替换进行更改。主题颜色、主要品牌元素和面向公众的文本可以与国家或机构的品牌保持一致。 - **表单与数据字段:** 表单定义、字段标签、验证规则以及可选与必填字段可以扩展或重新配置,以便数据收集满足本地的报告和监管需求,同时在需要互操作性的地方保留底层数据模型。 本地化(参见 [本地化](#localization))支持多种语言,并且可以通过为核心应用程序和自定义标签添加新的翻译命名空间来进行扩展。 ### 3. 模块可扩展性 系统支持以模块化的方式添加和组合功能: - **新功能:** 新特性可以作为独立的模块或服务添加,在运行时进行注册(例如:通过环境变量或部署配置),并在需要时与现有的 API 和前端集成。 - **扩展现有模块:** 现有模块(例如:national API、analytics、replicator、数据导入)的结构允许通过添加额外的处理程序、可选步骤或定义接口的可插拔实现来增加新行为。 - **可选组件:** 可选功能(例如:分析、外部数据导入、验证支持或与保障相关的模块)可以根据部署情况启用或禁用。代码库使用接口和依赖注入,以便可以在不更改核心服务的情况下替换或省略可选组件。 关于集成和列出模块集成的文档保存在代码库中(例如:在 `modules/` 下)。通过实现相关接口(例如:账本复制器、位置服务、文件处理程序、数据导入器),可以以一致的方式添加新的后端或集成。 ### 4. 数据集成与互操作性 ### 5. 配置文件与自定义点 代码库中主要的自定义切入点组织如下: | 领域 | 位置 / 描述 | |------|------------------------| | **前端配置** | `web/src/Config/` — API 基础 URL、主题颜色、路由。 | | **主题与品牌化** | `web/src/Config/colorConfigs.ts`, `web/src/Styles/` (SCSS 变量和主题文件), `web/public/` (logo、favicon、字体)。 | | **受控词汇表 (UI)** | `web/src/Definitions/Enums/` — 行业、减缓类型、角色、状态和其他下拉菜单的枚举。 | | **后端枚举与常量** | `backend/services/libs/shared/src/enum/`, `backend/services/libs/shared/src/constants/` — 服务端词汇表和常量。 | | **DTO 与验证** | `backend/services/libs/shared/src/dto/` — 影响 API 契约和表单行为的请求/响应结构与验证规则。 | | **参考数据** | `backend/services/countries.json`, `backend/services/regions.csv` (或等效路径) — 设置和位置服务使用的国家和地理区域。 | | **服务选择** | 环境变量 (例如 `RUN_MODULE`, `LEDGER_TYPE`, `LOCATION_SERVICE`, `FILE_SERVICE`) — 激活哪些模块和实现。 | | **部署与基础设施** | `docker-compose.yml`, `deployment/`, `backend/services/serverless.yml` — 服务组合和云/部署配置。 | | **本地化** | `web/public/locales/` — 每种语言和命名空间的翻译文件。 | Schema 定义、实体和视图定义以及账本接口位于 `backend/services/libs/shared/src/` 下(entities, view-entities, ledger-db 等)并定义了核心数据模型;可以通过配置包或使用这些接口的附加模块引入扩展或针对特定国家的覆盖配置。 ### 6. 开发者指南 自定义或扩展登记系统的开发者可以采用以下方法: - **为国家或部署创建配置包:** 将所有特定于部署的设置集中在一个地方:复制或扩展相关的配置文件(例如:从 `web/src/Config/`)、枚举(前端和后端)、参考数据(国家、地区)和环境变量。可选择使用专用文件夹或分支存放“X 国配置”,仅覆盖这些文件,保持代码库的其余部分不变。记录所选的国家代码、默认语言以及任何功能开关或已禁用的模块。 - **注册新模块或覆盖默认设置:** 要添加新的可选模块(例如:新的数据导入器或分析提供商),请在后端实现相应的接口(例如:importer, replicator, location, file-handler),在相关模块(例如:replicator 或 data-importer)中注册它,并通过 `RUN_MODULE` 或等效的环境配置启用它。要覆盖默认行为,请提供同一接口的新实现,并通过相应的环境变量(例如:`LOCATION_SERVICE`, `FILE_SERVICE`)选择它。 - **贡献新的自定义功能:** 添加新的自定义切入点(例如:新的配置文件、枚举集或功能标志)时,请将其保留在上述位置(Config, Enums, constants, 参考数据或部署 config)。优先使用配置和接口,而不是硬编码分支;在 README 或专门的文档文件中记录新选项,如果引入了新的自定义类别,请更新本节。 ## 以容器方式运行服务 - 根据需要更新 [docker compose 文件](./docker-compose.yml) 环境变量。 - 目前使用环境变量 `IS_EMAIL_DISABLED` 禁用了所有电子邮件。当禁用电子邮件时,邮件负载将被打印到控制台上。用户账户密码需要从此控制台日志中提取。对于 root 用户账户,请在 national 容器内搜索以 `Password (temporary)` 开头的日志行 (`docker logs -f undp-carbon-registry-national-1`)。 - 添加/更新以下环境变量以启用电子邮件功能。 - `IS_EMAIL_DISABLED`=false - `SOURCE_EMAIL` (发件人电子邮件地址) - `SMTP_ENDPOINT` - `SMTP_USERNAME` - `SMTP_PASSWORD` - 使用 `DB_PASSWORD` 环境变量更改 PostgresSQL 数据库密码 - 通过更新环境变量 `ROOT EMAIL` 来配置系统 root 账户电子邮件。如果启用了电子邮件服务,在首次启动 docker 时,此电子邮件地址将收到一封包含 root 用户密码的新电子邮件。 - 默认情况下,前端不会在仪表盘和项目视图上显示地图图像。要启用它们,请将 web 容器中的 `REACT_APP_MAP_TYPE` 环境变量更新为 `Mapbox`,并添加带有 [MapBox 公共访问令牌](https://docs.mapbox.com/help/tutorials/get-started-tokens-api/) 的新环境变量 `REACT_APP_MAPBOXGL_ACCESS_TOKEN`。 - 添加用户数据 - 更新 [organisations.csv](./organisations.csv) 文件以添加组织。 - 更新 [users.csv](./users.csv) 文件以添加用户。 - 更新文件时,请保留表头,并将现有的虚拟数据替换为您的数据。 - 每次 docker 重启时,这些用户和公司都会添加到系统中。 - 运行 `docker-compose up -d --build`。这将构建并启动以下服务的容器: - PostgresDB 容器 - National service - Analytics service - Replicator service - 带有 Nginx 的 React Web 服务器。 - Web 前端位于 http://localhost:3030/ - API 端点: - http://localhost:3000/national#/ - http://localhost:3100/stats#/ ## 本地开发 - 在本地设置 postgreSQL 并创建一个新数据库。 - 在 .env.local 文件中更新以下数据库配置(如果文件不存在,请新建一个 .env.local) - DB_HOST (默认 localhost) - DB_PORT (默认 5432) - DB_USER (默认 root) - DB_PASSWORD - DB_NAME (默认 carbondbdev) - 切换到目录 `cd backend/service` - 运行 `yarn run sls:install ` - 初始用户数据设置 `serverless invoke local --stage=local --function setup --data '{"rootEmail": "
用户 | 碳登记系统中的名称 | 碳登记系统中是否必填 | ITMO 平台中的名称 | | --- | --- | --- | | Email (_email_) | 是 | 默认设置 : nce.digital+[_organisation_]@undp.org | | Role (_role_) | 是 | 默认设置 : Admin | | Phone Number (_phoneNo_) | | 默认设置 : 00 |
项目 | **碳登记系统中的名称** | **碳登记系统中是否必填** | **ITMO 平台中的名称** | | --- | --- | --- | | Project Name (title) | 是 | Name | | External ID (externalId) | 是 | id | | Credit Issuance Serial Number | | | | Current Status | | 默认设置 : Pending | | Applicant Type | | 默认设置 : Project Developer | | Sector (_sector_) | 是 | [行业](#itmo-sector-mapping) | Sectoral Scope (_sectoralScope_) | 是 | [行业](#itmo-sector-mapping)| | Project Start Date (_startTime_) | 是 | createdAt | | Project End Date (_endTime_) | 是 | createdAt + 10 年 | | Geographical Location (Regional) (_geographicalLocation_) | 是 | country _(名称未注明为 ISO3 或实际名称)_ | | Buyer Country Eligibility | | | | Project Cost (USD) (_programmeCostUSD_) | 是 | 默认设置 : Null | | Financing Type | | | | Grant Equivalent Amount | | | | Carbon Price (Dollars per ton) | | | | Company | | company | | Company Tax ID (_proponentTaxVatId_) | 是 | company | | Company Percentage (_proponentPercentage_) | 是 | 默认设置 : 100% | | Type of Mitigation Action/Activity (_typeOfMitigation_) | 是 | [行业](#itmo-sector-mapping) | | GHGs Covered (_greenHouseGasses_) | 是 | 默认设置 : CO2 | | Credits Authorised | | 默认设置 : 100 | | Credits Issued | | 默认设置 : 10 | | Credits Transferred | | | | Credits Frozen | | | | Credits Retired | | | | Credits authorised for international transfer and use (Total cumulative maximum amount of Mitigation Outcomes for which international transfer and use is authorized) | | | | Crediting Period (years) | | | | Project Materials | | Files \* | | Project Materials | | Files \* | | **Credit Calculation Fields / Mitigation Type Calculation** | | | | **Agriculture** | | | | Land Area | | | | Land Area Unit | | | | **Solar** | | | | energy generation | | | | energy generation unit | | | | consumer group | | | #### ITMO 行业映射 | ITMO Sector Field Value | Sector | Sectoral Scope | Type Of Mitigation | | ----------------------- | ----------- | ------------------- | ------------------- | | energy-distribution | Energy | Energy Distribution | Energy Distribution | | agriculture | Agriculture | Agriculture | Agriculture | | energy-industries | Energy | Energy Industry | EE Industry | | Default | Other | Energy Industry | EE Industry | #### 假设 - 项目预估信用额度为 100。 - 项目发放的信用额度始终为 10。 #### Docker 集成设置 1. 将 `data-importer` 以逗号分隔追加到 `docker-compose` 文件 `replicator` 服务的 `RUN_MODULE` 环境变量中。 2. 更新 `docker-compose` 文件 `replicator` 服务中的以下环境变量。 - ITMO_API_KEY - ITMO_EMAIL - ITMO_PASSWORD - ITMO_ENDPOINT 3. 每次重启 docker 时都会导入项目。 ## 用户引导与权限模型 ### 用户角色 系统预定义的用户角色如下: - Root - 公司级别(DNA、项目和认证公司属于此级别) - Admin - Manager - View Only ### 用户引导流程 1. 系统设置完成后,系统将拥有一个与设置邮箱对应的 Root 用户(整个系统仅有一个 Root 用户)。 2. Root 用户负责创建 DNA 实体以及该 DNA 的 Admin。 3. DNA Admin 负责创建其他公司以及各公司的 Admin。 4. 公司的 Admin 有权向本公司添加其余用户(Admin、Managers、View Only Users)。 5. 将用户添加到系统后,应向用户发送一封包含登录密码的确认电子邮件。 ### 用户管理 所有 CRUD 操作均可按照下表执行: | Company Role | New User Role | Authorized User Roles (Company) | | ----------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------- | | DNA | Root | 除了默认系统用户外无法创建新用户,且可以管理系统中的所有用户 | | DNA | Admin
Manager
View Only | Root
Admin(DNA) | | All other Company Roles | Admin
Manager
View Only | Root
Admin(DNA)
Admin(Company) | - 除角色和电子邮件外,所有用户都可以编辑自己的用户账户。 - 用户不允许从系统中删除自己的账户。 ### Web 前端 Web 前端使用 ReactJS 框架实现。有关更多信息,请参考 [React 应用入门](./web/README.md)。 ### 本地化 - 语言(当前):英语 - 语言(进行中):法语。西班牙语 有关添加新语言翻译文件的信息,请参考[此处](./web/public/locales/i18n/README.md)。 ### 应用程序编程接口 (API) 如需集成,请通过 Swagger 参考RESTful Web API 文档。访问地址: - National API: api.APP_URL/national - Status API: api.APP_URL/stats ### 资源要求 | 资源 | 最低要求 | 推荐配置 | | :------- | -------------------------------------------------: | ----------: | | 内存 | 4 GB | 8 GB | | CPU | 4 核 | 4 核 | | 存储 | 20 GB | 50 GB | | 操作系统 | Linux
Windows Server 2016 及更高版本。 | | 注意:上述资源要求是针对每个微服务的单个实例而言的。
标签:巴黎协定, 数字公共产品, 气候变化, 测试用例, 碳信用登记, 系统定制, 联合国开发计划署, 自动化攻击, 请求拦截