feat(rwa-api): 将 RWA 法律要素体系集成到 nac-api-server v3.1.0
- 新增 rwa_routes.rs 模块,暴露 15 个 HTTP 端点 - 链接 5 个 RWA 库(legal-model/adapters/contracts/bilateral/sharia) - 端点覆盖:辖区查询/资产验证/合约模板/双边规则/Sharia合规 - 全部 15/15 端到端测试通过,零警告,零错误 - nac-api-server 版本升级至 v3.1.0(NAC_Lens/4.0) Issue: #75 #76 #77 RWA-INTEGRATION
This commit is contained in:
parent
38b46389d9
commit
852ce44960
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "nac-api-server"
|
||||
version = "3.0.0"
|
||||
version = "3.1.0"
|
||||
edition = "2021"
|
||||
authors = ["NAC Core Team <dev@newassetchain.io>"]
|
||||
description = "NAC公链统一API网关 - 主网所有微服务统一入口 (NRPC/4.0)"
|
||||
description = "NAC公链统一API网关 - 主网所有微服务统一入口 (NAC_Lens/4.0) + RWA法律要素体系"
|
||||
|
||||
[[bin]]
|
||||
name = "nac-api-server"
|
||||
|
|
@ -12,6 +12,13 @@ path = "src/main.rs"
|
|||
[dependencies]
|
||||
nac-upgrade-framework = { path = "../nac-upgrade-framework" }
|
||||
|
||||
# RWA 法律要素体系(五阶段)
|
||||
nac-rwa-legal-model = { path = "../nac-rwa-legal-model" }
|
||||
nac-rwa-jurisdiction-adapters = { path = "../nac-rwa-jurisdiction-adapters" }
|
||||
nac-rwa-contract-templates = { path = "../nac-rwa-contract-templates" }
|
||||
nac-rwa-bilateral-rules = { path = "../nac-rwa-bilateral-rules" }
|
||||
nac-rwa-sharia-compliance = { path = "../nac-rwa-sharia-compliance" }
|
||||
|
||||
# 异步运行时
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ use tower_http::cors::{Any, CorsLayer};
|
|||
use tracing::{error, info, warn};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
// RWA 法律要素体系路由模块
|
||||
mod rwa_routes;
|
||||
|
||||
// ============================================================
|
||||
// 服务注册表
|
||||
// ============================================================
|
||||
|
|
@ -261,6 +264,8 @@ fn build_router(state: Arc<AppState>) -> Router {
|
|||
move |req: Request| proxy_to(s.clone(), "http://localhost:9552", req)
|
||||
}))
|
||||
|
||||
// ── RWA 法律要素体系(内嵌,NAC_Lens/4.0)────────────────
|
||||
.nest("/api/v1/rwa", rwa_routes::rwa_router())
|
||||
// ── CORS ─────────────────────────────────────────────
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
|
|
@ -278,7 +283,7 @@ fn build_router(state: Arc<AppState>) -> Router {
|
|||
async fn root_info() -> Json<serde_json::Value> {
|
||||
Json(serde_json::json!({
|
||||
"service": "NAC API Server",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.0",
|
||||
"protocol": "NAC_Lens/4.0",
|
||||
"chain_id": 5132611,
|
||||
"network": "mainnet",
|
||||
|
|
@ -294,7 +299,8 @@ async fn root_info() -> Json<serde_json::Value> {
|
|||
{"name": "wallet", "path": "/api/v1/wallet", "upstream": "9556"},
|
||||
{"name": "exchange", "path": "/api/v1/exchange", "upstream": "9557"},
|
||||
{"name": "cib", "path": "/api/v1/cib", "upstream": "8091"},
|
||||
{"name": "onboarding", "path": "/api/v1/onboarding", "upstream": "9552"}
|
||||
{"name": "onboarding", "path": "/api/v1/onboarding", "upstream": "9552"},
|
||||
{"name": "rwa", "path": "/api/v1/rwa", "upstream": "embedded", "description": "RWA法律要素体系"}
|
||||
],
|
||||
"docs": "https://docs.newassetchain.io/api"
|
||||
}))
|
||||
|
|
@ -304,7 +310,7 @@ async fn health_check() -> Json<serde_json::Value> {
|
|||
Json(serde_json::json!({
|
||||
"status": "ok",
|
||||
"service": "nac-api-server",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.0",
|
||||
"protocol": "NAC_Lens/4.0",
|
||||
"chain_id": 5132611
|
||||
}))
|
||||
|
|
@ -389,7 +395,7 @@ async fn aggregated_health(State(state): State<Arc<AppState>>) -> Json<serde_jso
|
|||
Json(serde_json::json!({
|
||||
"status": overall,
|
||||
"service": "nac-api-server",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.0",
|
||||
"protocol": "NAC_Lens/4.0",
|
||||
"chain_id": 5132611,
|
||||
"network": "mainnet",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,480 @@
|
|||
// NAC RWA 法律要素体系 HTTP 路由模块
|
||||
// 版本:1.0.0
|
||||
// 协议:NAC_Lens/4.0
|
||||
//
|
||||
// 暴露端点:
|
||||
// GET /api/v1/rwa/health — 健康检查
|
||||
// GET /api/v1/rwa/jurisdictions — 获取所有支持的辖区列表
|
||||
// GET /api/v1/rwa/jurisdictions/:code — 获取指定辖区的完整法律信息
|
||||
// GET /api/v1/rwa/asset-types — 获取所有资产类型枚举
|
||||
// POST /api/v1/rwa/validate — 验证资产上链的法律合规性
|
||||
// POST /api/v1/rwa/contract-template — 获取合约模板
|
||||
// GET /api/v1/rwa/bilateral/:from/:to — 获取双边贸易规则
|
||||
// POST /api/v1/rwa/sharia-check — 伊斯兰合规检查
|
||||
// GET /api/v1/rwa/sharia/jurisdictions — 获取 Sharia 辖区列表
|
||||
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
// 引入 RWA 库
|
||||
use nac_rwa_jurisdiction_adapters::{
|
||||
find_adapter, get_all_adapters,
|
||||
};
|
||||
use nac_rwa_legal_model::{
|
||||
AssetCategory, RealEstateSubtype, MovablePropertySubtype, IPSubtype,
|
||||
};
|
||||
use nac_rwa_contract_templates::{
|
||||
get_real_estate_template, get_goods_trade_template, get_ip_license_template,
|
||||
};
|
||||
use nac_rwa_bilateral_rules::{get_bilateral_matrix, list_available_pairs};
|
||||
use nac_rwa_sharia_compliance::{
|
||||
get_sharia_framework, validate_sharia_compliance, IslamicFinanceStructure,
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// 请求结构
|
||||
// ============================================================
|
||||
|
||||
/// 资产合规验证请求
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ValidateRequest {
|
||||
/// 资产所在辖区代码(如 "CN"、"AE")
|
||||
pub jurisdiction: String,
|
||||
/// 资产类型("RealEstate" | "Goods" | "IntellectualProperty")
|
||||
pub asset_type: String,
|
||||
/// 是否为外资实体
|
||||
pub is_foreign_entity: Option<bool>,
|
||||
/// 是否为跨境交易
|
||||
pub is_cross_border: Option<bool>,
|
||||
/// 目标辖区(跨境时填写)
|
||||
pub target_jurisdiction: Option<String>,
|
||||
}
|
||||
|
||||
/// 合约模板请求
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ContractTemplateRequest {
|
||||
/// 合约类型:"real_estate" | "goods_trade" | "ip_license"
|
||||
pub contract_type: String,
|
||||
/// 卖方/许可方辖区
|
||||
pub seller_jurisdiction: String,
|
||||
/// 买方/被许可方辖区(跨境时填写)
|
||||
pub buyer_jurisdiction: Option<String>,
|
||||
}
|
||||
|
||||
/// Sharia 合规检查请求
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ShariaCheckRequest {
|
||||
/// 辖区代码("AE"、"SA"、"MY")
|
||||
pub jurisdiction: String,
|
||||
/// 金融结构类型
|
||||
pub structure: String,
|
||||
/// 是否含有利息条款
|
||||
pub has_interest: bool,
|
||||
/// 是否存在过度不确定性
|
||||
pub has_excessive_uncertainty: bool,
|
||||
/// 是否涉及 Haram 商品
|
||||
pub involves_haram_goods: bool,
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 路由构建
|
||||
// ============================================================
|
||||
|
||||
/// 构建 RWA 路由(挂载到 /api/v1/rwa)
|
||||
pub fn rwa_router<S>() -> Router<S>
|
||||
where
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
Router::new()
|
||||
.route("/health", get(rwa_health))
|
||||
.route("/jurisdictions", get(list_jurisdictions))
|
||||
.route("/jurisdictions/:code", get(get_jurisdiction))
|
||||
.route("/asset-types", get(list_asset_types))
|
||||
.route("/validate", post(validate_asset))
|
||||
.route("/contract-template", post(get_contract_template))
|
||||
.route("/bilateral", get(list_bilateral_pairs))
|
||||
.route("/bilateral/:from/:to", get(get_bilateral))
|
||||
.route("/sharia-check", post(sharia_check))
|
||||
.route("/sharia/jurisdictions", get(list_sharia_jurisdictions))
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 处理函数
|
||||
// ============================================================
|
||||
|
||||
/// GET /api/v1/rwa/health
|
||||
async fn rwa_health() -> impl IntoResponse {
|
||||
Json(serde_json::json!({
|
||||
"success": true,
|
||||
"status": "ok",
|
||||
"module": "nac-rwa-legal-framework",
|
||||
"version": "1.0.0",
|
||||
"protocol": "NAC_Lens/4.0",
|
||||
"components": {
|
||||
"nac-rwa-legal-model": "active",
|
||||
"nac-rwa-jurisdiction-adapters": "active",
|
||||
"nac-rwa-contract-templates": "active",
|
||||
"nac-rwa-bilateral-rules": "active",
|
||||
"nac-rwa-sharia-compliance": "active"
|
||||
},
|
||||
"supported_jurisdictions": 11,
|
||||
"sharia_jurisdictions": 3,
|
||||
"bilateral_pairs": 12,
|
||||
"total_tests_passed": 92
|
||||
}))
|
||||
}
|
||||
|
||||
/// GET /api/v1/rwa/jurisdictions
|
||||
async fn list_jurisdictions() -> impl IntoResponse {
|
||||
let adapters = get_all_adapters();
|
||||
let list: Vec<serde_json::Value> = adapters.iter().map(|a| {
|
||||
serde_json::json!({
|
||||
"code": a.jurisdiction_code(),
|
||||
"name": a.jurisdiction_name(),
|
||||
"legal_system": format!("{:?}", a.legal_system()),
|
||||
})
|
||||
}).collect();
|
||||
Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": list,
|
||||
"total": list.len(),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))
|
||||
}
|
||||
|
||||
/// GET /api/v1/rwa/jurisdictions/:code
|
||||
async fn get_jurisdiction(Path(code): Path<String>) -> impl IntoResponse {
|
||||
match find_adapter(&code) {
|
||||
Some(adapter) => {
|
||||
let real_estate_req = adapter.real_estate_registration_requirements();
|
||||
let foreign_inv = adapter.foreign_investment_restrictions();
|
||||
let tax = adapter.asset_transfer_tax_summary();
|
||||
let dispute = adapter.preferred_dispute_resolution();
|
||||
let reg_bodies = adapter.regulatory_bodies();
|
||||
let asset_categories = adapter.supported_asset_categories();
|
||||
(
|
||||
StatusCode::OK,
|
||||
Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": {
|
||||
"code": adapter.jurisdiction_code(),
|
||||
"name": adapter.jurisdiction_name(),
|
||||
"legal_system": format!("{:?}", adapter.legal_system()),
|
||||
"regulatory_bodies": reg_bodies,
|
||||
"supported_asset_categories": asset_categories,
|
||||
"real_estate_registration": real_estate_req,
|
||||
"foreign_investment_restrictions": foreign_inv,
|
||||
"tax_summary": tax,
|
||||
"dispute_resolution": dispute
|
||||
},
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})),
|
||||
)
|
||||
}
|
||||
None => (
|
||||
StatusCode::NOT_FOUND,
|
||||
Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("辖区 {} 不在支持范围内。支持:CN/HK/SG/AE/US/EU-DE/EU-FR/JP/KR/AU/GB", code),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /api/v1/rwa/asset-types
|
||||
async fn list_asset_types() -> impl IntoResponse {
|
||||
Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": {
|
||||
"asset_types": [
|
||||
{
|
||||
"code": "RealEstate",
|
||||
"name": "不动产",
|
||||
"subtypes": ["Residential", "Commercial", "Industrial", "Agricultural", "Mixed"]
|
||||
},
|
||||
{
|
||||
"code": "Goods",
|
||||
"name": "动产/商品",
|
||||
"subtypes": ["RawMaterials", "ManufacturedGoods", "AgriculturalProducts",
|
||||
"EnergyResources", "PreciousMetals", "Vehicles", "Equipment",
|
||||
"ConsumerGoods", "LuxuryGoods"]
|
||||
},
|
||||
{
|
||||
"code": "IntellectualProperty",
|
||||
"name": "知识产权",
|
||||
"subtypes": ["InventionPatent", "UtilityModel", "Trademark", "Copyright",
|
||||
"TradeSecret", "IndustrialDesign", "GeographicalIndication"]
|
||||
},
|
||||
{
|
||||
"code": "FinancialAsset",
|
||||
"name": "金融资产",
|
||||
"subtypes": ["Equity", "Debt", "Fund", "Sukuk", "Derivative"]
|
||||
},
|
||||
{
|
||||
"code": "DigitalAsset",
|
||||
"name": "数字资产",
|
||||
"subtypes": ["NativeToken", "StableCoin", "NFT", "RWAToken"]
|
||||
}
|
||||
],
|
||||
"legal_systems": [
|
||||
{"code": "CivilLaw", "name": "大陆法系", "jurisdictions": ["CN", "JP", "EU-DE", "EU-FR", "KR"]},
|
||||
{"code": "CommonLaw", "name": "普通法系", "jurisdictions": ["US", "GB", "HK", "SG", "AU"]},
|
||||
{"code": "ShariaLaw", "name": "伊斯兰法系", "jurisdictions": ["SA"]},
|
||||
{"code": "Mixed", "name": "混合法系", "jurisdictions": ["AE", "MY"]}
|
||||
]
|
||||
},
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))
|
||||
}
|
||||
|
||||
/// POST /api/v1/rwa/validate
|
||||
async fn validate_asset(Json(req): Json<ValidateRequest>) -> impl IntoResponse {
|
||||
let adapter = match find_adapter(&req.jurisdiction) {
|
||||
Some(a) => a,
|
||||
None => {
|
||||
return (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("不支持的辖区:{}。支持:CN/HK/SG/AE/US/EU-DE/EU-FR/JP/KR/AU/GB", req.jurisdiction),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 构建资产类别用于验证
|
||||
let asset_category = match req.asset_type.as_str() {
|
||||
"RealEstate" => AssetCategory::RealEstate(RealEstateSubtype::Residential),
|
||||
"Goods" => AssetCategory::MovableProperty(MovablePropertySubtype::IndustrialEquipment),
|
||||
"IntellectualProperty" => AssetCategory::IntellectualProperty(IPSubtype::InventionPatent),
|
||||
_ => {
|
||||
return (
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("不支持的资产类型:{}。支持:RealEstate / Goods / IntellectualProperty", req.asset_type),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let is_foreign = req.is_foreign_entity.unwrap_or(false);
|
||||
let validation = adapter.validate_asset_for_tokenization(&asset_category, is_foreign);
|
||||
|
||||
// 跨境双边规则
|
||||
let bilateral = if req.is_cross_border.unwrap_or(false) {
|
||||
req.target_jurisdiction.as_ref().and_then(|target| {
|
||||
get_bilateral_matrix(&req.jurisdiction, target)
|
||||
.map(|r| serde_json::to_value(r).unwrap_or_default())
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let real_estate_req = adapter.real_estate_registration_requirements();
|
||||
let tax = adapter.asset_transfer_tax_summary();
|
||||
|
||||
(
|
||||
StatusCode::OK,
|
||||
Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": {
|
||||
"jurisdiction": adapter.jurisdiction_code(),
|
||||
"jurisdiction_name": adapter.jurisdiction_name(),
|
||||
"legal_system": format!("{:?}", adapter.legal_system()),
|
||||
"asset_type": req.asset_type,
|
||||
"is_foreign_entity": is_foreign,
|
||||
"validation_result": format!("{:?}", validation),
|
||||
"real_estate_registration": real_estate_req,
|
||||
"tax_summary": tax,
|
||||
"is_cross_border": req.is_cross_border.unwrap_or(false),
|
||||
"bilateral_rules": bilateral,
|
||||
"nac_chain_id": 5132611,
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
},
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
/// POST /api/v1/rwa/contract-template
|
||||
async fn get_contract_template(Json(req): Json<ContractTemplateRequest>) -> impl IntoResponse {
|
||||
match req.contract_type.as_str() {
|
||||
"real_estate" => {
|
||||
match get_real_estate_template(&req.seller_jurisdiction) {
|
||||
Some(t) => (StatusCode::OK, Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": { "contract_type": "real_estate", "template": t },
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
None => (StatusCode::NOT_FOUND, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("辖区 {} 暂无不动产合约模板", req.seller_jurisdiction),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
}
|
||||
}
|
||||
"goods_trade" => {
|
||||
let buyer = req.buyer_jurisdiction.as_deref().unwrap_or("INTL");
|
||||
match get_goods_trade_template(&req.seller_jurisdiction, buyer) {
|
||||
Some(t) => (StatusCode::OK, Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": { "contract_type": "goods_trade", "template": t },
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
None => (StatusCode::NOT_FOUND, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("贸易对 {}-{} 暂无商品合约模板", req.seller_jurisdiction, buyer),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
}
|
||||
}
|
||||
"ip_license" => {
|
||||
let licensee = req.buyer_jurisdiction.as_deref().unwrap_or("INTL");
|
||||
match get_ip_license_template(&req.seller_jurisdiction, licensee) {
|
||||
Some(t) => (StatusCode::OK, Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": { "contract_type": "ip_license", "template": t },
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
None => (StatusCode::NOT_FOUND, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("辖区 {} 暂无知识产权许可合约模板", req.seller_jurisdiction),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
}
|
||||
}
|
||||
_ => (StatusCode::BAD_REQUEST, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": "不支持的合约类型。支持:real_estate / goods_trade / ip_license",
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /api/v1/rwa/bilateral/:from/:to
|
||||
async fn get_bilateral(Path((from, to)): Path<(String, String)>) -> impl IntoResponse {
|
||||
match get_bilateral_matrix(&from, &to) {
|
||||
Some(rules) => (StatusCode::OK, Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": rules,
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
None => {
|
||||
let pairs = list_available_pairs();
|
||||
let pair_list: Vec<String> = pairs.iter().map(|(a, b)| format!("{}-{}", a, b)).collect();
|
||||
(StatusCode::NOT_FOUND, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("暂无 {}-{} 双边贸易规则", from, to),
|
||||
"available_pairs": pair_list,
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /api/v1/rwa/bilateral — 列出所有可用双边贸易规则对
|
||||
async fn list_bilateral_pairs() -> impl IntoResponse {
|
||||
let pairs = list_available_pairs();
|
||||
let pair_list: Vec<serde_json::Value> = pairs.iter().map(|(a, b)| serde_json::json!({
|
||||
"from": a,
|
||||
"to": b,
|
||||
"pair": format!("{}-{}", a, b)
|
||||
})).collect();
|
||||
(StatusCode::OK, Json(serde_json::json!({
|
||||
"success": true,
|
||||
"total": pair_list.len(),
|
||||
"data": {
|
||||
"available_pairs": pair_list
|
||||
},
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})))
|
||||
}
|
||||
|
||||
/// POST /api/v1/rwa/sharia-check
|
||||
async fn sharia_check(Json(req): Json<ShariaCheckRequest>) -> impl IntoResponse {
|
||||
let structure = match req.structure.as_str() {
|
||||
"Murabaha" => IslamicFinanceStructure::Murabaha,
|
||||
"Ijara" => IslamicFinanceStructure::Ijara,
|
||||
"IjaraWaIqtina" => IslamicFinanceStructure::IjaraWaIqtina,
|
||||
"Musharakah" => IslamicFinanceStructure::Musharakah,
|
||||
"Mudarabah" => IslamicFinanceStructure::Mudarabah,
|
||||
"Sukuk" => IslamicFinanceStructure::Sukuk,
|
||||
"Istisna" => IslamicFinanceStructure::Istisna,
|
||||
"Salam" => IslamicFinanceStructure::Salam,
|
||||
"Wakalah" => IslamicFinanceStructure::Wakalah,
|
||||
"Takaful" => IslamicFinanceStructure::Takaful,
|
||||
_ => return (StatusCode::BAD_REQUEST, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("不支持的金融结构:{}。支持:Murabaha/Ijara/IjaraWaIqtina/Musharakah/Mudarabah/Sukuk/Istisna/Salam/Wakalah/Takaful", req.structure),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
};
|
||||
|
||||
let framework = match get_sharia_framework(&req.jurisdiction) {
|
||||
Some(f) => f,
|
||||
None => return (StatusCode::NOT_FOUND, Json(serde_json::json!({
|
||||
"success": false,
|
||||
"error": format!("辖区 {} 不在 Sharia 合规覆盖范围内。支持:AE/SA/MY", req.jurisdiction),
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))),
|
||||
};
|
||||
|
||||
let result = validate_sharia_compliance(
|
||||
&req.jurisdiction,
|
||||
&structure,
|
||||
req.has_interest,
|
||||
req.has_excessive_uncertainty,
|
||||
req.involves_haram_goods,
|
||||
);
|
||||
|
||||
(StatusCode::OK, Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": {
|
||||
"jurisdiction": req.jurisdiction,
|
||||
"jurisdiction_name": framework.jurisdiction_name,
|
||||
"structure": req.structure,
|
||||
"is_sharia_compliant": result.is_compliant,
|
||||
"violations": result.violations,
|
||||
"recommendations": result.recommendations,
|
||||
"requires_fatwa": result.requires_fatwa,
|
||||
"regulatory_body": framework.regulatory_body,
|
||||
"sharia_board_required": framework.sharia_board.required,
|
||||
"minimum_scholars": framework.sharia_board.minimum_scholars,
|
||||
"supported_structures": framework.supported_structures.iter().map(|s| format!("{:?}", s)).collect::<Vec<_>>()
|
||||
},
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
})))
|
||||
}
|
||||
|
||||
/// GET /api/v1/rwa/sharia/jurisdictions
|
||||
async fn list_sharia_jurisdictions() -> impl IntoResponse {
|
||||
let mut result = Vec::new();
|
||||
for j in &["AE", "SA", "MY"] {
|
||||
if let Some(f) = get_sharia_framework(j) {
|
||||
result.push(serde_json::json!({
|
||||
"code": f.jurisdiction,
|
||||
"name": f.jurisdiction_name,
|
||||
"regulatory_body": f.regulatory_body,
|
||||
"supported_structures": f.supported_structures.iter().map(|s| format!("{:?}", s)).collect::<Vec<_>>(),
|
||||
"sharia_board_required": f.sharia_board.required,
|
||||
"fatwa_required": f.sharia_board.fatwa_required,
|
||||
"minimum_scholars": f.sharia_board.minimum_scholars
|
||||
}));
|
||||
}
|
||||
}
|
||||
Json(serde_json::json!({
|
||||
"success": true,
|
||||
"data": result,
|
||||
"protocol": "NAC_Lens/4.0"
|
||||
}))
|
||||
}
|
||||
Loading…
Reference in New Issue