Chore/init startup#71
Conversation
There was a problem hiding this comment.
Pull request overview
This PR focuses on “startup/init” chores across the web client, admin frontend, backend file service, and deployment tooling—primarily improving type safety, stabilizing UI behavior, and simplifying Docker/Compose + GitHub Actions deployment/healthchecks.
Changes:
- Frontend/admin: tighten TypeScript types (API payloads/responses, component props), minor UI robustness tweaks, and cleanup of unused code.
- Backend: add Qiniu object key prefix support when generating uploaded file keys.
- Ops: update Dockerfiles/Compose and GitHub Actions to standardize
/api/healthhealthchecks and streamline staging deployment.
Reviewed changes
Copilot reviewed 41 out of 42 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
vocata-web/src/views/SearchRole.vue |
Avoid rendering RoleDialog without a selected role; remove unused Vue APIs/state. |
vocata-web/src/views/NewRole.vue |
Type the role-creation form payload and voice options; tighten upload success handler signature. |
vocata-web/src/views/LoginPage.vue |
Align registration field with nickname instead of username. |
vocata-web/src/views/components/RoleDialog.vue |
Strongly type the item prop and normalize tags to a safe string list. |
vocata-web/src/views/ChatPage.vue |
Improve typing for current conversation and adjust greeting/connection/VAD-related logic. |
vocata-web/src/utils/aiChat.ts |
Strengthen WebSocket message typing and AudioContext initialization; expose new voiceActive getter. |
vocata-web/src/types/common.ts |
Make roleInfo.id required; widen tags type; replace any metadata with unknown. |
vocata-web/src/types/api.ts |
Expand API type definitions (login user info, character create payloads, conversation/message typing). |
vocata-web/src/layouts/SliderBar.vue |
Safer route meta comparisons; improve edit input template-ref typing; remove unused delete helper. |
vocata-web/src/api/modules/role.ts |
Add stronger request/response typing for role endpoints and payloads. |
vocata-web/Dockerfile |
Improve layer caching, support build-time VITE_APP_URL, standardize Nginx on 8080 + /health. |
vocata-web/.dockerignore |
Add Docker ignore rules to reduce build context size and avoid env leakage. |
vocata-server/src/main/java/com/vocata/file/service/impl/FileServiceImpl.java |
Prepend configurable Qiniu key prefix to generated object keys. |
vocata-server/src/main/java/com/vocata/file/config/QiniuProperties.java |
Add keyPrefix property accessors. |
vocata-server/src/main/java/com/vocata/file/config/QiniuConfig.java |
Add keyPrefix field and accessors. |
vocata-server/Dockerfile.ci |
Adjust runtime image defaults, ports, and healthcheck path to /api/health. |
vocata-server/Dockerfile |
Add BuildKit syntax + Maven cache mounts; adjust runtime healthcheck to /api/health. |
vocata-server/.dockerignore |
Ensure target/*.jar can be included in Docker build context. |
vocata-admin/src/views/UserPage.vue |
Introduce typed user table rows and tighten error handling/types. |
vocata-admin/src/views/RolePage.vue |
Introduce typed role rows/form defaults and tighten error handling/types. |
vocata-admin/src/views/passport/LoginPage.vue |
Avoid depending on missing user in login response; remove unused route import. |
vocata-admin/src/types/api.ts |
Expand API typing (login user info, admin profile, pagination helpers). |
vocata-admin/src/router/routes.ts |
Simplify root route to redirect-only. |
vocata-admin/src/layouts/TabBar.vue |
Remove unused lifecycle import; widen emits; guard against empty admin profile response. |
vocata-admin/src/layouts/MenuCom.vue |
Fix recursive component tag naming and tighten route callback typing. |
vocata-admin/src/api/modules/user.ts |
Add typed query/response models and correct axios params usage. |
vocata-admin/src/api/modules/role.ts |
Tighten role list query typing. |
vocata-admin/Dockerfile |
Same Docker improvements as web; correct image labels for admin. |
vocata-admin/.dockerignore |
Add Docker ignore rules to reduce build context size and avoid env leakage. |
docs/GitHub-Staging-Secrets.md |
Document required staging secrets and deployment assumptions. |
docker-compose.yml |
Parameterize ports/credentials; switch Postgres image; add more backend env wiring; add tooling profiles. |
docker-compose.test.yml |
Add env vars (incl. Qiniu key prefix / AI provider config) and update healthcheck path. |
docker-compose.prod.yml |
Update web/admin internal ports and healthchecks; update backend healthcheck path. |
.gitignore |
Ignore **/.local/ (e.g., local deploy keys). |
.github/workflows/release.yml |
Update healthcheck URLs to /api/health. |
.github/workflows/emergency-rollback.yml |
Update healthcheck URLs to /api/health. |
.github/workflows/ci.yml |
Adjust change detection filters (no longer include workflow files). |
.github/workflows/cd-staging.yml |
Replace multi-build/push pipeline with remote git clone + docker compose up --build deploy. |
.github/workflows/cd-production.yml |
Update healthcheck URLs to /api/health. |
.env.example |
Add development defaults for Docker Compose and backend/frontend env values. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| get voiceActive(): boolean { | ||
| return this.audioManager.recording | ||
| } |
There was a problem hiding this comment.
voiceActive getter currently returns audioManager.recording, which is just “mic recording is on” and not “voice activity/VAD”. Since ChatPage treats this as VAD状态(“正在收音…” vs “准备开始说话”), UI will report voice activity whenever recording is enabled. Consider either exposing a real VAD/volume-based activity flag from AudioManager, or rename this getter (and the UI state) to reflect recording state.
| vadCheckInterval.value = window.setInterval(() => { | ||
| // 检查aiChat的audioManager是否有VAD状态 | ||
| if (aiChat.value && (aiChat.value as any).audioManager) { | ||
| const audioManager = (aiChat.value as any).audioManager | ||
| vadActive.value = audioManager.voiceActive || false | ||
| } | ||
| vadActive.value = aiChat.value?.voiceActive ?? false | ||
| }, 100) // 每100ms检查一次VAD状态 |
There was a problem hiding this comment.
startVADMonitoring sets vadActive from aiChat.voiceActive, but voiceActive is currently implemented as “recording state” (see VocaTaAIChat.voiceActive). This makes the VAD indicator effectively mirror “is recording” rather than actual voice activity. Either compute a real VAD/volume threshold here, or rename vadActive/UI copy to match recording state to avoid misleading behavior.
| filters: | | ||
| server: | ||
| - 'vocata-server/**' | ||
| - 'pom.xml' | ||
| - '.github/workflows/**' | ||
| web: | ||
| - 'vocata-web/**' | ||
| - '.github/workflows/**' | ||
| admin: | ||
| - 'vocata-admin/**' |
There was a problem hiding this comment.
The paths-filter no longer includes .github/workflows/**, so PRs that only modify workflow files will set all *-changed outputs to false and skip all CI jobs. If workflow changes should still run CI (common to prevent unreviewed CI drift), re-add .github/workflows/** to the relevant filters or add a separate always-run job for workflow-only changes.
| 当前 staging 目标机: | ||
|
|
||
| - `STAGING_HOST=86.53.161.33` | ||
| - `STAGING_USER=deploy` | ||
| - SSH 端口固定为 `22`(当前 workflow 已写死) |
There was a problem hiding this comment.
This document hardcodes the staging server public IP (STAGING_HOST=86.53.161.33) and references a local filesystem path to the private key location. If this repo is public (or shared broadly), these details increase the attack surface and can confuse other contributors. Consider replacing concrete values with placeholders (e.g., STAGING_HOST=<staging_host>) and moving machine-specific paths to a private/internal doc.
| const searchInput = ref() | ||
| const userMenu = useTemplateRef('userMenu') | ||
| const editInput = useTemplateRef('editInput') | ||
| const editInput = useTemplateRef<InstanceType<typeof ElInput>[]>('editInput') |
There was a problem hiding this comment.
useTemplateRef<InstanceType<typeof ElInput>[]> forces a runtime import of ElInput just for typing. Element Plus exposes an InputInstance type; using that (with import type) keeps this purely type-level and avoids coupling typing to component values.
| else | ||
| cd "$REPO_DIR" | ||
| git remote set-url origin "$REPO_URL" | ||
| git fetch --depth 1 origin "$GIT_REF" | ||
| git checkout "$GIT_REF" | ||
| git reset --hard "origin/$GIT_REF" |
There was a problem hiding this comment.
The remote deploy script checks out and hard-resets to origin/$GIT_REF (branch tip), but the workflow is triggered for a specific GIT_SHA. If the branch advances between trigger time and SSH execution, staging may deploy a different commit than the one recorded in the workflow summary. Consider fetching and checking out $GIT_SHA explicitly (detached HEAD) after clone/fetch to make deployments reproducible.
| else | |
| cd "$REPO_DIR" | |
| git remote set-url origin "$REPO_URL" | |
| git fetch --depth 1 origin "$GIT_REF" | |
| git checkout "$GIT_REF" | |
| git reset --hard "origin/$GIT_REF" | |
| cd "$REPO_DIR" | |
| # Ensure the exact commit that triggered the workflow is available and checked out | |
| git fetch --depth 1 origin "$GIT_SHA" | |
| git checkout --detach "$GIT_SHA" | |
| else | |
| cd "$REPO_DIR" | |
| git remote set-url origin "$REPO_URL" | |
| # Fetch and check out the exact commit SHA for reproducible deployments | |
| git fetch --depth 1 origin "$GIT_SHA" | |
| git checkout --detach "$GIT_SHA" |
📌 变更内容
✅ 测试验证
PR 提交规范提醒: