@h-ai/cli 0.1.0-alpha9 → 1.0.0-beta.2
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.en.md +229 -0
- package/README.ja.md +229 -0
- package/README.md +175 -113
- package/dist/chunk-AKV2CQZV.js +1497 -0
- package/dist/chunk-AKV2CQZV.js.map +1 -0
- package/dist/chunk-EF7WOFWZ.js +7557 -0
- package/dist/chunk-EF7WOFWZ.js.map +1 -0
- package/dist/chunk-MUHRBJSW.js +29272 -0
- package/dist/chunk-MUHRBJSW.js.map +1 -0
- package/dist/chunk-ZSDEVXZ7.js +38 -0
- package/dist/{chunk-2H7UOFLK.js.map → chunk-ZSDEVXZ7.js.map} +1 -1
- package/dist/cli-config-templates-HHFHNXBN.js +5 -0
- package/dist/cli-config-templates-HHFHNXBN.js.map +1 -0
- package/dist/cli-skill-templates-PN4FLGBC.js +5 -0
- package/dist/cli-skill-templates-PN4FLGBC.js.map +1 -0
- package/dist/index.js +4444 -554
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -0
- package/dist/src-TEBHR5I5.js +5 -0
- package/dist/src-TEBHR5I5.js.map +1 -0
- package/package.json +35 -15
- package/templates/README.md +56 -114
- package/templates/apps/admin/messages/en-US.json +7 -0
- package/templates/apps/admin/messages/ja-JP.json +40 -0
- package/templates/apps/admin/messages/zh-CN.json +7 -0
- package/templates/apps/admin/src/routes/+layout.svelte.hbs +65 -8
- package/templates/apps/admin/src/routes/+page.svelte.hbs +35 -14
- package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +54 -22
- package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +33 -24
- package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +16 -13
- package/templates/apps/api/.dockerignore.hbs +25 -0
- package/templates/apps/api/.gitignore.hbs +22 -0
- package/templates/apps/api/.npmrc.hbs +1 -0
- package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +39 -0
- package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +41 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-contract.ts.hbs +27 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +28 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/index.ts.hbs +5 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +16 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +18 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tsconfig.json.hbs +12 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +11 -0
- package/templates/apps/api/apps/{{projectName}}-contract/vitest.config.ts.hbs +9 -0
- package/templates/apps/api/apps/{{projectName}}-serv/README.md.hbs +60 -0
- package/templates/apps/api/apps/{{projectName}}-serv/config/_core.yml.hbs +17 -0
- package/templates/apps/api/apps/{{projectName}}-serv/config/_serv.yml.hbs +54 -0
- package/templates/apps/api/apps/{{projectName}}-serv/data/.gitkeep.hbs +1 -0
- package/templates/apps/api/apps/{{projectName}}-serv/package.json.hbs +66 -0
- package/templates/apps/api/apps/{{projectName}}-serv/src/app.ts.hbs +119 -0
- package/templates/apps/api/apps/{{projectName}}-serv/src/build-metadata.ts.hbs +7 -0
- package/templates/apps/api/apps/{{projectName}}-serv/src/index.ts.hbs +41 -0
- package/templates/apps/api/apps/{{projectName}}-serv/src/lib/server/init.ts.hbs +165 -0
- package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +57 -0
- package/templates/apps/api/apps/{{projectName}}-serv/src/server/procedures/index.ts.hbs +41 -0
- package/templates/apps/api/apps/{{projectName}}-serv/tests/service.test.ts.hbs +176 -0
- package/templates/apps/api/apps/{{projectName}}-serv/tsconfig.json.hbs +16 -0
- package/templates/apps/api/apps/{{projectName}}-serv/tsup.config.ts.hbs +20 -0
- package/templates/apps/api/apps/{{projectName}}-serv/vitest.config.ts.hbs +12 -0
- package/templates/apps/api/e2e/api-serv.spec.ts.hbs +113 -0
- package/templates/apps/api/e2e/capture-evidence.ts.hbs +23 -0
- package/templates/apps/api/eslint.config.js.hbs +30 -0
- package/templates/apps/api/hai.json.hbs +4 -0
- package/templates/apps/api/images/serv.Dockerfile.hbs +37 -0
- package/templates/apps/api/package.json.hbs +53 -0
- package/templates/apps/api/playwright.config.ts.hbs +67 -0
- package/templates/apps/api/pnpm-workspace.yaml.hbs +40 -0
- package/templates/apps/api/tsconfig.base.json +14 -0
- package/templates/apps/fullstack/.dockerignore.hbs +25 -0
- package/templates/apps/fullstack/.gitignore.hbs +38 -0
- package/templates/apps/fullstack/.npmrc.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/.env.example.hbs +10 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +67 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +22 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/en-US.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/ja-JP.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/zh-CN.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +86 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/project.inlang/settings.json.hbs +17 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/public/runtime-config.js.hbs +4 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +59 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.css.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.d.ts.hbs +8 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/build-metadata.ts.hbs +9 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +19 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/main.ts.hbs +21 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/tsconfig.json.hbs +23 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +74 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/.env.example.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +64 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/eslint.config.js.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/index.html.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/en-US.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/ja-JP.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/messages/zh-CN.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +66 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/project.inlang/settings.json.hbs +17 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +25 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.css.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.d.ts.hbs +8 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/build-metadata.ts.hbs +9 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/main.ts.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/Cargo.toml.hbs +33 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/build.rs.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/capabilities/default.json.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128@2x.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/32x32.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.icns +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.ico +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/lib.rs.hbs +91 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/main.rs.hbs +8 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +46 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +14 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/tsconfig.json.hbs +22 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +89 -0
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/README.md.hbs +25 -0
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/en-US.json.hbs +12 -0
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/ja-JP.json.hbs +12 -0
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/messages/zh-CN.json.hbs +12 -0
- package/templates/apps/fullstack/apps/{{projectName}}-miniapp/project.inlang/settings.json.hbs +17 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +54 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +20 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +21 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/messages/en-US.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/messages/ja-JP.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/messages/zh-CN.json.hbs +7 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +53 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/project.inlang/settings.json.hbs +17 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/public/runtime-config.js.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/App.svelte.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.css.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.d.ts.hbs +8 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/build-metadata.ts.hbs +9 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +14 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/tsconfig.json.hbs +23 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +76 -0
- package/templates/apps/fullstack/docs/security-configuration.md.hbs +349 -0
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +988 -0
- package/templates/apps/fullstack/e2e/session-close.spec.ts.hbs +119 -0
- package/templates/apps/fullstack/eslint.config.js.hbs +41 -0
- package/templates/apps/fullstack/hai.json.hbs +11 -0
- package/templates/apps/fullstack/images/serv.Dockerfile.hbs +38 -0
- package/templates/apps/fullstack/images/web/19-runtime-config.envsh.hbs +5 -0
- package/templates/apps/fullstack/images/web/nginx.conf.hbs +24 -0
- package/templates/apps/fullstack/images/web/runtime-config.js.template.hbs +3 -0
- package/templates/apps/fullstack/images/web.Dockerfile.hbs +37 -0
- package/templates/apps/fullstack/package.json.hbs +61 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/README.md.hbs +40 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +30 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-contract.ts.hbs +78 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/admin-schemas.ts.hbs +134 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/app-contract.ts.hbs +20 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/app-schemas.ts.hbs +35 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/index.ts.hbs +7 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +23 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/tests/contract.test.ts.hbs +31 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/tsconfig.json.hbs +9 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/tsup.config.ts.hbs +9 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +84 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_ai.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_audit.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_cache.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +22 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_db.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_feedback.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_iam.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_payment.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_reach.yml.hbs +60 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_scheduler.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +64 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_storage.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_vecdb.yml.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/data/.gitkeep.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +62 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +115 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/build-metadata.ts.hbs +7 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +40 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/admin-service.ts.hbs +294 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/audit-jobs.ts.hbs +28 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/business-settings.ts.hbs +50 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/messages.ts.hbs +50 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +106 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/app-procedures.ts.hbs +49 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/index.ts.hbs +34 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/runtime.ts.hbs +159 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/security-roles.ts.hbs +73 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/app-server.test.ts.hbs +505 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/runtime.test.ts.hbs +72 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/security.test.ts.hbs +183 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tsconfig.json.hbs +10 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tsup.config.ts.hbs +18 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/vitest.config.ts.hbs +12 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/.gitignore.hbs +10 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +97 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +164 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/ja-JP.json.hbs +164 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +164 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +55 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/project.inlang/settings.json.hbs +11 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/index.ts.hbs +7 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +94 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/feedback-client.ts.hbs +36 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/sensitive-actions.svelte.ts.hbs +16 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/session-recovery.svelte.ts.hbs +4 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +122 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +90 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/FeedbackEntry.svelte.hbs +86 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/audit.svelte.hbs +94 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/configuration.svelte.hbs +25 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/feedback.svelte.hbs +157 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/roles.svelte.hbs +77 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/settings.svelte.hbs +44 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/pages/users.svelte.hbs +216 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/security/role-label.ts.hbs +12 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/guide-store.ts.hbs +55 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/management-store.svelte.ts.hbs +614 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/theme-store.svelte.ts.hbs +23 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/svelte.config.js.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/api-client.test.ts.hbs +150 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tests/management-store.test.ts.hbs +253 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tsconfig.json.hbs +17 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/vitest.config.ts.hbs +7 -0
- package/templates/apps/fullstack/playwright.config.ts.hbs +114 -0
- package/templates/apps/fullstack/playwright.session-close.config.ts.hbs +18 -0
- package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +38 -0
- package/templates/apps/fullstack/tsconfig.base.json +14 -0
- package/templates/apps/h5/messages/en-US.json +3 -0
- package/templates/apps/h5/messages/ja-JP.json +40 -0
- package/templates/apps/h5/messages/zh-CN.json +3 -0
- package/templates/apps/h5/src/routes/+layout.svelte.hbs +85 -30
- package/templates/apps/h5/src/routes/+page.svelte.hbs +20 -8
- package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +17 -6
- package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +17 -6
- package/templates/apps/mobile-app/.env.hbs +3 -0
- package/templates/apps/{android-app → mobile-app}/capacitor.config.ts.hbs +2 -2
- package/templates/apps/mobile-app/index.html.hbs +14 -0
- package/templates/apps/mobile-app/messages/en-US.json +36 -0
- package/templates/apps/mobile-app/messages/ja-JP.json +36 -0
- package/templates/apps/mobile-app/messages/zh-CN.json +36 -0
- package/templates/apps/mobile-app/public/runtime-config.js +1 -0
- package/templates/apps/mobile-app/src/App.svelte.hbs +153 -0
- package/templates/apps/mobile-app/src/lib/api.ts.hbs +213 -0
- package/templates/apps/mobile-app/src/lib/app-config.ts.hbs +14 -0
- package/templates/apps/{android-app → mobile-app}/src/lib/capacitor.ts +6 -7
- package/templates/apps/mobile-app/src/lib/pages/home.svelte.hbs +58 -0
- package/templates/apps/mobile-app/src/lib/pages/profile.svelte.hbs +13 -0
- package/templates/apps/mobile-app/src/lib/pages/tasks.svelte.hbs +16 -0
- package/templates/apps/mobile-app/src/main.ts.hbs +11 -0
- package/templates/apps/website/messages/en-US.json +4 -2
- package/templates/apps/website/messages/ja-JP.json +34 -0
- package/templates/apps/website/messages/zh-CN.json +4 -2
- package/templates/apps/website/scripts/static-website.mjs.hbs +67 -0
- package/templates/apps/website/src/routes/+layout.svelte.hbs +77 -26
- package/templates/apps/website/src/routes/+layout.ts +3 -0
- package/templates/apps/website/src/routes/+page.svelte.hbs +31 -12
- package/templates/apps/website/src/routes/about/+page.svelte.hbs +11 -6
- package/templates/apps/website/src/routes/api/health/+server.ts +3 -0
- package/templates/apps/website/src/routes/contact/+page.svelte.hbs +44 -34
- package/templates/apps/website/src/routes/services/+page.svelte.hbs +27 -40
- package/templates/base/.dockerignore.hbs +27 -0
- package/templates/base/.gitignore.hbs +41 -0
- package/templates/base/.npmrc.hbs +1 -0
- package/templates/base/e2e/app.spec.ts.hbs +213 -0
- package/templates/base/e2e/helpers.ts +1 -1
- package/templates/base/eslint-rules.js +45 -0
- package/templates/base/eslint.config.js.hbs +34 -0
- package/templates/base/hai.json.hbs +4 -0
- package/templates/base/images/web/nginx.conf.hbs +24 -0
- package/templates/base/images/web.Dockerfile.hbs +72 -0
- package/templates/base/package.json.hbs +125 -49
- package/templates/base/playwright.config.ts +44 -6
- package/templates/base/pnpm-workspace.yaml.hbs +40 -0
- package/templates/base/src/app.css.hbs +40 -0
- package/templates/base/src/app.d.ts.hbs +14 -1
- package/templates/base/src/app.html.hbs +13 -0
- package/templates/base/src/hooks.server.ts.hbs +115 -43
- package/templates/base/src/lib/build-metadata.ts.hbs +7 -0
- package/templates/base/src/lib/server/init.ts.hbs +125 -152
- package/templates/base/src/lib/server/kit-config.ts.hbs +40 -0
- package/templates/base/src/routes/+layout.server.ts.hbs +35 -0
- package/templates/base/static/favicon.png +0 -0
- package/templates/base/svelte.config.js.hbs +84 -5
- package/templates/base/tests/scaffold.test.ts.hbs +102 -0
- package/templates/base/tsconfig.json.hbs +50 -0
- package/templates/base/vite.config.ts.hbs +117 -12
- package/templates/base/vitest.config.ts.hbs +19 -0
- package/templates/features/ai/routes/api/chat/+server.ts +6 -7
- package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +3 -17
- package/templates/features/iam/routes-admin/(auth)/auth/forgot-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +9 -96
- package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +9 -122
- package/templates/features/iam/routes-admin/(auth)/auth/reset-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-h5/auth/forgot-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +9 -96
- package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +9 -112
- package/templates/features/iam/routes-h5/auth/reset-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-shared/api/auth/captcha/+server.ts.hbs +4 -0
- package/templates/features/iam/routes-shared/api/auth/config/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/login/+server.ts +1 -29
- package/templates/features/iam/routes-shared/api/auth/login/ldap/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/login/otp/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/logout/+server.ts +13 -6
- package/templates/features/iam/routes-shared/api/auth/otp/send/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/password/renew/+server.ts +5 -0
- package/templates/features/iam/routes-shared/api/auth/password-reset/confirm/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/password-reset/request/+server.ts +4 -0
- package/templates/features/iam/routes-shared/api/auth/reauthenticate/+server.ts +5 -0
- package/templates/features/iam/routes-shared/api/auth/register/+server.ts +1 -23
- package/templates/features/iam/routes-shared/api/auth/session/close/+server.ts.hbs +4 -0
- package/templates/features/iam/routes-website/auth/forgot-password/+page.svelte.hbs +10 -0
- package/templates/features/iam/routes-website/auth/login/+page.svelte.hbs +11 -0
- package/templates/features/iam/routes-website/auth/register/+page.svelte.hbs +11 -0
- package/templates/features/iam/routes-website/auth/reset-password/+page.svelte.hbs +10 -0
- package/templates/features/payment/routes/api/v1/payment/create/+server.ts +25 -23
- package/templates/features/payment/routes/api/v1/payment/notify/[provider]/+server.ts +5 -2
- package/templates/features/storage/routes/api/upload/+server.ts +10 -8
- package/templates/i18n/project.inlang/settings.json +2 -2
- package/templates/shared/.gitattributes +11 -0
- package/templates/shared/build-metadata.ts +42 -0
- package/templates/shared/container-runtime-config.sh +30 -0
- package/templates/shared/e2e-env.ts +98 -0
- package/templates/shared/hash-router.svelte.ts +83 -0
- package/templates/shared/public-base-path.mjs +19 -0
- package/templates/shared/run-e2e.mjs +104 -0
- package/templates/shared/vite-runtime-config.ts +56 -0
- package/templates/skills/AGENTS.md +75 -16
- package/templates/skills/CLAUDE.md +0 -11
- package/templates/skills/bridges/admin/AGENTS.md +89 -0
- package/templates/skills/bridges/api/AGENTS.md +83 -0
- package/templates/skills/bridges/fullstack/AGENTS.md.hbs +102 -0
- package/templates/skills/bridges/h5/AGENTS.md +88 -0
- package/templates/skills/bridges/mobile-app/AGENTS.md +100 -0
- package/templates/skills/bridges/website/AGENTS.md +88 -0
- package/templates/skills/copilot-instructions.md +3 -59
- package/templates/skills/hai-ai/SKILL.md +44 -715
- package/templates/skills/hai-ai/guide.md +457 -0
- package/templates/skills/hai-ai/reference.md +292 -0
- package/templates/skills/hai-api-client/SKILL.md +26 -339
- package/templates/skills/hai-api-client/reference.md +180 -0
- package/templates/skills/hai-api-contract/SKILL.md +36 -0
- package/templates/skills/hai-api-contract/reference.md +280 -0
- package/templates/skills/hai-app-create/SKILL.md +38 -351
- package/templates/skills/hai-app-create/collaboration.md +52 -0
- package/templates/skills/hai-app-create/development.md +243 -0
- package/templates/skills/hai-app-create/reference.md +376 -0
- package/templates/skills/hai-app-review/SKILL.md +57 -126
- package/templates/skills/hai-app-review/differential.md +34 -0
- package/templates/skills/hai-app-tests/SKILL.md +34 -454
- package/templates/skills/hai-app-tests/reference.md +462 -0
- package/templates/skills/hai-app-tests/validation.md +42 -0
- package/templates/skills/hai-audit/SKILL.md +37 -122
- package/templates/skills/hai-audit/reference.md +184 -0
- package/templates/skills/hai-build/SKILL.md +62 -315
- package/templates/skills/hai-build/paths.md +30 -0
- package/templates/skills/hai-build/reference.md +353 -0
- package/templates/skills/hai-cache/SKILL.md +26 -175
- package/templates/skills/hai-cache/reference.md +229 -0
- package/templates/skills/hai-capacitor/SKILL.md +24 -364
- package/templates/skills/hai-capacitor/reference.md +358 -0
- package/templates/skills/hai-change-plan/SKILL.md +46 -0
- package/templates/skills/hai-ci/SKILL.md +114 -0
- package/templates/skills/hai-core/SKILL.md +31 -469
- package/templates/skills/hai-core/reference.md +557 -0
- package/templates/skills/hai-core/request-access.md +65 -0
- package/templates/skills/hai-crypto/SKILL.md +29 -180
- package/templates/skills/hai-crypto/reference.md +317 -0
- package/templates/skills/hai-datapipe/SKILL.md +24 -207
- package/templates/skills/hai-datapipe/reference.md +204 -0
- package/templates/skills/hai-deploy/SKILL.md +53 -178
- package/templates/skills/hai-deploy/credentials.md +19 -0
- package/templates/skills/hai-deploy/middleware.md +129 -0
- package/templates/skills/hai-feedback/SKILL.md +85 -0
- package/templates/skills/hai-framework-sync/SKILL.md +105 -0
- package/templates/skills/hai-framework-sync/sync.md +49 -0
- package/templates/skills/hai-iam/SKILL.md +53 -325
- package/templates/skills/hai-iam/reference.md +535 -0
- package/templates/skills/hai-kit/SKILL.md +33 -329
- package/templates/skills/hai-kit/reference.md +202 -0
- package/templates/skills/hai-payment/SKILL.md +28 -262
- package/templates/skills/hai-payment/reference.md +295 -0
- package/templates/skills/hai-pr-review/SKILL.md +41 -0
- package/templates/skills/hai-reach/SKILL.md +28 -300
- package/templates/skills/hai-reach/reference.md +363 -0
- package/templates/skills/hai-reldb/SKILL.md +28 -449
- package/templates/skills/hai-reldb/reference.md +500 -0
- package/templates/skills/hai-scheduler/SKILL.md +26 -174
- package/templates/skills/hai-scheduler/reference.md +216 -0
- package/templates/skills/hai-serv/SKILL.md +60 -0
- package/templates/skills/hai-serv/reference.md +792 -0
- package/templates/skills/hai-spec-implement/SKILL.md +50 -0
- package/templates/skills/hai-spec-implement/changes.md +67 -0
- package/templates/skills/hai-spec-implement/evaluation.md +18 -0
- package/templates/skills/hai-spec-implement/handoff.md +47 -0
- package/templates/skills/hai-spec-implement/templates.md +117 -0
- package/templates/skills/hai-spec-implement/workflow.md +56 -0
- package/templates/skills/hai-spec-review/SKILL.md +57 -0
- package/templates/skills/hai-spec-review/checklist.md +71 -0
- package/templates/skills/hai-storage/SKILL.md +31 -262
- package/templates/skills/hai-storage/reference.md +284 -0
- package/templates/skills/hai-ui/SKILL.md +62 -238
- package/templates/skills/hai-ui/guide.md +81 -0
- package/templates/skills/hai-ui/reference.md +705 -0
- package/templates/skills/hai-ui-design/SKILL.md +31 -0
- package/templates/skills/hai-ui-design/patterns.md +31 -0
- package/templates/skills/hai-ui-review/SKILL.md +32 -0
- package/templates/skills/hai-ui-review/checklist.md +29 -0
- package/templates/skills/hai-vecdb/SKILL.md +25 -267
- package/templates/skills/hai-vecdb/reference.md +325 -0
- package/templates/skills/opencode.json +0 -5
- package/dist/chunk-2H7UOFLK.js +0 -10
- package/dist/chunk-LANIDJC7.js +0 -659
- package/dist/chunk-LANIDJC7.js.map +0 -1
- package/dist/chunk-YV7WPUI6.js +0 -206
- package/dist/chunk-YV7WPUI6.js.map +0 -1
- package/dist/config-templates-S5RI2MC6.js +0 -5
- package/dist/config-templates-S5RI2MC6.js.map +0 -1
- package/dist/skill-templates-N5DU5FNX.js +0 -5
- package/dist/skill-templates-N5DU5FNX.js.map +0 -1
- package/dist/src-XJ6YXNAF.js +0 -15030
- package/dist/src-XJ6YXNAF.js.map +0 -1
- package/templates/apps/android-app/.env.hbs +0 -3
- package/templates/apps/android-app/messages/en-US.json +0 -24
- package/templates/apps/android-app/messages/zh-CN.json +0 -24
- package/templates/apps/android-app/src/lib/api.ts.hbs +0 -30
- package/templates/apps/android-app/src/routes/+layout.svelte.hbs +0 -42
- package/templates/apps/android-app/src/routes/+layout.ts +0 -7
- package/templates/apps/android-app/src/routes/+page.svelte.hbs +0 -27
- package/templates/apps/api/src/routes/+layout.svelte +0 -14
- package/templates/apps/api/src/routes/+page.svelte +0 -11
- package/templates/apps/api/src/routes/api/v1/health/+server.ts +0 -14
- package/templates/apps/api/src/routes/api/v1/items/+server.ts +0 -37
- package/templates/apps/api/src/routes/api/v1/items/[id]/+server.ts +0 -30
- package/templates/base/src/app.css +0 -2
- package/templates/base/tsconfig.json +0 -8
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hai-framework-sync
|
|
3
|
+
description: "升级应用的 hai-framework 到最新或指定发布版本:分析版本差异、提示用户选择与阻塞、迁移依赖/代码/配置并同步 skills;排查 npm/本地漂移。"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# hai-framework-sync — 框架升级与同步
|
|
7
|
+
|
|
8
|
+
## 能力契约
|
|
9
|
+
|
|
10
|
+
| 项目 | 契约 |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| 能力 | 发现最新发布版本,比较当前到目标的累计差异,处理选择与阻塞,完成应用升级及 skills/AI 入口同步 |
|
|
13
|
+
| 适用场景 | “升级 Hai-framework 到最新版本”、指定版本升级、版本差异审查、模板同步或 npm/本地联调漂移排查 |
|
|
14
|
+
| 输入 | 当前应用、升级目标及已有约束;当前版本、registry、架构与本地覆盖从项目读取,不要求用户预先提供框架源目录 |
|
|
15
|
+
| 输出 | 当前/目标版本及来源、差异与处理清单、迁移后的依赖/代码/配置/skills、验证结果;未完成时给出选择或阻塞及恢复步骤 |
|
|
16
|
+
| 限制 | 仅操作授权项目,保留已有改动、架构和私有规则;以实际发布产物为准,未确认选择或未解除阻塞不得越过 |
|
|
17
|
+
|
|
18
|
+
## 任务入口
|
|
19
|
+
|
|
20
|
+
- 用户说“升级 Hai-framework 到最新版本”时,直接从当前应用执行下方升级流程。该请求已授权常规依赖更新、必要兼容迁移、skills 合并和本地验证;不为每个文件修改重复确认,也不只输出升级建议后结束。
|
|
21
|
+
- 用户仅要求审查/比较版本时,完成现状、目标与差异分析,不安装或修改应用。
|
|
22
|
+
- 仅同步通用规范、AI 入口或联调两个仓库时,按需读取 [同步与本地联调](sync.md);普通应用升级不要求框架仓库可写。
|
|
23
|
+
- 先识别当前目录是否为目标应用;确实无法确定目标项目时才询问。应用升级不包含 npm 发布、部署、生产数据迁移或系统级工具安装,已有明确授权时按其范围执行。
|
|
24
|
+
|
|
25
|
+
## 升级流程
|
|
26
|
+
|
|
27
|
+
### 1. 确认现状
|
|
28
|
+
|
|
29
|
+
读取 AGENTS、README、package.json、workspace 配置、lockfile 与相关初始化/调用点,用 `rg` 搜索实现、引用、测试和版本配置。记录 Git 状态及已有改动;工作区有改动本身不构成阻塞,不清空、覆盖或自动 stash 用户工作。
|
|
30
|
+
|
|
31
|
+
- 识别包管理器、Node/包管理器版本、实际 scripts,以及 SvelteKit、API workspace、fullstack、Vite SPA 或原生端架构。
|
|
32
|
+
- 盘点全部 workspace 实际消费的 `@h-ai/*`:记录声明位置、lockfile 解析版本、已安装版本及 npm/local 模式。核对 `catalog`/命名 catalogs、overrides、patchedDependencies、file/link/workspace 映射和联调脚本,不能只看根 package.json。
|
|
33
|
+
- 混用多个版本时分别保留基线;未安装依赖时标明已安装版本不可得,以 lockfile 为比较基线,安装后补验。关联代码、配置、环境变量名及 AI 入口,记录已有质量问题;不输出凭据或完整私有配置。
|
|
34
|
+
|
|
35
|
+
### 2. 发现并固定目标
|
|
36
|
+
|
|
37
|
+
使用项目有效 registry(包含 scope registry)在线查询;无法访问时诊断网络/镜像/权限,不把缓存或记忆中的版本说成“最新”。
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# 查询示例;PowerShell 使用 npm.cmd / pnpm.cmd。
|
|
41
|
+
npm view @h-ai/core dist-tags --json
|
|
42
|
+
npm view @h-ai/core@latest version engines dist --json
|
|
43
|
+
npm view @h-ai/cli dist-tags --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- 未指定版本/通道时,以 `@h-ai/core` 的 `latest` 为候选;`latest` 即使指向预发布版也应说明并按该通道分析。用户指定版本、稳定版或其他 dist-tag 时遵循其目标;没有满足条件的发布版时提示处理,不擅自替换。
|
|
47
|
+
- 对每个已用框架包及用于模板同步的 `@h-ai/cli`,逐一查询候选**精确版本**的存在性、deprecated、engines、dependencies/peerDependencies 和 dist 信息。新增的必要框架依赖同样核验;不能因 core 或 CLI 已发布就假定整组已发布。
|
|
48
|
+
- 记录查询时间、registry、每包当前/目标版本与发布产物来源,固定本次目标。发布不齐、镜像滞后、目标被弃用或应用实际采用比候选更晚的发布版时,说明差异并让用户选择等待、指定可用版本/来源或取消相关升级,不静默降级或混装。判断发布先后结合官方发布序列,不能因旧命名 `alpha9` 的 SemVer 排序就认定它更晚。
|
|
49
|
+
- 使用精确版本;不能用 `versions` 的字典序、最大 SemVer 或 `pnpm update --latest` 代替 dist-tag 决策。旧命名 `alpha9` 可能在 SemVer 中高于 `alpha.58`,`^`/`~` 范围不保证选中本次目标。
|
|
50
|
+
|
|
51
|
+
### 3. 比较累计差异并关联应用
|
|
52
|
+
|
|
53
|
+
在修改依赖前,读取当前到目标版本之间的 Release/CHANGELOG、迁移说明及官方提交差异,覆盖中间版本;混版本逐包比较。上游仓库从包元数据或官方 README 确认,按发布 tag/commit 定位,不能把 main 分支的未发布能力归到目标版本。
|
|
54
|
+
|
|
55
|
+
没有本地框架源码也应继续:在临时目录用 `npm pack <包名>@<精确版本> --ignore-scripts --pack-destination <临时目录>` 获取当前/目标包,比较 package.json.exports、公开 `.d.ts`、配置 schema/默认值、实现与随包文档;从同版本 CLI 的 `templates/skills/` 获取完整技能目录及入口模板。占位参数先替换为已确认值;只读比较产物,不覆盖应用或执行其中脚本。命令依据:[npm view](https://docs.npmjs.com/cli/commands/npm-view)、[npm pack](https://docs.npmjs.com/cli/commands/npm-pack)。
|
|
56
|
+
|
|
57
|
+
发布说明不足时以产物、对应源码和测试补充证据;关键兼容差异无法核实时标为待核实/阻塞,不能推断“无破坏性变更”。
|
|
58
|
+
|
|
59
|
+
逐项检查并关联实际文件/调用点:
|
|
60
|
+
|
|
61
|
+
- 公开入口、API/类型/错误码、HaiResult 与流/抛错语义、初始化依赖和关闭行为。
|
|
62
|
+
- 配置 schema、默认行为、环境覆盖、认证/安全策略、DB schema/迁移、外部服务与引擎要求。
|
|
63
|
+
- 构建/运行/发布脚本、第三方 peer 依赖、原生/容器集成,以及版本绑定的补丁是否仍必要。
|
|
64
|
+
- skills 及相邻资源、AGENTS/Claude/Copilot/OpenCode 路由;新能力是否可替换本次相关的自定义实现或配置。按 [能力选择规则](../hai-app-create/development.md) 判断适用性,不为升级强行安装无关模块或转换架构。
|
|
65
|
+
|
|
66
|
+
先给出可追踪的差异清单,再执行迁移:
|
|
67
|
+
|
|
68
|
+
| 差异/证据 | 应用位置与影响 | 处理类别 | 迁移或选项 | 验收与状态 |
|
|
69
|
+
| --- | --- | --- | --- | --- |
|
|
70
|
+
| 当前 → 目标及发布/产物位置 | 具体调用、配置、依赖或“不适用”的依据 | 自动处理 / 用户选择 / 阻塞 / 不适用 | 必要修正或带取舍的方案 | 可观察验收、待处理/已解决/待用户 |
|
|
71
|
+
|
|
72
|
+
### 4. 处理用户选择与阻塞
|
|
73
|
+
|
|
74
|
+
| 类别 | 处理方式 |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| 自动处理 | 目标明确、可保持现有行为的依赖更新、兼容性修正、无冲突的 skills 合并和验证,直接执行 |
|
|
77
|
+
| 用户选择 | 存在多个有意义的方案且影响产品行为、架构、成本、Provider 或运维方式,展示证据、选项、推荐与取舍,等待回答 |
|
|
78
|
+
| 阻塞 | 无法取得必要产物、依赖不兼容、无法无损合并、必要工具/服务/授权缺失等导致后续无法执行,先处理可自行解决的原因;仍无法推进时说明具体步骤。普通门禁失败先记录,继续独立检查,本轮汇总后集中修复;必要门禁未通过仍不能交付完成 |
|
|
79
|
+
| 不适用 | 当前应用未使用且不影响其依赖/运行的变化,记录依据;不要求用户逐项确认 |
|
|
80
|
+
|
|
81
|
+
- 尽量合并相互独立的选择,明确每个回答控制哪项改动;已给出的目标、授权和选择持续有效,不重复询问。
|
|
82
|
+
- 提问时给出问题位置、事实、影响、可选路径及推荐。用户未回答时保持选择待定,可继续独立分析/验证;不能以等待超时替用户选择,也不能先安装一部分框架包造成混版本。
|
|
83
|
+
- 阻塞报告包含失败命令、退出码、脱敏关键错误、受影响步骤、已尝试处理、用户最小操作和解除后的验证方式。不要求在聊天中粘贴密钥,不通过关闭检查、忽略 engines 或无依据覆盖依赖掩盖失败。
|
|
84
|
+
- 涉及不可逆数据迁移、删除私有覆盖或外部发布时,先准备可审查方案及备份/恢复步骤,再取得该操作所需授权。等待期间不执行依赖该决定的操作;恢复后沿已固定目标和清单继续。
|
|
85
|
+
|
|
86
|
+
### 5. 执行升级与同步
|
|
87
|
+
|
|
88
|
+
必要选择和安装阻塞解除后,按既有包管理方式更新所有已用框架包的精确版本,统一修改相关 package.json/catalogs/overrides。保留应用 workspace 协议及无关依赖;必要 peer 更新须来自目标契约,禁止无差别升级全部依赖。
|
|
89
|
+
|
|
90
|
+
1. 按差异清单迁移调用方、类型、配置、环境变量说明、初始化和构建入口,保留应用行为与架构。新默认行为改变须显式核对;只对生命周期模块遵循 init → use → close,不给 core/serv/纯函数套用生命周期。
|
|
91
|
+
2. 用目标版本回归核验已有补丁/本地覆盖:仍必要则针对目标重建并说明依据;只有上游已修复且回归通过时移除。npm 升级遇到本地联调映射时,明确恢复 npm 或继续本地验证的选择,不能只改版本号却继续运行旧源码。
|
|
92
|
+
3. 使用当前包管理器安装并更新 lockfile,保留失败诊断;不手改 lockfile 的解析字段。安装后从**各消费 workspace**核对真实版本、公开 exports/类型及框架传递依赖,检查残留旧版/重复解析和本地路径。
|
|
93
|
+
4. 按 [同步规则](sync.md) 合并目标 CLI 中适配本架构的完整 skill 目录及 AI 入口。对“旧发布模板、应用现有文件、新发布模板”比较,保留仍适用的私有规则/自定义技能;已明确的业务需求优先于模板默认值,仅未决冲突转为选择。没有旧模板时先辨识私有内容,不直接覆盖。同步版本必须与目标运行时一致。
|
|
94
|
+
5. 同步受影响的 README、配置样例、skill 与测试,逐项更新差异清单状态。即使已处于目标版本,也核验解析/配置/skills 漂移;一致时报告无需升级,不制造改动。
|
|
95
|
+
|
|
96
|
+
### 6. 验证与交付
|
|
97
|
+
|
|
98
|
+
按应用实际 scripts 和 [分轮验证与集中修复](../hai-app-tests/validation.md) 先收集一轮适用门禁,汇总根因后集中修复、再验证;优先受影响 workspace,跨包契约验证所有消费者。按 [hai-app-tests](../hai-app-tests/SKILL.md) 选择集成/E2E,覆盖启动/关闭、变更 API、认证、持久化等实际路径;CI/发布按 [hai-ci](../hai-ci/SKILL.md) 保留失败阻断。
|
|
99
|
+
|
|
100
|
+
- 依赖升级后另核对 lockfile 与安装版本、公开入口、配置加载和关键业务流程;build 通过不能替代 typecheck 或运行验收。
|
|
101
|
+
- 检查同步后的全部相邻资源、相对引用和各工具入口;目标存在 `check:skills` 时运行,不假定应用具有框架仓库私有脚本。
|
|
102
|
+
- 修复本次引入的失败,区分升级前已有失败。必要验收缺服务/凭证/平台时提示阻塞;额外平台或未涉及的真实 Provider 验证明确标为未执行及原因,不能用 mock/Web 结果冒充真实/原生验证。
|
|
103
|
+
- 最终报告当前 → 目标及来源、差异处理结果、用户选择、变更文件与同步入口、实际门禁和未验证边界、恢复方法。依赖与必要迁移完成、选择/阻塞已解除且必要验证通过才称“升级完成”;否则报告当前进度与下一步,用户处理后继续完成。
|
|
104
|
+
|
|
105
|
+
指定精确版本后先 hai upgrade <version>,一次核对实际消费包及 CLI/deploy 发布完整性、制品/skills、catalog/lock/安装漂移和业务定制。此命令只读,缺包不得先改工程;报告完整后再按本 skill 执行获授权的升级,合并定制不覆盖。数据库迁移单独停旧写入、备份、migrateIam/migrateReach/migrateScheduler 预检;无凭据代次的旧会话重新登录。
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# 通用规范同步与本地联调
|
|
2
|
+
|
|
3
|
+
从 [hai-framework-sync](SKILL.md) 进入。仅同步 skills/AI 入口、修改通用模板或联调两个仓库时读取本文件;应用版本升级先执行入口中的版本发现与差异流程。
|
|
4
|
+
|
|
5
|
+
## 来源与边界
|
|
6
|
+
|
|
7
|
+
hai-framework 是通用能力和 skill 模板的源头;应用仓库消费这些能力,并保留项目私有规则。
|
|
8
|
+
|
|
9
|
+
| 任务 | 来源与修改范围 |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| 框架仓库开发规范与 skills | 框架根 `AGENTS.md`、`.agents/instructions/`、`.agents/skills/`;仓库私有路径不复制到应用模板 |
|
|
12
|
+
| 应用消费某发布版的 skills/AI 入口 | 对应精确版本 `@h-ai/cli` 的 `templates/skills/`;合并到当前授权应用,不要求修改框架仓库 |
|
|
13
|
+
| 修正可复用模块用法或工作流 | 在已授权框架仓库的 `packages/cli/templates/skills/` 修改源头,再同步受影响应用;核对相关仓库 skills 的公共契约 |
|
|
14
|
+
| 应用私有业务规则、产品决策与路径 | 留在应用 AGENTS 或本地 skill,不复制到通用模板 |
|
|
15
|
+
| 未发布模板/运行时联调 | 使用明确版本/提交的已授权本地框架来源,报告与 npm 发布版的差异 |
|
|
16
|
+
|
|
17
|
+
先确认目标应用的入口、实际目录、package.json/lockfile 和 npm/local 模式;有本地框架来源时再确认该仓库的入口与版本/提交。模板同步不证明新 API 已安装;示例必须符合目标依赖的公开 exports/types。通用内容不含敏感聊天记录、token 或私有地址。
|
|
18
|
+
|
|
19
|
+
## 同步完整技能与入口
|
|
20
|
+
|
|
21
|
+
通过 CLI 补齐缺失文件时,先按 [CLI 安装与命令](../hai-app-create/development.md#cli-安装与命令) 安装所需精确版本的 `@h-ai/cli` 并检查 `hai --version` / `hai --help`,再从应用根运行 `hai init`。临时使用 CLI 可隔离安装到临时目录;不为读取模板要求全局安装或改变系统级工具。
|
|
22
|
+
|
|
23
|
+
`hai init` 只补缺失内容,即使 `--force` 也不覆盖已有 AI 规则和 skills,不能用它代替旧版本规则合并。未发布模板修正从明确本地来源同步,不能假定已发布 CLI 已包含。
|
|
24
|
+
|
|
25
|
+
1. 比较来源与应用的同名完整目录,包括 SKILL、reference/guide、脚本和资产;升级时结合旧发布模板识别应用私有覆盖。模板业务默认值服从用户当前明确要求及其指定文档;移除或改写已被需求替代的旧模板强制规则,保留仍适用的项目私有决策,不将默认 admin/user、限额或流程重新强加给应用。无冲突部分合并,真实未决冲突列出位置、双方意图和可选方案;已有明确决策不重复询问。
|
|
26
|
+
2. 按目标架构选择需要的模块技能与桥接模板;不将 SvelteKit 指令套到 API/Vite 项目。保留自定义技能;上游重命名/删除的旧目录先检查调用与私有内容,不能整树覆盖或删除。
|
|
27
|
+
3. 项目规则合并到 AGENTS,`.github/copilot-instructions.md` 只引用共享入口;CLAUDE 如存在,通过 `@AGENTS.md` 复用共享规则,保留用户额外规则及现有 `.claude/`,不另复制技能正文。OpenCode 的 `instructions` 直接引用 `AGENTS.md`;配置有变化时合并已有字段,不整体替换。
|
|
28
|
+
4. 确保新增/修改/修复任务能到达 `hai-app-create` 与其 `development.md`,审查到达 `hai-app-review`,框架升级到达 `hai-framework-sync`。只引用目标实际交付的可选技能,不把目录缺失当成运行时能力缺失。
|
|
29
|
+
|
|
30
|
+
Codex 原生读取根 `AGENTS.md` 并发现 `.agents/skills/`,可用 `$hai-app-create` 等名称调用;不复制额外的 `.codex/skills`。同步后验证技能列表和按需参考文件可达;列表尚未刷新时重新打开项目或开始新会话。
|
|
31
|
+
|
|
32
|
+
## npm 与本地联调
|
|
33
|
+
|
|
34
|
+
默认 CI 验证 lockfile 中的已发布 npm 依赖,不依赖本机路径。先查应用实际 scripts;仅在存在时使用相应 `framework:*` 命令,否则遵循本项目 README,不凭空新增联调脚本:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm framework:status
|
|
38
|
+
pnpm framework:use:local <package>
|
|
39
|
+
pnpm framework:watch <package>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
PowerShell 使用 `pnpm.cmd`;占位包名替换后执行。本地来源先验证其版本/提交、构建产物与 exports,再开启联调;记录依赖映射/overrides 的恢复方式。联调结束按项目已有机制恢复 npm 并重装验证,不能把本地通过报告为发布版通过。
|
|
43
|
+
|
|
44
|
+
## 验证与交付
|
|
45
|
+
|
|
46
|
+
- 仅 skills/入口变更:检查 diff、完整目录、目标实际存在的入口及相邻资源、相对引用;排除框架仓库私有绝对路径/命令。
|
|
47
|
+
- 框架模板维护:运行已有 `check:skills` 和 CLI `test:scaffold-gates`,确认资源与路由在生成项目中可达。
|
|
48
|
+
- 同步应用依赖或运行时:按入口升级流程和 [分轮验证与集中修复](../hai-app-tests/validation.md) 收集适用门禁、集中修复并复测;CI/发布遵守 [hai-ci](../hai-ci/SKILL.md),不以模板已同步代替运行验收。
|
|
49
|
+
- 双仓改动时说明来源版本/提交、改动顺序、应用私有覆盖和双方验证;涉及 PR 时按 [hai-pr-review](../hai-pr-review/SKILL.md) 关联同步说明。仅授权一个仓库时记录另一方待同步,不擅自修改。
|
|
@@ -1,361 +1,89 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hai-iam
|
|
3
|
-
description: 使用 @h-ai/iam
|
|
3
|
+
description: "使用 @h-ai/iam 实现登录、注册、会话、OTP/LDAP/API Key 和 RBAC。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# hai-iam
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## 能力契约
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
| 项目 | 契约 |
|
|
11
|
+
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
12
|
+
| 能力 | 使用 @h-ai/iam 实现登录、注册、会话、OTP/LDAP/API Key 和 RBAC |
|
|
13
|
+
| 适用场景 | 应用身份认证、会话失效或角色权限管理 |
|
|
14
|
+
| 输入 | IamConfigInput、已初始化依赖、凭据、用户/角色/权限 ID |
|
|
15
|
+
| 输出 | 认证、会话与授权操作的 HaiResult |
|
|
16
|
+
| 限制 | 仅服务端,先初始化 reldb/cache(crypto 未初始化时由 IAM 初始化);公开认证入口是 iam.auth。客户端经 contract/API 调用,凭证只用于认证和安全存储,不进入日志或公开配置。 |
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
用户列表列头排序通过公开 IAM HTTP 查询的 sortBy(username/email/displayName/enabled/createdAt)与 sortDirection(asc/desc)提交,服务端在分页前排序;角色等关联列不伪装为当前页排序。
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
## 使用路径
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
- 密码登录接收 identifier/password,以及启用时的单用 captcha 证明;AuthPanel 将 LoginForm 的 username 映射为 identifier。会话期限来自服务端 session.maxAge/refreshTokenMaxAge,不增加未实现的登录偏好字段或持久会话选择框。
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
- `_iam.yml` 只存 IamConfigSettingsInput,运行时回调单独传给 iam.init;不把 reldb/cache 句柄混入配置。
|
|
25
|
+
- 角色资料与 permissionIds 一次保存:未传保持、空数组清空、未知 ID 失败;人数查询失败不能显示为 0。
|
|
26
|
+
- IAM 服务端是 iam.auth;typed HTTP client 的路径是 apiClient.iam.auth。
|
|
27
|
+
- OTP/API Key 等先核对 login 开关;不把未启用能力的 NOT_INITIALIZED 当认证失败。
|
|
28
|
+
- API Key 的配置、scope 交集示例表与创建→登录→操作授权→撤销代码见参考中的 API Key 小节。不要以 `checkPermission(userId)` 绕过请求 scope;ID/code/name 分别用于关联、守卫与展示。
|
|
29
|
+
- API Key scopes 与主体权限取交集,默认空数组无操作权限;受限 key 无角色授权,使用 permission 守卫。显式 * 仍受主体限制,派生会话读取/刷新检查 key,撤销/禁用/到期立即拒绝。
|
|
19
30
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| `@h-ai/cache` | 缓存(会话/OTP/重置令牌/权限缓存) | **必需** | 需在 `iam.init()` 前初始化 |
|
|
24
|
-
| `@h-ai/crypto` | 密码哈希 | 内部使用 | 自动初始化 |
|
|
25
|
-
| `@h-ai/audit` | 审计日志(RBAC 关键操作记录) | 内部使用 | 已初始化时自动写入 |
|
|
31
|
+
- 认证页面使用 await iam.getPublicConfig() + AuthPanel,先检查 success;同步 iam.publicConfig 仅为文件快照,协议用弹窗,表单通过 header/extraFields/footer 或 AuthPanel 的 login*/register* snippet 扩展;Kit 使用 kit.auth.createApi/publicPaths + kit.client.createAuthActions,HTTP 客户端使用 apiClient.createAuthActions。
|
|
32
|
+
- LDAP/Reach 均可选:基础认证无需安装;默认 LDAP 关闭,选用默认客户端才安装 ldapts 并设置 login.ldap + ldap。OTP 邮件/短信由 otp.email/sms 控制,选择 Reach 标准模板或自定义发送回调;具体签名与失败处理见参考中的“可选 LDAP 与通知”。
|
|
33
|
+
- 多节点共享 DB + Redis,Memory 只用于单进程。重置的策略失败计入 maxAttempts;OTP 消费不解除 resendInterval。管理员 createUser 不受自助注册开关限制。
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
- 受保护请求使用 `iam.auth.verifyToken`:会话校验读取共享代际缓存中的当前用户/凭据状态,校验激活状态、期限与 `credentialVersion`,再读取共享缓存中的当前角色/权限;缓存不可信时回源,必要读取失败即拒绝。`iam.session.get/verifyToken` 复用同一当前用户/凭据状态读取,但返回的角色/权限仍是会话快照,不能替代当前授权。serv 内置 IAM 注入默认使用当前授权入口,无需手动补查。
|
|
36
|
+
- 用户批量读取用 `iam.user.getUsers(ids, { include: ['roles'] })`(最多 1000,去重保留输入顺序,缺失省略);角色筛选用 `listUsers({ roleCode })`,在分页前执行,避免 N+1 和分页后过滤。
|
|
28
37
|
|
|
29
|
-
- 用户注册与登录(密码/OTP/LDAP/API Key)
|
|
30
|
-
- Bearer Token 认证与管理(TokenPair: accessToken + refreshToken)
|
|
31
|
-
- Token 刷新(rotation 策略)与吊销
|
|
32
|
-
- RBAC 角色/权限的创建、分配与检查
|
|
33
|
-
- API Key 管理(创建、吊销、验证)
|
|
34
|
-
- 密码重置流程
|
|
35
|
-
- 与 kit 集成的认证守卫
|
|
36
|
-
- API 契约定义(`@h-ai/iam/api`)
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
`captcha.enabled` 默认关闭;开启后共享 Cache 保存自托管 ALTCHA 的签名秘密/用途/相对TTL,iam.auth.createCaptcha({operation}) 只返回 {id,challenge}。标准 AuthPanel/createAuthActions 自动求解并通过 captcha 字段提交;自定义表单用 altcha/lib 求解。login/register/sendOtp/passwordReset/renewPassword 严格用途绑定,验证后原子单用,失败也需新挑战;API Key 机器鉴别和管理员创建/邀请不额外加人机交互。sendOtp(identifier,{captcha})、requestPasswordReset(identifier,{captcha}) 第二参数不能在审计/HTTP包装层丢失。TTL默认120秒、cost5000、maxCounter100,可按设备设置;计算工作量不保证是真人。Cache 故障拒绝,重初始化不延期,证明不持久化在浏览器或进入日志。标准 Kit 须导出 POST /api/auth/captcha,Serv 已提供;公开配置只含 captcha.enabled。错误030/031/032/033分别需验证/无效已用过期/关闭/不可用。
|
|
39
40
|
|
|
40
|
-
##
|
|
41
|
-
|
|
42
|
-
### 1. 配置
|
|
43
|
-
|
|
44
|
-
```yaml
|
|
45
|
-
# config/_iam.yml
|
|
46
|
-
password:
|
|
47
|
-
minLength: ${HAI_IAM_PASSWORD_MIN_LENGTH:8}
|
|
48
|
-
requireUppercase: true
|
|
49
|
-
requireNumber: true
|
|
50
|
-
session:
|
|
51
|
-
maxAge: ${HAI_IAM_SESSION_MAX_AGE:86400}
|
|
52
|
-
refreshTokenMaxAge: ${HAI_IAM_REFRESH_TOKEN_MAX_AGE:604800} # 7 天
|
|
53
|
-
sliding: true
|
|
54
|
-
singleDevice: false
|
|
55
|
-
login:
|
|
56
|
-
password: true
|
|
57
|
-
otp: false
|
|
58
|
-
register:
|
|
59
|
-
enabled: true
|
|
60
|
-
security:
|
|
61
|
-
maxLoginAttempts: ${HAI_IAM_MAX_LOGIN_ATTEMPTS:5}
|
|
62
|
-
lockoutDuration: 900
|
|
63
|
-
rbac:
|
|
64
|
-
defaultRole: user
|
|
65
|
-
superAdminRole: super_admin
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### 2. 初始化
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
import { cache } from '@h-ai/cache'
|
|
72
|
-
import { reldb } from '@h-ai/reldb'
|
|
73
|
-
import { iam } from '@h-ai/iam'
|
|
74
|
-
|
|
75
|
-
// 必须先初始化 reldb 和 cache
|
|
76
|
-
await reldb.init(core.config.get('db'))
|
|
77
|
-
await cache.init(core.config.get('cache'))
|
|
78
|
-
|
|
79
|
-
// IAM 自动使用已初始化的 reldb 和 cache 单例
|
|
80
|
-
await iam.init({
|
|
81
|
-
...core.config.get('iam'),
|
|
82
|
-
seedDefaultData: true,
|
|
83
|
-
})
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
初始化时自动创建数据库表(5 张):`hai_iam_users`、`hai_iam_roles`、`hai_iam_permissions`、`hai_iam_role_permissions`、`hai_iam_user_roles`。
|
|
87
|
-
|
|
88
|
-
Token 和 OTP 存储在 cache 中(不落库)。refreshToken 使用独立的 cache key 存储。
|
|
41
|
+
## 按需参考
|
|
89
42
|
|
|
90
|
-
|
|
43
|
+
认证凭据错误统一为“用户名或密码不正确”;当前密码复用使用 `HaiIamError.PASSWORD_REUSE_NOT_ALLOWED`(034),复杂度不符仍为 008。UI 复用 `authErrorMessage`,隐藏未知原文并保留 traceId;本地确认不一致明确提示,不改写原始密码。首次改密失败不签发会话,已登录改密的凭据错误不作为会话过期处理。
|
|
91
44
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
### 认证 — `iam.auth`
|
|
95
|
-
|
|
96
|
-
| 方法 | 签名 | 说明 |
|
|
97
|
-
| ------------------ | ----------------------------------------------------------- | ---------------------------------- |
|
|
98
|
-
| `login` | `({ identifier, password }) => Promise<HaiResult<AuthResult>>` | 密码登录(用户名/邮箱/手机号) |
|
|
99
|
-
| `loginWithOtp` | `({ identifier, code }) => Promise<HaiResult<AuthResult>>` | OTP 验证码登录 |
|
|
100
|
-
| `loginWithLdap` | `({ username, password }) => Promise<HaiResult<AuthResult>>` | LDAP 登录 |
|
|
101
|
-
| `loginWithApiKey` | `({ key }) => Promise<HaiResult<AuthResult>>` | API Key 登录 |
|
|
102
|
-
| `sendOtp` | `(identifier) => Promise<HaiResult<{ expiresAt }>>` | 发送 OTP 验证码 |
|
|
103
|
-
| `verifyToken` | `(token) => Promise<HaiResult<Session>>` | 验证令牌(推荐入口,委托 session) |
|
|
104
|
-
| `logout` | `(token) => Promise<HaiResult<void>>` | 登出 |
|
|
105
|
-
| `registerAndLogin` | `(options: RegisterOptions) => Promise<HaiResult<AuthResult>>` | 注册并登录(一站式) |
|
|
106
|
-
|
|
107
|
-
**AuthResult**(已改造为 TokenPair):
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
interface AuthResult {
|
|
111
|
-
user: User
|
|
112
|
-
tokens: TokenPair
|
|
113
|
-
roles: string[]
|
|
114
|
-
permissions: string[]
|
|
115
|
-
agreements?: AgreementDisplay
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
interface TokenPair {
|
|
119
|
-
accessToken: string
|
|
120
|
-
refreshToken: string
|
|
121
|
-
expiresIn: number
|
|
122
|
-
tokenType: 'Bearer'
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### 会话管理 — `iam.session`
|
|
127
|
-
|
|
128
|
-
| 方法 | 签名 | 说明 |
|
|
129
|
-
| ------------------- | -------------------------------------------------------------------- | --------------------------------------- |
|
|
130
|
-
| `create` | `({ userId, username, roles, source? }) => Promise<HaiResult<Session>>` | 创建会话(返回含 TokenPair 的 session) |
|
|
131
|
-
| `get` | `(token) => Promise<HaiResult<Session \| null>>` | 获取会话(滑动续期自动延长) |
|
|
132
|
-
| `verifyToken` | `(token) => Promise<HaiResult<Session>>` | 验证令牌 |
|
|
133
|
-
| `update` | `(token, data) => Promise<HaiResult<void>>` | 更新会话字段(浅合并 data) |
|
|
134
|
-
| `delete` | `(token) => Promise<HaiResult<void>>` | 删除会话 |
|
|
135
|
-
| `deleteByUserId` | `(userId) => Promise<HaiResult<number>>` | 删除用户所有会话(返回删除数量) |
|
|
136
|
-
| `refresh` | `(refreshToken) => Promise<HaiResult<TokenPair>>` | 刷新 Token(rotation:旧 Token 失效) |
|
|
137
|
-
| `revokeRefresh` | `(refreshToken) => Promise<HaiResult<void>>` | 吊销 refreshToken |
|
|
138
|
-
| `patchUserSessions` | `(userId, updates: SessionFieldUpdates) => Promise<HaiResult<void>>` | 批量更新用户所有会话的 roles/permissions |
|
|
139
|
-
|
|
140
|
-
**Token 刷新(rotation 策略)**:
|
|
141
|
-
|
|
142
|
-
- `refresh()` 会删除旧的 accessToken + refreshToken
|
|
143
|
-
- 创建全新的 session,返回新的 TokenPair
|
|
144
|
-
- 旧 refreshToken 立即失效,防止重放攻击
|
|
145
|
-
|
|
146
|
-
### 用户管理 — `iam.user`
|
|
147
|
-
|
|
148
|
-
| 方法 | 签名 | 说明 |
|
|
149
|
-
| -------------------------- | ----------------------------------------------------------------------- | ------------------------------------ |
|
|
150
|
-
| `register` | `(input) => Promise<HaiResult<RegisterResult>>` | 用户注册 |
|
|
151
|
-
| `getUser` | `(id, options?) => Promise<HaiResult<User \| null>>` | 获取用户(可选 include: ['roles']) |
|
|
152
|
-
| `getCurrentUser` | `(token) => Promise<HaiResult<User>>` | 通过令牌获取当前用户 |
|
|
153
|
-
| `updateCurrentUser` | `(token, data: UpdateCurrentUserInput) => Promise<HaiResult<User>>` | 当前用户修改个人资料(白名单字段) |
|
|
154
|
-
| `listUsers` | `(options?: ListUsersOptions) => Promise<HaiResult<PaginatedResult<User>>>` | 用户列表(分页 + 搜索 + 过滤) |
|
|
155
|
-
| `updateUser` | `(id, data) => Promise<HaiResult<User>>` | 更新用户信息 |
|
|
156
|
-
| `deleteUser` | `(id) => Promise<HaiResult<void>>` | 删除用户(自动清除会话) |
|
|
157
|
-
| `changePassword` | `(id, old, new) => Promise<HaiResult<void>>` | 修改密码(自动清除会话) |
|
|
158
|
-
| `changeCurrentUserPassword`| `(token, old, new) => Promise<HaiResult<void>>` | 当前用户修改密码(通过令牌识别) |
|
|
159
|
-
| `requestPasswordReset` | `(email) => Promise<HaiResult<void>>` | 请求密码重置(防枚举) |
|
|
160
|
-
| `confirmPasswordReset` | `(token, newPassword) => Promise<HaiResult<void>>` | 确认密码重置(自动清除会话) |
|
|
161
|
-
| `adminResetPassword` | `(userId, newPassword) => Promise<HaiResult<void>>` | 管理员直接重置密码 |
|
|
162
|
-
| `validatePassword` | `(password) => HaiResult<void>` | 验证密码强度(**同步方法**) |
|
|
163
|
-
|
|
164
|
-
### RBAC 授权 — `iam.authz`
|
|
165
|
-
|
|
166
|
-
| 方法 | 签名 | 说明 |
|
|
167
|
-
| -------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------- |
|
|
168
|
-
| `checkPermission` | `(userId, permission) => Promise<HaiResult<boolean>>` | 检查权限(超管自动通过,支持通配符) |
|
|
169
|
-
| `getUserPermissions` | `(userId) => Promise<HaiResult<Permission[]>>` | 获取用户权限列表(通过角色聚合去重) |
|
|
170
|
-
| `getUserRoles` | `(userId) => Promise<HaiResult<Role[]>>` | 获取用户角色列表 |
|
|
171
|
-
| `getUserRolesForMany` | `(userIds) => Promise<HaiResult<Map<string, Role[]>>>` | 批量获取多用户角色(避免 N+1) |
|
|
172
|
-
| `assignRole` | `(userId, roleId, tx?) => Promise<HaiResult<void>>` | 分配角色给用户 |
|
|
173
|
-
| `removeRole` | `(userId, roleId, tx?) => Promise<HaiResult<void>>` | 移除用户角色 |
|
|
174
|
-
| `syncRoles` | `(userId, roleIds, tx?) => Promise<HaiResult<void>>` | 同步用户角色(替换为目标列表) |
|
|
175
|
-
| `createRole` | `({ code, name, description? }, tx?) => Promise<HaiResult<Role>>` | 创建角色 |
|
|
176
|
-
| `getRole` | `(roleId) => Promise<HaiResult<Role \| null>>` | 获取角色 |
|
|
177
|
-
| `getRoleByCode` | `(code) => Promise<HaiResult<Role \| null>>` | 根据代码获取角色 |
|
|
178
|
-
| `getAllRoles` | `(options?) => Promise<HaiResult<PaginatedResult<Role>>>` | 获取所有角色(分页) |
|
|
179
|
-
| `updateRole` | `(roleId, data, tx?) => Promise<HaiResult<Role>>` | 更新角色 |
|
|
180
|
-
| `deleteRole` | `(roleId, tx?) => Promise<HaiResult<void>>` | 删除角色(级联清理关联 + 会话同步) |
|
|
181
|
-
| `createPermission` | `({ code, name, type?, resource?, action? }, tx?) => Promise<HaiResult<Permission>>`| 创建权限 |
|
|
182
|
-
| `getPermission` | `(permissionId) => Promise<HaiResult<Permission \| null>>` | 获取权限 |
|
|
183
|
-
| `getPermissionByCode` | `(code) => Promise<HaiResult<Permission \| null>>` | 根据代码获取权限 |
|
|
184
|
-
| `getAllPermissions` | `(options?: PermissionQueryOptions) => Promise<HaiResult<PaginatedResult<Permission>>>` | 获取所有权限(分页 + 类型/关键字筛选) |
|
|
185
|
-
| `deletePermission` | `(permissionId, tx?) => Promise<HaiResult<void>>` | 删除权限(级联清理关联 + 会话同步) |
|
|
186
|
-
| `assignPermissionToRole` | `(roleId, permId, tx?) => Promise<HaiResult<void>>` | 分配权限给角色 |
|
|
187
|
-
| `removePermissionFromRole` | `(roleId, permId, tx?) => Promise<HaiResult<void>>` | 移除角色权限 |
|
|
188
|
-
| `getRolePermissions` | `(roleId) => Promise<HaiResult<Permission[]>>` | 获取角色的权限列表 |
|
|
189
|
-
| `getRolePermissionsForMany`| `(roleIds) => Promise<HaiResult<Map<string, Permission[]>>>` | 批量获取多角色权限(避免 N+1) |
|
|
190
|
-
|
|
191
|
-
**通配符规则**:`admin:*` 匹配 `admin:read`、`admin:write` 等。超管角色自动拥有所有权限。
|
|
192
|
-
|
|
193
|
-
### API Key 管理 — `iam.apiKey`
|
|
194
|
-
|
|
195
|
-
| 方法 | 签名 | 说明 |
|
|
196
|
-
| -------------- | ----------------------------------------------------------------------- | -------------------------------------- |
|
|
197
|
-
| `createApiKey` | `(userId, options: CreateApiKeyOptions) => Promise<HaiResult<CreateApiKeyResult>>` | 创建 API Key(明文密钥仅返回一次) |
|
|
198
|
-
| `listApiKeys` | `(userId) => Promise<HaiResult<ApiKey[]>>` | 列出用户的所有 API Key |
|
|
199
|
-
| `getApiKey` | `(keyId) => Promise<HaiResult<ApiKey \| null>>` | 获取 API Key 详情 |
|
|
200
|
-
| `revokeApiKey` | `(keyId) => Promise<HaiResult<void>>` | 吊销/删除 API Key |
|
|
201
|
-
| `verifyApiKey` | `(rawKey) => Promise<HaiResult<ApiKey>>` | 验证 API Key 并返回实体(含用户 ID) |
|
|
202
|
-
|
|
203
|
-
> 需在 `login.apikey: true` 时才会初始化此子模块,否则访问返回 `NOT_INITIALIZED` 错误。
|
|
45
|
+
公开登录与 `renewPassword` 对不存在、无本地口令、休眠、注销、到期或锁定账号统一返回 `INVALID_CREDENTIALS`。受限账号不继续验证猜测的密码,正确与错误密码反馈相同且不改变原有失败计数;具体状态只供已认证管理入口查看。密码计算或存储故障保留基础设施错误,不累计密码失败。测试同时验证公开反馈、实际锁定和到期恢复,不能只把锁定断言改成统一错误码。
|
|
204
46
|
|
|
205
|
-
|
|
47
|
+
按任务读取 [reference.md](reference.md) 的对应小节;签名以当前源码或安装版本的公开类型为准,不默认加载全部资料。示例中的业务变量由应用提供。
|
|
206
48
|
|
|
207
|
-
|
|
49
|
+
- 运行环境
|
|
50
|
+
- 依赖
|
|
51
|
+
- 适用场景
|
|
52
|
+
- 使用步骤
|
|
53
|
+
- 可选 LDAP 与通知 — 安装、TLS/AD 配置、标准模板、自定义发送
|
|
54
|
+
- 核心 API
|
|
55
|
+
- HTTP API 契约
|
|
56
|
+
- 错误码 — `HaiIamError`
|
|
57
|
+
- 常见模式
|
|
58
|
+
- 相关 Skills
|
|
208
59
|
|
|
209
|
-
|
|
210
|
-
import { iamEndpoints } from '@h-ai/iam/api'
|
|
60
|
+
会话与 refresh 消费记录统一保存在 `hai:iam:sessions:{SHA256(userId)}` 版本化文档,不再使用独立 token 映射/索引。Bearer token 携带不可作为凭据的分区提示和 256 位随机值;客户端必须视为不透明字符串。`Session.version` 用于轮换提交校验。Memory 仅用于单进程测试,生产所有节点共享 Redis(含 Cluster)。并发冲突从最新文档重试,耗尽返回 CONFLICT;旧 refresh 不会产生第二个后继。若响应丢失后结果不明,调用方按失败关闭并重新登录,不假定旧凭据仍有效;全部会话仍受同一用户状态索引管理。
|
|
211
61
|
|
|
212
|
-
|
|
213
|
-
iamEndpoints.login // POST /api/v1/auth/login
|
|
214
|
-
iamEndpoints.loginWithOtp // POST /api/v1/auth/login-otp
|
|
215
|
-
iamEndpoints.sendOtp // POST /api/v1/auth/send-otp
|
|
216
|
-
iamEndpoints.logout // POST /api/v1/auth/logout
|
|
217
|
-
iamEndpoints.register // POST /api/v1/auth/register
|
|
218
|
-
iamEndpoints.currentUser // GET /api/v1/auth/me
|
|
219
|
-
iamEndpoints.refreshToken // POST /api/v1/auth/refresh
|
|
220
|
-
iamEndpoints.changePassword // POST /api/v1/auth/change-password
|
|
221
|
-
iamEndpoints.resetPassword // POST /api/v1/auth/reset-password
|
|
222
|
-
```
|
|
62
|
+
`iam.session.update(token, patch, expectedVersion)` 必须传入读取到的 Session.version。旧版本返回 CONFLICT,已撤销 token 返回 SESSION_NOT_FOUND;不会将旧内容重新写回或覆盖新会话。仅滑动时间戳更新不改变内容版本,允许正常并行请求。批量权限更新绑定首次读取的 token/版本集合,不将迟到数据应用到后续登录;遇到较新内容版本失败,调用方重新查询授权后再提交。
|
|
223
63
|
|
|
224
|
-
|
|
64
|
+
`create({ maxAge })` 可覆盖配置默认时长(正安全整数秒),该值持久化为 `Session.maxAge`;签发和刷新返回的 `expiresIn` 均使用它。滑动续期按该时长延长 access,返回已成功提交的 `lastActiveAt/expiresAt`;迟到请求只延长时间,不缩短较新续期。显式 `update` 的有效日期补丁完整生效并产生新内容版本。客户端根据本次返回的 `expiresIn` 安排刷新,不能硬编码配置默认值。
|
|
225
65
|
|
|
226
|
-
|
|
227
|
-
// 服务端
|
|
228
|
-
export const POST = kit.fromContract(iamEndpoints.login, async (input) => {
|
|
229
|
-
const result = await iam.auth.login(input)
|
|
230
|
-
return result.success ? kit.response.ok(result.data) : kit.response.unauthorized()
|
|
231
|
-
})
|
|
66
|
+
未启用额外期限时,access 与 refresh 独立到期:access 过期仍可凭有效 refresh 轮换,刷新不先要求旧 access 认证。`session.idleTimeout`、`absoluteTimeout` 以秒配置,0关闭;启用后 access 与 refresh 均检查,刷新保留首次登录时间。成功的 access 认证请求算活动;自动 refresh 仅换票,不延长闲置期限。后台业务轮询仍需按项目设计。`maxSessions: 0` 不限,否则在用户分区 CAS 原子限制有效会话数;`singleDevice: true` 默认顶旧保新,`singleDeviceMode: 'reject'` 保留旧会话并拒绝新登录。删除 access、logoutAll、单设备替换均撤销对应 refresh;`revokeRefresh` 保留仍有效的 access。
|
|
232
67
|
|
|
233
|
-
|
|
234
|
-
const result = await api.call(iamEndpoints.login, { username, password })
|
|
235
|
-
```
|
|
68
|
+
账号默认 `permanent/active`;管理端可配置 `temporary` 与 `accountExpiresAt`,或设 `accountStatus` 为 `dormant/closed`。状态/有效期变化推进持久凭据代际,重新激活不恢复旧会话。`accounts.dormantAfterDays: 0` 关闭自动休眠;启用后按 `scanIntervalSeconds` 扫描最后成功登录/创建时间,也可从可信后台调用 `iam.user.scanInactiveAccounts()`。公开注册不能接受管理字段;`closed` 保留记录,个人数据注销由项目处理。
|
|
236
69
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
## 错误码 — `HaiIamError`
|
|
240
|
-
|
|
241
|
-
| 错误码 | code | 说明 |
|
|
242
|
-
|--------|------|------|
|
|
243
|
-
| `HaiIamError.AUTH_FAILED` | `hai:iam:001` | 认证失败 |
|
|
244
|
-
| `HaiIamError.INVALID_CREDENTIALS` | `hai:iam:002` | 凭证无效 |
|
|
245
|
-
| `HaiIamError.USER_NOT_FOUND` | `hai:iam:003` | 用户不存在 |
|
|
246
|
-
| `HaiIamError.USER_DISABLED` | `hai:iam:004` | 用户已禁用 |
|
|
247
|
-
| `HaiIamError.USER_LOCKED` | `hai:iam:005` | 用户已锁定 |
|
|
248
|
-
| `HaiIamError.USER_ALREADY_EXISTS` | `hai:iam:006` | 用户已存在 |
|
|
249
|
-
| `HaiIamError.PASSWORD_EXPIRED` | `hai:iam:007` | 密码已过期 |
|
|
250
|
-
| `HaiIamError.PASSWORD_POLICY_VIOLATION` | `hai:iam:008` | 密码不符合策略 |
|
|
251
|
-
| `HaiIamError.OTP_INVALID` | `hai:iam:009` | 验证码无效 |
|
|
252
|
-
| `HaiIamError.NOT_INITIALIZED` | `hai:iam:010` | 未初始化 |
|
|
253
|
-
| `HaiIamError.OTP_RESEND_TOO_FAST` | `hai:iam:011` | 发送过于频繁 |
|
|
254
|
-
| `HaiIamError.LOGIN_DISABLED` | `hai:iam:012` | 登录方式已禁用 |
|
|
255
|
-
| `HaiIamError.REGISTER_DISABLED` | `hai:iam:013` | 注册已禁用 |
|
|
256
|
-
| `HaiIamError.STRATEGY_NOT_SUPPORTED` | `hai:iam:014` | 认证策略不支持 |
|
|
257
|
-
| `HaiIamError.APIKEY_INVALID` | `hai:iam:015` | API Key 无效 |
|
|
258
|
-
| `HaiIamError.APIKEY_EXPIRED` | `hai:iam:016` | API Key 已过期 |
|
|
259
|
-
| `HaiIamError.APIKEY_DISABLED` | `hai:iam:017` | API Key 已禁用 |
|
|
260
|
-
| `HaiIamError.APIKEY_NOT_FOUND` | `hai:iam:018` | API Key 不存在 |
|
|
261
|
-
| `HaiIamError.RESET_TOKEN_INVALID` | `hai:iam:019` | 重置令牌无效 |
|
|
262
|
-
| `HaiIamError.RESET_TOKEN_EXPIRED` | `hai:iam:020` | 重置令牌已过期 |
|
|
263
|
-
| `HaiIamError.RESET_TOKEN_MAX_ATTEMPTS` | `hai:iam:021` | 重置验证次数超限 |
|
|
264
|
-
| `HaiIamError.OTP_EXPIRED` | `hai:iam:022` | 验证码已过期 |
|
|
265
|
-
| `HaiIamError.SESSION_NOT_FOUND` | `hai:iam:101` | 会话不存在 |
|
|
266
|
-
| `HaiIamError.SESSION_EXPIRED` | `hai:iam:102` | 会话已过期 |
|
|
267
|
-
| `HaiIamError.SESSION_INVALID` | `hai:iam:103` | 会话无效 |
|
|
268
|
-
| `HaiIamError.SESSION_CREATE_FAILED` | `hai:iam:104` | 会话创建失败 |
|
|
269
|
-
| `HaiIamError.TOKEN_EXPIRED` | `hai:iam:105` | 令牌已过期 |
|
|
270
|
-
| `HaiIamError.TOKEN_INVALID` | `hai:iam:106` | 令牌无效 |
|
|
271
|
-
| `HaiIamError.TOKEN_REFRESH_FAILED` | `hai:iam:107` | 令牌刷新失败 |
|
|
272
|
-
| `HaiIamError.PERMISSION_DENIED` | `hai:iam:201` | 权限不足 |
|
|
273
|
-
| `HaiIamError.ROLE_NOT_FOUND` | `hai:iam:202` | 角色不存在 |
|
|
274
|
-
| `HaiIamError.PERMISSION_NOT_FOUND` | `hai:iam:203` | 权限不存在 |
|
|
275
|
-
| `HaiIamError.ROLE_ALREADY_EXISTS` | `hai:iam:204` | 角色已存在 |
|
|
276
|
-
| `HaiIamError.PERMISSION_ALREADY_EXISTS` | `hai:iam:205` | 权限已存在 |
|
|
277
|
-
| `HaiIamError.LDAP_CONNECTION_FAILED` | `hai:iam:301` | LDAP 连接失败 |
|
|
278
|
-
| `HaiIamError.LDAP_BIND_FAILED` | `hai:iam:302` | LDAP 绑定失败 |
|
|
279
|
-
| `HaiIamError.LDAP_SEARCH_FAILED` | `hai:iam:303` | LDAP 搜索失败 |
|
|
280
|
-
| `HaiIamError.REPOSITORY_ERROR` | `hai:iam:401` | 存储层操作错误 |
|
|
281
|
-
| `HaiIamError.NOT_FOUND` | `hai:iam:402` | 资源不存在 |
|
|
282
|
-
| `HaiIamError.CONFLICT` | `hai:iam:403` | 资源冲突 |
|
|
283
|
-
| `HaiIamError.FORBIDDEN` | `hai:iam:501` | 禁止访问 |
|
|
284
|
-
| `HaiIamError.INVALID_ARGUMENT` | `hai:iam:502` | 参数无效 |
|
|
285
|
-
| `HaiIamError.CONFIG_ERROR` | `hai:iam:901` | 配置错误 |
|
|
286
|
-
| `HaiIamError.INTERNAL_ERROR` | `hai:iam:999` | 内部错误 |
|
|
287
|
-
|
|
288
|
-
---
|
|
70
|
+
`password.minCharacterClasses` 支持任意 N 类字符;创建/改密/重置共用服务端强度校验。`expirationDays: 0` 关闭期限;`preventSamePassword` 可独立启用,期限或首次强改时也拒绝旧密码。`requireInitialChange` 只约束管理端初始/重置密码,关闭后不受历史标记约束。首次/过期用户用 `iam.user.renewPassword({identifier,password,newPassword})` 完成原密码验证与换密后重新登录,不能先授予普通会话。AuthPanel 与标准 Kit/Serv 端点提供该流程。
|
|
289
71
|
|
|
290
|
-
|
|
72
|
+
`security.lockoutEnabled` 可关闭失败锁定;`failureWindow` 为首次失败起的固定窗口秒数(默认86400),并用 `maxLoginAttempts/lockoutDuration` 配置阈值/锁定时间。共享 DB 原子计次。`initialCredentials.enabled` 开启 `iam.user.inviteUser()`,只发送现有 passwordReset 短期单次设密邀请,随机初始秘密不外发;需要重置通知就绪。投递未知保留账号/已发布凭据并返回失败,先核对后恢复,不自动重发或删除账号。
|
|
291
73
|
|
|
292
|
-
|
|
74
|
+
`loginAccess.enabled` 配置 `allowIps/denyIps`(IP/CIDR,拒绝优先)、IANA `timezone` 和 `windows[{days,start,end}]`(周一1至周日7,HH:mm,含起不含止,跨午夜)。登录第二参 `AuthRequestContext` 必须来自可信宿主;不能使用任意转发头/JSON IP。地址规则启用但缺少可信地址时拒绝。`reauthentication.enabled/operations/ttlSeconds` 控制敏感操作证明;`reauthenticate` 验证原密码,`checkSensitiveOperation` 在原有权限/资源检查后原子消费短期单次票据,绑定用户/会话/操作。Serv 标准 IAM 写操作和 admin 守卫用 `x-hai-reauthentication`,Kit 业务用 `kit.guard.requireSensitive`;证明不提升权限且只短暂保存在内存。
|
|
293
75
|
|
|
294
|
-
```typescript
|
|
295
|
-
import { iam } from '$lib/server/init'
|
|
296
|
-
import { kit } from '@h-ai/kit'
|
|
297
76
|
|
|
298
|
-
|
|
299
|
-
validateSession: async (token) => {
|
|
300
|
-
const result = await iam.auth.verifyToken(token)
|
|
301
|
-
if (!result.success)
|
|
302
|
-
return null
|
|
303
|
-
const roles = await iam.authz.getUserRoles(result.data.userId)
|
|
304
|
-
return {
|
|
305
|
-
userId: result.data.userId,
|
|
306
|
-
roles: roles.success ? roles.data.map(r => r.code) : [],
|
|
307
|
-
permissions: [],
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
guards: [
|
|
311
|
-
{
|
|
312
|
-
guard: kit.guard.auth({ apiMode: true }),
|
|
313
|
-
paths: ['/api/*'],
|
|
314
|
-
exclude: ['/api/auth/*'],
|
|
315
|
-
},
|
|
316
|
-
],
|
|
317
|
-
})
|
|
77
|
+
OTP 发布/消费用单身份 CAS;密码重置最终 SQL 同时核验 resetVersion、credentialVersion、有效期、用户状态并改密/消费令牌。认证与刷新绑定数据库凭据代际;通知第三参数提供 expiresAt/idempotencyKey,接收端持久化幂等,异常是投递未知且不自动重发。
|
|
318
78
|
|
|
319
|
-
|
|
320
|
-
```
|
|
79
|
+
`iam.auth.logout(accessToken)` 直接按完整不透明令牌在用户分区执行一次 CAS,原子撤销 access 与关联 refresh;access 已到期也不能跳过撤销。非法/不存在的令牌幂等成功,缓存读取或提交故障返回失败,恢复后可用同一令牌重试。HTTP 登出只允许撤销所持令牌,不以 userId 定位他人会话,也不要求该 access 仍通过认证。调用方必须检查 `success`;本地 Cookie/安全存储清理不代表服务端撤销已经确认,失败应显示提示。
|
|
321
80
|
|
|
322
|
-
|
|
81
|
+
配置示例用 `IamConfigInput` 表达可省略默认值的输入;需要完整策略快照时用对应 Schema.parse 得到输出类型。应用仅从 `@h-ai/iam` 取公开函数/类型,不深导内部策略与仓储。源码内部示例明确标注上下文,文档示例类型检查不替代真实共享存储和通知集成验证。
|
|
323
82
|
|
|
324
|
-
|
|
325
|
-
import { iamEndpoints } from '@h-ai/iam/api'
|
|
83
|
+
默认 Reach 通知自动使用 sensitive/expiresAt/idempotencyKey,不保存凭据正文或进入延迟队列;自定义回调同样遵守有效期与幂等。RelDB 初始化后可 migrateIam({dryRun:true}),iam.init 执行支持版本的字段升级,保留用户/密码。升级前停旧写入并备份;无安全代次的旧会话需重新登录,不能降级凭据安全代次。
|
|
326
84
|
|
|
327
|
-
|
|
328
|
-
const login = await api.call(iamEndpoints.login, { username, password })
|
|
329
|
-
if (login.success) {
|
|
330
|
-
await api.auth.setTokens(login.data.tokens)
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// 获取当前用户
|
|
334
|
-
const me = await api.call(iamEndpoints.currentUser, {})
|
|
335
|
-
|
|
336
|
-
// Token 过期时,api-client 自动调用 refreshUrl 刷新
|
|
337
|
-
// 刷新失败时,清除 Token 并跳转登录页
|
|
338
|
-
|
|
339
|
-
// 登出
|
|
340
|
-
await api.call(iamEndpoints.logout, {})
|
|
341
|
-
await api.auth.clear()
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### 自动会话失效
|
|
345
|
-
|
|
346
|
-
以下操作自动清除受影响用户的所有活跃会话:
|
|
347
|
-
|
|
348
|
-
- `deleteUser` / `updateUser({ enabled: false })` / `changePassword` / `confirmPasswordReset`
|
|
349
|
-
- `assignRole` / `removeRole` / `deleteRole` 会同步更新活跃会话中的角色列表
|
|
350
|
-
|
|
351
|
-
---
|
|
85
|
+
- 可选再认证规则为文件 operations 与权限 sensitiveOperations 的并集,主开关仍是 reauthentication.enabled;可信管理端使用 authz.setPermissionSensitiveOperations,异步 iam.getPublicConfig 返回含数据库的有效公开策略,读取失败拒绝放行。session.terminalLimits 按 web/app/desktop/api 限制,非空时未列类型拒绝;全局 maxSessions/singleDevice 同时生效,终端分组不是硬件真实性证明。原地登录使用标准 expectedUserId 限定原用户,凭据/验证码/锁定规则照常执行。
|
|
352
86
|
|
|
353
|
-
|
|
87
|
+
- 自动审计由宿主初始化 audit 后启用;未选用时不采集。启用后的写入失败仍可观察,外部事务收到失败应回滚。
|
|
354
88
|
|
|
355
|
-
-
|
|
356
|
-
- `hai-kit`:SvelteKit 集成(Bearer Token + 契约处理)
|
|
357
|
-
- `hai-api-client`:客户端契约调用
|
|
358
|
-
- `hai-reldb`:底层数据存储
|
|
359
|
-
- `hai-cache`:Token 与权限缓存
|
|
360
|
-
- `hai-crypto`:密码哈希(内部依赖)
|
|
361
|
-
- `hai-ui`:IAM 场景组件(LoginForm/RegisterForm 等)
|
|
89
|
+
- 高频验签/鉴权/敏感操作和 Key 验证复用 IAM 共享缓存,不能另建长寿命进程授权缓存。IAM 写入口在变更前后推进共享代际,外部事务等完成后再回填;不确定提交/失效保留 dirty 并安全回源。账号与口令/Key期限逐次检查,不缓存长期放行结论。多节点同时升级并通过 IAM API 写安全数据;直接 SQL 修改需停写后整体失效缓存。
|