openxiangda 1.0.85 → 1.0.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/lib/cli.js +482 -10
- package/openxiangda-skills/SKILL.md +5 -1
- package/openxiangda-skills/references/architecture-design.md +29 -0
- package/openxiangda-skills/references/openxiangda-api.md +105 -3
- package/openxiangda-skills/references/pages/page-sdk.md +35 -0
- package/openxiangda-skills/references/permissions-settings.md +39 -2
- package/openxiangda-skills/references/resource-manifest-cheatsheet.md +70 -4
- package/package.json +2 -1
- package/packages/sdk/dist/runtime/index.cjs +3590 -3388
- package/packages/sdk/dist/runtime/index.cjs.map +1 -1
- package/packages/sdk/dist/runtime/index.d.mts +4 -1001
- package/packages/sdk/dist/runtime/index.d.ts +4 -1001
- package/packages/sdk/dist/runtime/index.mjs +3049 -2849
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/react.cjs +2793 -116
- package/packages/sdk/dist/runtime/react.cjs.map +1 -1
- package/packages/sdk/dist/runtime/react.d.mts +1394 -2
- package/packages/sdk/dist/runtime/react.d.ts +1394 -2
- package/packages/sdk/dist/runtime/react.mjs +2749 -84
- package/packages/sdk/dist/runtime/react.mjs.map +1 -1
- package/templates/openxiangda-react-spa/AGENTS.md +29 -0
- package/templates/openxiangda-react-spa/src/app/router.tsx +21 -1
- package/templates/openxiangda-react-spa/src/pages/public/PublicRegisterPage.tsx +15 -0
- package/templates/openxiangda-react-spa/src/resources/permissions/page-groups/public-visitor.json +8 -0
- package/templates/openxiangda-react-spa/src/resources/public-access/public-register.json +14 -0
- package/templates/openxiangda-react-spa/src/resources/routes/public-register.json +8 -0
- package/templates/openxiangda-react-spa/tsconfig.app.json +1 -1
- package/templates/openxiangda-react-spa/vite.config.ts +1 -1
- package/packages/sdk/dist/openxiangdaProvider-CaXMpsnK.d.mts +0 -328
- package/packages/sdk/dist/openxiangdaProvider-CaXMpsnK.d.ts +0 -328
|
@@ -29,7 +29,8 @@ OpenXiangda supports two workspace modes. Classic `sy-lowcode-app-workspace` pub
|
|
|
29
29
|
| 自动化 / 定时任务 / 提交触发 / cron | `openxiangda-workflow-automation` | `openxiangda automation validate / create / publish / enable` |
|
|
30
30
|
| App Function / function_call / 可复用后端逻辑 | `openxiangda-workflow-automation` | declare `src/resources/functions/<code>.json` + `src/functions/<code>/index.ts` |
|
|
31
31
|
| 应用登录 / Auth SDK / 手机号验证码 / CAS / 钉钉免登 | `openxiangda-architecture-design` + `openxiangda-page` | design security gate first, then declare `src/resources/auth/<code>.json` and use `createAuthClient` / `LoginPage` |
|
|
32
|
-
| 角色 / 权限组 / 字段权限 / 数据范围
|
|
32
|
+
| 角色 / 权限组 / 字段权限 / 数据范围 | `openxiangda-permission-settings` | `openxiangda permission ...` / `openxiangda settings ...` |
|
|
33
|
+
| 外部人员无需登录访问 / 公开报名 / 公开查询 / public page | `openxiangda-architecture-design` + `openxiangda-permission-settings` + `openxiangda-page` | 先确认公开范围、外部角色、ticket、grants;再声明 `routes` + `public-access` 并用 `PublicAccessGate` |
|
|
33
34
|
| 看应用结构 / 快照 / 对比 / 诊断 / 排查 / 报错 | `openxiangda-inspect` | `openxiangda app snapshot <APP_XXX> --profile <name> --json` |
|
|
34
35
|
| 登录 / 切换平台 / profile / token / whoami | `openxiangda-core` | `openxiangda env --profile <name>` / `openxiangda auth status` |
|
|
35
36
|
| 多表只读联表 / 固定口径统计 / 强实时复杂查询 / 看板指标 | `openxiangda-form` (data view) | declare `src/resources/data-views/<code>.json` with `storageMode` → `resource publish` |
|
|
@@ -44,6 +45,7 @@ OpenXiangda supports two workspace modes. Classic `sy-lowcode-app-workspace` pub
|
|
|
44
45
|
- ✅ Run `openxiangda update check --json` at the start of substantial work; if `updateAvailable`, run `openxiangda update install` and `openxiangda skill install --force`.
|
|
45
46
|
- ✅ For non-trivial app requirements, run the architecture design gate first: forms, fields, pages, permissions, data views, status/workflow, automation, notifications, and development tasks must be decided before coding.
|
|
46
47
|
- ✅ For app login/auth requirements, run the auth security gate before coding: enabled methods, registration policy, identity matching keys, provider boundary, default roles, rate limits, audit fields, and third-party ownership must be confirmed.
|
|
48
|
+
- ✅ For public/no-login access requirements, run the public access design gate before coding: public routes, external role codes, guest vs ticket, form/dataView/function/connector grants, and backend permission groups must be confirmed. New React SPA apps use `/view/:appType/public/*`, `src/resources/routes/`, `src/resources/public-access/`, and `PublicAccessGate`.
|
|
47
49
|
- ✅ For form-entry UX, pick components in this order: OpenXiangda platform form components → `antd` / `antd-mobile` wrappers → custom component only when neither exists.
|
|
48
50
|
- ✅ List pages, linked options, remote selectors, and report drill-downs must use paginated server-side queries with explicit searchable fields. Do not fetch a large page and filter in local state.
|
|
49
51
|
- ✅ Treat workflow forms as an exception. Ordinary ticket/order/task/asset lifecycles use status fields, state machines, action logs, permissions, and automations; workflows are for real approval tasks.
|
|
@@ -58,6 +60,7 @@ OpenXiangda supports two workspace modes. Classic `sy-lowcode-app-workspace` pub
|
|
|
58
60
|
- ❌ Running a full publish after editing one file. Default to `--changed --dry-run` → `--changed`, or targeted `--page` / `--form`.
|
|
59
61
|
- ❌ Storing tokens, AK, SK, or third-party API secrets in project files. Shared env (`APP_OSS_*`, feedback robot) goes to `~/.openxiangda/.env`.
|
|
60
62
|
- ❌ Raw native HTML form controls in AI-authored workspace code (`<input>`, `<select>`, `<textarea>`, file inputs, hand-written pickers, hand-written upload controls). They are allowed only inside OpenXiangda SDK/platform component internals.
|
|
63
|
+
- ❌ Using `?publicAccess=guest` or form `publicAccess` settings for new React SPA apps. Those are legacy `sy-lowcode-view` compatibility only.
|
|
61
64
|
|
|
62
65
|
## Platform Routing
|
|
63
66
|
|
|
@@ -145,6 +148,7 @@ When the user provides a root domain such as `https://yida.wisejob.cn/`, use it
|
|
|
145
148
|
- For external APIs, create a connector manifest in `src/resources/connectors/` and call it from pages through `sdk.connector`; never put third-party API keys in page source.
|
|
146
149
|
- For reusable backend logic shared by pages, automations, and workflows, create an App Function in `src/resources/functions/<functionCode>.json` plus `src/functions/<functionCode>/index.ts`. Call it from pages with `sdk.function.invoke`, from automation/workflow graphs with `function_call`, or from the runtime endpoint when the caller has app automation management permission. Current App Function MVP exposes controlled helpers such as `ctx.resources`, `ctx.form`, `ctx.dataView`, `ctx.connector`, `ctx.notification`, and `ctx.platform.api`; it does not expose raw SQL or Redis.
|
|
147
150
|
- For application login, declare auth resources in `src/resources/auth/<code>.json` and publish them with `openxiangda resource publish`. App Function auth providers may validate external credentials and return only an identity assertion; they must never issue tokens, set cookies, or write platform user/binding tables directly. The platform auth service decides create/bind/reject and issues tokens.
|
|
151
|
+
- For external/no-login pages in React SPA apps, declare `src/resources/routes/<code>.json` and `src/resources/public-access/<code>.json`, put the page under `/view/:appType/public/*`, and use `PublicAccessGate` or `createPublicAccessClient`. Public guest access to forms, dataViews, functions, and connectors is denied unless policy `grants` explicitly names the resource; backend permission groups still apply.
|
|
148
152
|
- Before scaffolding a real app, complex page, data management page, portal shell, status lifecycle, role governance, or automation, read `references/best-practices.md` and pick the architecture first. Prefer copying the relevant pattern from `examples/best-practices/` into `src/` instead of generating a single large page file.
|
|
149
153
|
- Before publishing to another platform, verify the workspace is bound for that profile. Resource IDs from one profile must not be reused for another profile.
|
|
150
154
|
- Use `openxiangda app snapshot <APP_XXX> --profile <name> --json` for diagnosis before changing an existing app.
|
|
@@ -25,6 +25,7 @@ This design flow is for applications built on OpenXiangda. The output is not a g
|
|
|
25
25
|
- automations, JS_CODE V2 nodes, and App Functions
|
|
26
26
|
- notifications and connectors
|
|
27
27
|
- application login/auth methods, registration policy, identity matching, and provider boundaries
|
|
28
|
+
- public access routes, external roles, ticket strategy, and explicit grants
|
|
28
29
|
- publish and acceptance steps
|
|
29
30
|
|
|
30
31
|
The design is complete only when another agent can implement it without deciding major architecture tradeoffs.
|
|
@@ -170,6 +171,25 @@ Ask these before generating any login/auth design:
|
|
|
170
171
|
|
|
171
172
|
Default: registration is rejected; provider functions return identity assertions only; platform auth service owns account creation, binding, permission assignment, cookies, and tokens.
|
|
172
173
|
|
|
174
|
+
### Public Access
|
|
175
|
+
|
|
176
|
+
Ask these before designing any page or data that external people can access without normal login:
|
|
177
|
+
|
|
178
|
+
- Which exact routes are public? Use `/view/:appType/public/*` for new React SPA apps.
|
|
179
|
+
- What can anonymous/external users do: view a page only, submit a form, query a dataView, invoke a function, or call a connector-backed action?
|
|
180
|
+
- Which virtual external role codes should represent these visitors, for example `external_visitor`, `external_applicant`, or `external_ticket_holder`?
|
|
181
|
+
- Is ordinary guest mode enough, or does the link need `mode: "ticket"` with expiry/single-use behavior?
|
|
182
|
+
- Which forms/dataViews/functions/connectors are explicitly granted? Everything not listed in `grants` is denied.
|
|
183
|
+
- Which backend permission groups must also include the external role codes?
|
|
184
|
+
- Is the page safe for search/share, or should the URL contain a generated ticket?
|
|
185
|
+
|
|
186
|
+
Recommended default if the user is unsure:
|
|
187
|
+
|
|
188
|
+
- Public marketing/info pages: `mode: "guest"`, no data grants.
|
|
189
|
+
- Public form submission: `mode: "guest"` plus one form grant and a submit permission group for `external_visitor`.
|
|
190
|
+
- Sensitive lookup or status query: `mode: "ticket"` plus one dataView/function grant, short TTL, and a read-only permission group.
|
|
191
|
+
- Never use old `?publicAccess=guest` for new React SPA apps; it is legacy `sy-lowcode-view` compatibility only.
|
|
192
|
+
|
|
173
193
|
### UI Design
|
|
174
194
|
|
|
175
195
|
Ask whether to use Product Design or another design skill for:
|
|
@@ -238,6 +258,15 @@ For simple CRUD/admin lists, design can proceed with the appropriate OpenXiangda
|
|
|
238
258
|
- Phone-code providers are App Functions. They validate send/verify events and return identity assertions; they do not issue tokens or mutate platform users.
|
|
239
259
|
- New-user registration must be explicit, with default roles and identity conflict behavior documented.
|
|
240
260
|
|
|
261
|
+
### Public Access
|
|
262
|
+
|
|
263
|
+
- Route resources live under `src/resources/routes/` and use `publicAccess: "guest"` or `"ticket"` only for `/view/:appType/public/*` paths.
|
|
264
|
+
- Public policies live under `src/resources/public-access/`.
|
|
265
|
+
- Policy `externalRoleCodes` are virtual role codes carried by the scoped public token; use the same codes in page/form/dataView permission groups.
|
|
266
|
+
- Policy `grants` must list every form/dataView/function/connector the public page can access. Do not rely on broad guest permissions.
|
|
267
|
+
- Use `PublicAccessGate` in React routes or `createPublicAccessClient` for custom bootstrapping.
|
|
268
|
+
- Old `?publicAccess=guest` and form `publicAccess` settings are legacy compatibility and should not appear in new-app designs.
|
|
269
|
+
|
|
241
270
|
## Final Document Template
|
|
242
271
|
|
|
243
272
|
```markdown
|
|
@@ -166,11 +166,11 @@ Body:
|
|
|
166
166
|
|
|
167
167
|
### GET `/apps/:appType/forms/:formUuid/public-access`
|
|
168
168
|
|
|
169
|
-
Requires Bearer token. Returns public/guest access config for the form.
|
|
169
|
+
Requires Bearer token. Returns legacy public/guest access config for the form. This endpoint is only for old `sy-lowcode-view` compatibility.
|
|
170
170
|
|
|
171
171
|
### PUT `/apps/:appType/forms/:formUuid/public-access`
|
|
172
172
|
|
|
173
|
-
Requires Bearer token. Creates or updates public/guest access config.
|
|
173
|
+
Requires Bearer token. Creates or updates legacy public/guest access config.
|
|
174
174
|
|
|
175
175
|
Body:
|
|
176
176
|
|
|
@@ -183,7 +183,109 @@ Body:
|
|
|
183
183
|
|
|
184
184
|
### DELETE `/apps/:appType/forms/:formUuid/public-access`
|
|
185
185
|
|
|
186
|
-
Requires Bearer token. Deletes public/guest access config for the form.
|
|
186
|
+
Requires Bearer token. Deletes legacy public/guest access config for the form.
|
|
187
|
+
|
|
188
|
+
## React SPA Public Access
|
|
189
|
+
|
|
190
|
+
New React SPA apps use `/view/:appType/public/*`, route resources, public access policies, and a scoped public session. Do not use `?publicAccess=guest` for new apps.
|
|
191
|
+
|
|
192
|
+
### GET `/apps/:appType/routes`
|
|
193
|
+
|
|
194
|
+
Requires Bearer token. Lists route resources.
|
|
195
|
+
|
|
196
|
+
### POST `/apps/:appType/routes`
|
|
197
|
+
|
|
198
|
+
Requires Bearer token. Creates a route resource.
|
|
199
|
+
|
|
200
|
+
Body:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"code": "public.register",
|
|
205
|
+
"title": "公开报名",
|
|
206
|
+
"kind": "page",
|
|
207
|
+
"pathPattern": "/view/:appType/public/register",
|
|
208
|
+
"publicAccess": "guest",
|
|
209
|
+
"publicPolicyCode": "public_register"
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### PUT `/apps/:appType/routes/:code`
|
|
214
|
+
|
|
215
|
+
Requires Bearer token. Updates a route resource.
|
|
216
|
+
|
|
217
|
+
### DELETE `/apps/:appType/routes/:code`
|
|
218
|
+
|
|
219
|
+
Requires Bearer token. Deletes a route resource.
|
|
220
|
+
|
|
221
|
+
### GET `/apps/:appType/public-access/policies`
|
|
222
|
+
|
|
223
|
+
Requires Bearer token. Lists public access policies.
|
|
224
|
+
|
|
225
|
+
### POST `/apps/:appType/public-access/policies`
|
|
226
|
+
|
|
227
|
+
Requires Bearer token. Creates a public access policy.
|
|
228
|
+
|
|
229
|
+
Body:
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"code": "public_register",
|
|
234
|
+
"name": "公开报名入口",
|
|
235
|
+
"enabled": true,
|
|
236
|
+
"mode": "guest",
|
|
237
|
+
"routeCode": "public.register",
|
|
238
|
+
"pathPattern": "/view/:appType/public/register",
|
|
239
|
+
"externalRoleCodes": ["external_visitor"],
|
|
240
|
+
"grants": {
|
|
241
|
+
"forms": ["FORM_UUID"],
|
|
242
|
+
"dataViews": ["public_registration_lookup"],
|
|
243
|
+
"functions": ["submit_public_registration"],
|
|
244
|
+
"connectors": ["sms.sendCode"]
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### PUT `/apps/:appType/public-access/policies/:code`
|
|
250
|
+
|
|
251
|
+
Requires Bearer token. Updates a public access policy.
|
|
252
|
+
|
|
253
|
+
### DELETE `/apps/:appType/public-access/policies/:code`
|
|
254
|
+
|
|
255
|
+
Requires Bearer token. Deletes a public access policy.
|
|
256
|
+
|
|
257
|
+
### POST `/apps/:appType/public-access/policies/:code/tickets`
|
|
258
|
+
|
|
259
|
+
Requires Bearer token. Creates a ticket for a `mode: "ticket"` policy.
|
|
260
|
+
|
|
261
|
+
Body:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"expiresAt": "2026-06-18T12:00:00.000Z",
|
|
266
|
+
"subject": { "usage": "single-use" }
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### POST `/apps/:appType/public/session`
|
|
271
|
+
|
|
272
|
+
Does not require an existing login. Creates a scoped public guest session.
|
|
273
|
+
|
|
274
|
+
Body:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"policyCode": "public_register",
|
|
279
|
+
"routeCode": "public.register",
|
|
280
|
+
"path": "/view/APP_XXX/public/register",
|
|
281
|
+
"ticket": "optional-ticket",
|
|
282
|
+
"guestIdentifier": "public:APP_XXX:browser-id",
|
|
283
|
+
"domain": "example.com",
|
|
284
|
+
"userAgent": "browser"
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Returns the normal guest token payload plus `extra.publicAccess`.
|
|
187
289
|
|
|
188
290
|
### GET `/apps/:appType/menus`
|
|
189
291
|
|
|
@@ -15,6 +15,7 @@ Guidelines:
|
|
|
15
15
|
- Use `sdk.connector.invoke`, `sdk.connector.call("connector.api")`, or `sdk.connector.download` for external services. The SDK calls the platform runtime connector endpoint; it must not call third-party domains directly.
|
|
16
16
|
- Use `sdk.notification.sendByType` and `batchSendByType` for reusable business messages. Custom notification types must be declared in `src/resources/notifications/` and published with `openxiangda resource publish`.
|
|
17
17
|
- Use `createAuthClient` from `openxiangda/runtime` or `LoginPage` / `useAuth` from `openxiangda/runtime/react` for application login pages. Auth provider App Functions return identity assertions only; platform auth owns create/bind/reject/token decisions.
|
|
18
|
+
- Use `PublicAccessGate` from `openxiangda/runtime/react` or `createPublicAccessClient` from `openxiangda/runtime` for React SPA public pages under `/view/:appType/public/*`. Do not append old `?publicAccess=guest` links in new apps.
|
|
18
19
|
- For the current user's department hierarchy, use `sdk.department.getCurrentUserParentDepartments()`; do not hardcode `GET /department/:id/parentDepartments` in page code.
|
|
19
20
|
- Use `sdk.auth.logoutAndRedirect({ loginUrl })` for user logout when the page should return after login. It calls the platform logout endpoint, appends the current page URL as `callback`, and redirects to the login URL. Use `sdk.auth.logout()` only when the page wants to handle redirect itself.
|
|
20
21
|
- Use `sdk.role.getMyRoles()`, `sdk.role.getCurrentRole()`, and `sdk.role.switchAppRole()` for current-user app role switching. Pass `roleId: ""` to switch back to all app roles.
|
|
@@ -141,6 +142,40 @@ const result = await auth.phoneCodeLogin({
|
|
|
141
142
|
|
|
142
143
|
For phone-code auth, the App Function provider receives `event`, `appType`, `method`, `credential`, `requestId`, `request`, and `challenge`. It may return `{ ok, providerState }` for send and `{ ok, identity }` for verify. It must not return `token`, `accessToken`, `refreshToken`, cookies, or mutate platform account tables.
|
|
143
144
|
|
|
145
|
+
Public access route:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { PublicAccessGate } from "openxiangda/runtime/react";
|
|
149
|
+
|
|
150
|
+
export function PublicRegisterRoute() {
|
|
151
|
+
return (
|
|
152
|
+
<PublicAccessGate
|
|
153
|
+
policyCode="public_register"
|
|
154
|
+
routeCode="public.register"
|
|
155
|
+
>
|
|
156
|
+
<PublicRegisterPage />
|
|
157
|
+
</PublicAccessGate>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Standalone public session client:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { createPublicAccessClient } from "openxiangda/runtime";
|
|
166
|
+
|
|
167
|
+
const publicAccess = createPublicAccessClient({ appType, servicePrefix: "/service" });
|
|
168
|
+
|
|
169
|
+
await publicAccess.startSession({
|
|
170
|
+
policyCode: "public_register",
|
|
171
|
+
routeCode: "public.register",
|
|
172
|
+
path: window.location.pathname,
|
|
173
|
+
ticket: new URLSearchParams(window.location.search).get("ticket") || undefined,
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The matching resources must exist under `src/resources/routes/` and `src/resources/public-access/`. Public guest access to forms, data views, functions, and connectors is denied unless the policy `grants` explicitly names that resource.
|
|
178
|
+
|
|
144
179
|
Logout and current-user role switching:
|
|
145
180
|
|
|
146
181
|
```ts
|
|
@@ -185,7 +185,44 @@ Data management config is stored as an opaque JSON object by the platform. Keep
|
|
|
185
185
|
}
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
-
Public
|
|
188
|
+
## Public Access
|
|
189
|
+
|
|
190
|
+
新 React SPA 应用的公开访问使用应用路由和公开策略资源:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"code": "public.register",
|
|
195
|
+
"pathPattern": "/view/:appType/public/register",
|
|
196
|
+
"publicAccess": "guest",
|
|
197
|
+
"publicPolicyCode": "public_register"
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"code": "public_register",
|
|
204
|
+
"mode": "guest",
|
|
205
|
+
"routeCode": "public.register",
|
|
206
|
+
"externalRoleCodes": ["external_visitor"],
|
|
207
|
+
"grants": {
|
|
208
|
+
"forms": ["registration_form"],
|
|
209
|
+
"dataViews": ["public_registration_lookup"],
|
|
210
|
+
"functions": ["submit_public_registration"],
|
|
211
|
+
"connectors": ["sms.sendCode"]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Rules:
|
|
217
|
+
|
|
218
|
+
- Public routes live under `/view/:appType/public/*`.
|
|
219
|
+
- Public users get a scoped `publicAccess` claim, not a normal app role assignment.
|
|
220
|
+
- Use virtual external role codes, such as `external_visitor`, in page/form/dataView permission groups.
|
|
221
|
+
- Form/dataView/function/connector access is denied unless the policy explicitly grants it.
|
|
222
|
+
- `mode: "ticket"` requires a valid ticket for sensitive links.
|
|
223
|
+
- Do not use `?publicAccess=guest` for new React SPA apps.
|
|
224
|
+
|
|
225
|
+
Legacy form public access config:
|
|
189
226
|
|
|
190
227
|
```json
|
|
191
228
|
{
|
|
@@ -194,4 +231,4 @@ Public access config:
|
|
|
194
231
|
}
|
|
195
232
|
```
|
|
196
233
|
|
|
197
|
-
|
|
234
|
+
This old form-level setting is resolved by `appType + formUuid` and exists only for old `sy-lowcode-view` compatibility.
|
|
@@ -101,7 +101,72 @@ await auth.phoneCodeLogin({ phone, code, challengeId: sent.challengeId });
|
|
|
101
101
|
|
|
102
102
|
设计前必须确认启用方式、注册策略、身份匹配键、provider 边界、默认权限、安全参数、第三方配置归属。
|
|
103
103
|
|
|
104
|
-
## 1.
|
|
104
|
+
## 1. Public Route — `src/resources/routes/<code>.json`
|
|
105
|
+
|
|
106
|
+
新 React SPA 公开页使用 `/view/:appType/public/*`,不要再使用旧 `?publicAccess=guest`。
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"code": "public.register",
|
|
111
|
+
"title": "公开报名",
|
|
112
|
+
"kind": "page",
|
|
113
|
+
"pathPattern": "/view/:appType/public/register",
|
|
114
|
+
"publicAccess": "guest",
|
|
115
|
+
"publicPolicyCode": "public_register"
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
React Router 中用 `PublicAccessGate` 创建 scoped public session:
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { PublicAccessGate } from "openxiangda/runtime/react";
|
|
123
|
+
|
|
124
|
+
<PublicAccessGate policyCode="public_register" routeCode="public.register">
|
|
125
|
+
<PublicRegisterPage />
|
|
126
|
+
</PublicAccessGate>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 2. Public Access Policy — `src/resources/public-access/<code>.json`
|
|
130
|
+
|
|
131
|
+
公开策略声明外部角色和可访问资源。未显式 grant 的 form/dataView/function/connector 默认拒绝;grant 后仍受对应后端权限组控制。
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"code": "public_register",
|
|
136
|
+
"name": "公开报名入口",
|
|
137
|
+
"mode": "guest",
|
|
138
|
+
"routeCode": "public.register",
|
|
139
|
+
"pathPattern": "/view/:appType/public/register",
|
|
140
|
+
"externalRoleCodes": ["external_visitor"],
|
|
141
|
+
"grants": {
|
|
142
|
+
"forms": ["registration_form"],
|
|
143
|
+
"dataViews": ["public_registration_lookup"],
|
|
144
|
+
"functions": ["submit_public_registration"],
|
|
145
|
+
"connectors": ["sms.sendCode"]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Ticket 模式:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"code": "public_score_lookup",
|
|
155
|
+
"name": "公开成绩查询",
|
|
156
|
+
"mode": "ticket",
|
|
157
|
+
"routeCode": "public.scoreLookup",
|
|
158
|
+
"pathPattern": "/view/:appType/public/score",
|
|
159
|
+
"externalRoleCodes": ["external_ticket_holder"],
|
|
160
|
+
"ticketConfig": { "ttlSeconds": 1800 },
|
|
161
|
+
"grants": {
|
|
162
|
+
"dataViews": ["public_score_lookup"]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`grants.forms` 可以写本地 `formCode`,CLI 发布时会解析为真实 `formUuid`。
|
|
168
|
+
|
|
169
|
+
## 3. Connector — `src/resources/connectors/<code>.json`
|
|
105
170
|
|
|
106
171
|
```json
|
|
107
172
|
{
|
|
@@ -140,7 +205,7 @@ const data = await sdk.connector.call("crm.getCustomer", { body: { keyword } });
|
|
|
140
205
|
|
|
141
206
|
不要把 `authConfig` 里的真实 secret 写进 manifest;用 placeholder,由平台管理员在后台覆盖。完整字段见 [`connector-resources.md`](connector-resources.md)。
|
|
142
207
|
|
|
143
|
-
##
|
|
208
|
+
## 4. Data View — `src/resources/data-views/<code>.json`
|
|
144
209
|
|
|
145
210
|
选择规则:
|
|
146
211
|
|
|
@@ -488,11 +553,12 @@ export default async function (ctx) {
|
|
|
488
553
|
{ "fields": ["customerCode"], "unique": true },
|
|
489
554
|
{ "fields": ["status", "ownerDept"] }
|
|
490
555
|
],
|
|
491
|
-
"dataManagement": { "enabled": true, "default": "list" }
|
|
492
|
-
"publicAccess": { "enabled": false }
|
|
556
|
+
"dataManagement": { "enabled": true, "default": "list" }
|
|
493
557
|
}
|
|
494
558
|
```
|
|
495
559
|
|
|
560
|
+
`publicAccess` 表单 setting 只用于旧 `sy-lowcode-view` 兼容。新 React SPA 公开页面必须使用 `src/resources/routes/` + `src/resources/public-access/` + `PublicAccessGate`。
|
|
561
|
+
|
|
496
562
|
## 12. Menu — `src/resources/menus/<code>.json`
|
|
497
563
|
|
|
498
564
|
```json
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openxiangda",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.87",
|
|
4
4
|
"description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"prepack": "npm run build:sdk",
|
|
66
66
|
"test:profile-isolation": "bash scripts/profile-isolation-smoke.sh",
|
|
67
67
|
"test:resource-plan": "node scripts/resource-plan-smoke.mjs",
|
|
68
|
+
"test:app-function-fallback": "node scripts/app-function-source-fallback-smoke.mjs",
|
|
68
69
|
"test:runtime-deploy": "node scripts/runtime-deploy-smoke.mjs",
|
|
69
70
|
"test:skill-install": "bash scripts/skill-install-smoke.sh",
|
|
70
71
|
"test:workspace-init": "bash scripts/workspace-init-smoke.sh"
|