Files
ERP/ofbiz-framework/plugins/modern-api
QiufengandClaude Opus 4.8 5e51dc3f56 SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)
恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。

== 此快照内容 ==
- 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091)
- 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static)
- 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB)
- 交接文档 go.md + go-code-reference/endpoints/entities/database.md
- 多代理建设脚本 .claude/wf-*.js

== 状态 ==
- 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板)
- 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用
- W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成)
- 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456

== 排除(gitignore, 可再生) ==
node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui)
完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules)

时间戳: 20260615-191517

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 19:19:15 +08:00
..

OFBiz Modern API

plugins/modern-api is the REST contract layer for the Vue 3 + Element Plus rewrite.

Endpoints

POST /api/v1/login
POST /api/v1/logout
GET  /api/v1/session
GET  /api/v1/navigation
GET  /api/v1/inventory
GET  /api/v1/pages/:pageId
POST /api/v1/actions/:actionId
GET  /api/v1/entities/:entityName
GET  /api/v1/lookups/:lookupId
GET  /api/v1/options/:entityName
POST /api/v1/uploads/:uploadId

All endpoints return:

type ApiResult<T> = {
  ok: boolean
  data?: T
  errors?: Array<{ code: string; message: string; field?: string }>
  messages?: string[]
  warnings?: string[]
  meta?: Record<string, unknown>
  traceId: string
}

Inventory

Generate the migration inventory:

cd /Users/qiu/Desktop/ERP/ofbiz-framework
node plugins/modern-api/scripts/generate-ui-inventory.mjs

Output:

plugins/modern-api/generated/ui-inventory.json
plugins/modern-ui/app/public/generated/ui-inventory.json
plugins/modern-ui/app/public/generated/pages/{pageId}--{hash}.json

The generated file includes:

routeManifest
pageDefinitions
actionDefinitions
controller/widget/service counts
coverage.missingRoutes
coverage.missingActions
coverage.pendingE2ePages
coverage.highRiskParityPages
parityManifest

Acceptance gates:

missingRoutes=0
missingActions=0
generatedOnlyPages=0
frontend split PageDefinition files=pageDefinition count
pendingE2ePages=0 before final functional-equivalence signoff

Run the full structural coverage gate from the modern UI app:

cd /Users/qiu/Desktop/ERP/ofbiz-framework/plugins/modern-ui/app
npm run verify:coverage

It writes:

plugins/modern-ui/verification/coverage-verification.json
plugins/modern-ui/verification/coverage-verification.md

parityManifest groups every generated page by domain, component, adapter, requirement, risk, and checklist progress. It is consumed by local verification/reporting. The production Vue app should remain an ERP administrator website, not a parity dashboard.

The full backend inventory keeps pageDefinitions and actionDefinitions for /api/v1/*. The frontend public index deliberately omits those large maps; each route has pageDefinitionUrl, and the SPA loads the exact page JSON on demand.

Integration Notes

  • login and logout run inside the /api web context so the modern UI can establish an OFBiz userLogin session for /api/v1/* requests.
  • actions/:actionId maps v1 action IDs to OFBiz service names when possible and executes through LocalDispatcher.
  • entities/:entityName, lookups/:lookupId, and options/:entityName require an OFBiz userLogin and OFBiz entity/business view permission. Business _ADMIN permissions and ENTITY_DATA_ADMIN imply view access.
  • navigation returns deployable SPA links under /modern/app/#/pages/....
  • lookups/:lookupId maps v1 lookup IDs to OFBiz entity names, supports query, page, pageSize, and orderBy, and applies query across likely text/id/name/description/code/status fields.
  • uploads/:uploadId is intentionally contract-only until the secure OFBiz upload policy is wired in.

API Contract Evidence

The modern API is not a component showcase surface. It must provide enough backend evidence for the modern ERP UI to distinguish session state, permission failures, empty queues, and contract-only gaps.

Endpoint group Contract evidence Current behavior
GET /api/v1/session ModernApiContractTests.sessionEndpointReturnsUnauthenticatedContractInsteadOfAuthError Always returns 200 ok=true; data.authenticated=false is the unauthenticated state instead of an auth error.
GET /api/v1/navigation NavigationResource checks every webapp base permission through ModernApiUtil.hasViewPermission; ModernApiUtilPermissionTests covers _VIEW, _ADMIN, and null-user denial. Navigation can include denied apps with allowed=false; UI must hide or disable them.
GET /api/v1/pages/:pageId and GET /api/v1/inventory UiInventoryLoader backed contract documented by generated inventory acceptance gates above. Returns generated metadata when present and a fallback page contract when missing; it is metadata, not proof of full legacy screen equivalence.
POST /api/v1/actions/:actionId ModernApiContractTests.serviceActionsRequireLoginBeforeExecution Service-backed actions require userLogin before dispatcher execution; unauthenticated calls return 401 AUTH_REQUIRED. Navigation-only actions may resolve without service execution.
GET /api/v1/entities/:entityName ModernApiUtilPermissionTests plus ModernApiContractTests.clampsPaginationToModernApiBounds, reportsHasMoreWhenNextPageContainsRows, and keepsOnlyKnownOrderByFieldsAndFallsBackToPrimaryKey. Requires login and entity/business view permission, clamps page >= 0, clamps 1 <= pageSize <= 100, returns total, hasMore, safe orderBy, fields, and an empty rows array when no records match.
GET /api/v1/lookups/:lookupId Shares the same ModernApiUtil.safePage, safePageSize, hasMore, and safeOrderByFields contract as entities. Requires login and entity/business view permission; lookup id maps to an entity name and returns paged rows/fields with safe ordering.
GET /api/v1/options/:entityName Uses the same ModernApiUtil.safePageSize and entity permission checks as entity reads. Requires login and entity/business view permission; returns {label,value} options, applied constraints, pageSize, and hasMore.
POST /api/v1/uploads/:uploadId ModernApiContractTests.uploadsRemainExplicitContractOnlyUntilPolicyIsImplemented Returns 501 UPLOAD_CONTRACT_ONLY; no upload side effects happen until OFBiz secure upload policy is wired.

Known non-equivalence remains explicit:

  • uploads/:uploadId is contract-only and is not business-equivalent to legacy OFBiz upload flows.
  • pages/:pageId and inventory prove route/widget/action metadata availability, not full rendered legacy behavior.
  • actions/:actionId executes service-backed actions and supported web events, but controller flows that only resolve views remain navigation contracts.
  • entities, lookups, and options provide secure generic read contracts; they do not replace every specialized OFBiz service, validation rule, or workflow-specific authorization branch.