Files
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

124 lines
6.3 KiB
Markdown

# OFBiz Modern API
`plugins/modern-api` is the REST contract layer for the Vue 3 + Element Plus rewrite.
## Endpoints
```text
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:
```ts
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:
```bash
cd /Users/qiu/Desktop/ERP/ofbiz-framework
node plugins/modern-api/scripts/generate-ui-inventory.mjs
```
Output:
```text
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:
```text
routeManifest
pageDefinitions
actionDefinitions
controller/widget/service counts
coverage.missingRoutes
coverage.missingActions
coverage.pendingE2ePages
coverage.highRiskParityPages
parityManifest
```
Acceptance gates:
```text
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:
```bash
cd /Users/qiu/Desktop/ERP/ofbiz-framework/plugins/modern-ui/app
npm run verify:coverage
```
It writes:
```text
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.