# 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 = { ok: boolean data?: T errors?: Array<{ code: string; message: string; field?: string }> messages?: string[] warnings?: string[] meta?: Record 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.