feat(scrap): 新增对内接口,让 Track 能提交生产报废

料一经出库领用,那条库存行的可用量就扣掉了,走不了标准库存行报废。
本接口内部做两件事:① 走逆向物流「从出库单退回(不良品)」→ 在管不良品;
② 对这笔在管量提交报废申请。两者在**同一个事务**里,要么都成要么都不成。

- 鉴权用 X-API-Key(config.MOM_INTERNAL_API_KEY),与 TRACK_WEBHOOK_KEY
  刻意分离:方向相反、权限不同,独立轮换不连坐。未配置一律 503(Fail-Closed),
  不静默放行 —— 一个默认开着的写接口比没配好的更危险。
- 刻意收紧:is_defective 恒为 true、need_reissue 恒为 false,都不由请求体
  控制。良品分支会往库存行加数量,一个泄漏的密钥就能凭空造库存。
- track_ref 必填:Redis 未部署,唯一索引是唯一的并发防线。
- 退回逻辑从 inbound/stock.py 抽到 services/return_service.py:内部接口没有
  JWT,而视图里夹着 get_current_company_filter/_normalize_user_id,不抽没法复用。
  API 层保留薄包装,restock 等既有调用方一行不用改。
This commit is contained in:
yueli
2026-09-23 15:17:44 +08:00
parent bfd0db791c
commit c7f85880a9
6 changed files with 856 additions and 246 deletions

View File

@ -135,6 +135,20 @@ def create_app():
except ImportError as e:
print(f"❌ 错误: Scrap 模块导入失败: {e}")
# -----------------------------------------------------
# 2.6b 注册对内接口模块(Track → MOM)
#
# ★ 鉴权走 X-API-Key(config.MOM_INTERNAL_API_KEY),**不走 JWT** ——
# Track 没有 MOM 账号,也不该有:申请人身份由请求体显式携带。
# ★ 只注册 /api/v1 一条路径,**不做 legacy 双注册**:内部写接口不该多一个入口。
# -----------------------------------------------------
try:
from app.api.v1.internal import internal_bp
app.register_blueprint(internal_bp, url_prefix='/api/v1/internal')
print("✅ Internal 模块注册成功")
except ImportError as e:
print(f"❌ 错误: Internal 模块导入失败: {e}")
# -----------------------------------------------------
# 2.8 注册采购管理模块
# -----------------------------------------------------