chore(aps): B0.1 APS 独立工具链与包骨架(uv + ruff + pytest,CI 分流)
This commit is contained in:
parent
4939313eb8
commit
698df32a06
|
|
@ -50,14 +50,15 @@ jobs:
|
||||||
echo "found=false" >> "$GITHUB_OUTPUT"
|
echo "found=false" >> "$GITHUB_OUTPUT"
|
||||||
echo "aps/ 下暂无 Python 代码,跳过(B1 落地后自动启用)"
|
echo "aps/ 下暂无 Python 代码,跳过(B1 落地后自动启用)"
|
||||||
fi
|
fi
|
||||||
- uses: actions/setup-python@v5
|
- uses: astral-sh/setup-uv@v5
|
||||||
if: steps.detect.outputs.found == 'true'
|
if: steps.detect.outputs.found == 'true'
|
||||||
with:
|
with:
|
||||||
python-version: '3.11'
|
enable-cache: true
|
||||||
|
- name: 安装 APS 工具链(按 uv.lock)
|
||||||
|
if: steps.detect.outputs.found == 'true'
|
||||||
|
run: uv sync --locked --directory aps
|
||||||
- name: APS 检查(ruff + pytest)
|
- name: APS 检查(ruff + pytest)
|
||||||
if: steps.detect.outputs.found == 'true'
|
if: steps.detect.outputs.found == 'true'
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
uv run --no-sync --directory aps ruff check .
|
||||||
pip install ruff pytest
|
uv run --no-sync --directory aps pytest -q
|
||||||
ruff check aps
|
|
||||||
pytest aps -q
|
|
||||||
|
|
@ -27,6 +27,7 @@ server/data/
|
||||||
|
|
||||||
# ---- Python(APS 侧搬迁适配时使用)----
|
# ---- Python(APS 侧搬迁适配时使用)----
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
.ruff_cache/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
.venv/
|
.venv/
|
||||||
venv/
|
venv/
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,27 @@
|
||||||
|
|
||||||
APS 现在还在 `main` 分支里与平台混装(`server/aps_domain` 39,212 行、`server/engines` 7,551 行、`server/state`、`server/importers`,以及早期原型 `aps-frontend/`)。B0–B7 负责把它拆到这里并补齐独立运行所需的能力。
|
APS 现在还在 `main` 分支里与平台混装(`server/aps_domain` 39,212 行、`server/engines` 7,551 行、`server/state`、`server/importers`,以及早期原型 `aps-frontend/`)。B0–B7 负责把它拆到这里并补齐独立运行所需的能力。
|
||||||
|
|
||||||
|
B0.1 已完成:`src/aps/` 子包骨架、`pyproject.toml`、`uv.lock` 与独立 CI job 就位;平台侧的 lint / typecheck / test 与 APS 的 ruff / pytest 互不阻塞。
|
||||||
|
|
||||||
|
## 工具链(B0.1)
|
||||||
|
|
||||||
|
| 项 | 值 |
|
||||||
|
| --- | --- |
|
||||||
|
| Python | 3.11+ |
|
||||||
|
| 依赖与锁定 | `uv`;`uv.lock` 入库,CI 用 `uv sync --locked` |
|
||||||
|
| 代码检查 | `ruff`(配置在 `pyproject.toml`) |
|
||||||
|
| 测试 | `pytest`(`tests/`) |
|
||||||
|
| 包结构 | `src/aps/`,子包对应 B 线的搬迁目标 |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd aps
|
||||||
|
uv sync # 建 .venv 并按 uv.lock 安装(含 dev 依赖)
|
||||||
|
uv run ruff check .
|
||||||
|
uv run pytest -q
|
||||||
|
```
|
||||||
|
|
||||||
|
依赖取舍:依赖清单以 `main` 分支的 `requirements.txt` 为准,按 B 线边界做了两处增删——**去掉** LLM 与对话智能体相关依赖(D12:APS 不内置对话智能体),**保留**求解引擎(ortools / scipy)、文档与图纸解析(openpyxl / pdfplumber / python-docx / lxml / ezdxf)与持久层(sqlalchemy / alembic / pymysql)——它们都归 APS。
|
||||||
|
|
||||||
## 边界规则
|
## 边界规则
|
||||||
|
|
||||||
| 规则 | 说明 |
|
| 规则 | 说明 |
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
[project]
|
||||||
|
name = "aps"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "APS:独立的高级排产业务系统。开发期与平台同仓不同目录(ADR-0010),工具链与依赖独立。"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
# 接口层(B5:契约化 API)
|
||||||
|
"fastapi>=0.115",
|
||||||
|
"uvicorn[standard]>=0.30",
|
||||||
|
"pydantic>=2.7",
|
||||||
|
"python-multipart>=0.0.9",
|
||||||
|
"httpx>=0.27",
|
||||||
|
# 求解引擎(B1 搬入 server/engines)
|
||||||
|
"ortools>=9.10",
|
||||||
|
"scipy>=1.14",
|
||||||
|
# 导入与文档解析(B1 搬入 server/importers;图纸解析归 APS)
|
||||||
|
"openpyxl>=3.1",
|
||||||
|
"pdfplumber>=0.11",
|
||||||
|
"python-docx>=1.1",
|
||||||
|
"lxml>=5.0",
|
||||||
|
"ezdxf>=1.4",
|
||||||
|
"fonttools>=4.50",
|
||||||
|
# 持久层:APS 库归 APS(ADR-0008),独立账号、独立 database
|
||||||
|
"sqlalchemy>=2.0",
|
||||||
|
"alembic>=1.13",
|
||||||
|
"pymysql>=1.1",
|
||||||
|
# APS 自己的审计归档加密(B4)
|
||||||
|
"cryptography>=42",
|
||||||
|
"python-dotenv>=1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
# 开发依赖用 uv 的 dependency-group(uv sync 默认安装,CI 用 --locked 保证一致)
|
||||||
|
[dependency-groups]
|
||||||
|
dev = ["ruff>=0.7", "pytest>=8.3", "pytest-asyncio>=0.24"]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[tool.hatch.build.targets.wheel]
|
||||||
|
packages = ["src/aps"]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 120
|
||||||
|
target-version = "py311"
|
||||||
|
src = ["src", "tests"]
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = ["E", "F", "W", "I", "UP", "B", "SIM"]
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
testpaths = ["tests"]
|
||||||
|
asyncio_mode = "auto"
|
||||||
|
addopts = "-q"
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
"""APS:独立的高级排产业务系统。
|
||||||
|
|
||||||
|
开发期与本仓库的平台代码同仓不同目录(ADR-0010),但按独立系统对待:
|
||||||
|
自己的工具链(Python / uv)、自己的库、自己的 CI job、自己的界面。
|
||||||
|
|
||||||
|
包内布局对应 B 线的搬迁顺序:
|
||||||
|
|
||||||
|
| 子包 | 内容 | 来源(main 分支) | 任务 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| ``domain`` | 业务主体:排产、主数据、订单、柔性、闭环运行时 | ``server/aps_domain`` | B1–B3 |
|
||||||
|
| ``engines`` | 求解引擎:CP-SAT / GA / NSGA2 / 池 / 规则 | ``server/engines`` | B1 |
|
||||||
|
| ``state`` | 世界状态、检查点、分支、数据包 | ``server/state`` | B1 |
|
||||||
|
| ``importers`` | Excel / SQL / MOM 导入与 profile | ``server/importers`` | B1 |
|
||||||
|
| ``governance`` | APS 自己的动作分级、确认与审计 | 新写(可借鉴旧权力矩阵与链式哈希) | B4 |
|
||||||
|
| ``api`` | 对平台的契约化接口层(capabilityId + schema) | 新写 | B5 |
|
||||||
|
"""
|
||||||
|
|
||||||
|
__version__ = "0.1.0"
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"""契约化接口层(B5):按能力语义暴露 HTTP API,schema 与平台 provider-sdk 对齐。"""
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"""业务主体(B1–B3):从 main 的 ``server/aps_domain`` 迁入,去掉对平台 agent_core 的反向引用。"""
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"""求解引擎(B1):CP-SAT / GA / NSGA2 / 池 / 规则,以及求解进程隔离。"""
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"""APS 自带的治理(B4):动作分级与确认、只追加的审计链。"""
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"""导入(B1):Excel / SQL / MOM 导入与 profile 机制。"""
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
"""世界状态(B1):状态、检查点、分支、数据包。"""
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
"""B0.1 冒烟:工具链与包结构可用(不测业务逻辑,业务逻辑随 B1 迁移进来)。"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_imports() -> None:
|
||||||
|
import aps
|
||||||
|
|
||||||
|
assert aps.__version__ == "0.1.0"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("name", ["api", "domain", "engines", "state", "importers", "governance"])
|
||||||
|
def test_subpackages_import(name: str) -> None:
|
||||||
|
"""每个子包都对应 B 线的一个搬迁目标,导入不了说明结构被改坏了。"""
|
||||||
|
module = __import__(f"aps.{name}", fromlist=[name])
|
||||||
|
|
||||||
|
assert module.__doc__, f"aps.{name} 缺少说明它负责什么的 docstring"
|
||||||
|
|
||||||
|
|
||||||
|
def test_platform_code_is_not_imported() -> None:
|
||||||
|
"""APS 不依赖平台代码:aps 包内不得出现对平台模块的引用(ADR-0010)。"""
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
"-c",
|
||||||
|
"import aps, aps.api, aps.domain, aps.engines, aps.state, aps.importers, aps.governance",
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.returncode == 0, result.stderr
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue