Logs container ID, all visible containers for each service, and inspect status
at each check interval. Will be removed after root cause is identified.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Docker applies -n N globally before label filter, so -n 1 with a service filter
returns empty if the most-recently-created container belongs to a different service.
Remove -n 1; docker ps without it sorts newest-first and the filter correctly
narrows to only the target service's containers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Jobs named xuqmgroup-<service> (e.g. xuqmgroup-update-service) now
automatically build only that service without requiring manual param
selection. Falls back to params.SERVICE for manual runs or all-in-one job.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Each service now has its own VERSION.<service> file (all at 1.0.0)
- Jenkinsfile bumps each service's version independently
- versions.json updated per-service (no cross-service overwrite)
- Summary log shows all service:version pairs on success
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove VERSION_STRATEGY/CUSTOM_VERSION/CHANGELOG/DEPLOY params
- Auto patch-bump from VERSION file (reset to 1.0.0 semver)
- Push :VERSION + :latest tags per service for one-click update
- Add demo-service to build choices
- Always deploy; merge-update versions.json (no web entry overwrite)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove @Valid/@NotBlank/@Size/@Email/@NotNull from all Java record DTOs
(incompatible with Jackson deserialization in Spring Boot 3.x)
- Add manual validation in controllers instead
- Add database reset with data preservation to reset container feature
(exports core config tables, drops all tables, Hibernate recreates on startup,
then restores preserved data)
- Update nginx timeout regex to cover all system endpoints
Affected services: tenant-service, license-service, im-service, push-service
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Package name matching is now entirely the SDK's responsibility.
- DeviceService: drop packageName param from register/verify, delete validatePackageName()
- LicensePublicController: remove matchesPackageName check in resolveAppKey(),
remove packageName from service calls, add GET /api/license/app-info for
SDK appKey-only flow to fetch configured package names for local comparison
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace compose-file-path-dependent `docker compose -f <path>` calls
with label-based `docker ps` queries so the ops log viewer works on
both public cloud and private deployments regardless of compose file
location.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enhance the universal cleanup in refreshStoreReviewStatus to also clear
stale nonCurrentRelease/preExisting marks when onlineVersionCode is blank
but currentSubmissionLive is false. This handles OPPO and other stores
that may not return a versionCode in their API response.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add AppService.ensureLicenseFile() that generates and persists a license
file when the app doesn't have one yet. Update AppController.downloadLicenseFile
to use it instead of throwing "License file not generated yet".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previous fix only cleared stale APPROVED+nonCurrentRelease states when
poll returned mappedState==APPROVED. If the store API returned UNDER_REVIEW
(for the newly-submitted version) while the DB still held a stale
APPROVED+nonCurrentRelease from the old online version, the stale state
was never cleared.
Add universal cleanup: before any mappedState branching, if onlineVersionCode
< submittedCode and the DB entry has nonCurrentRelease/preExisting flags,
immediately clear the store review state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add AppStoreService.clearStoreReview() to remove a store's review entry
from storeReviewStatus JSON (used for false-positive cleanup)
- refreshStoreReviewStatus: when existing state is APPROVED but polled
onlineVersionCode < submittedCode, clear the stale state instead of
leaving the misleading nonCurrentRelease flag in place
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Require @AuthenticationPrincipal tenantId in parseLicenseFile endpoint
and verify the decrypted appKey belongs to the current tenant before
returning license contents. Returns 403 "权限不足无法展示" for
cross-tenant license files.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add compareVersionCodes() helper to compare numeric versionCodes safely
- preflightStoreSubmission: block only when onlineVersionCode >= submittedCode;
allow submit when online < submitted (normal new release)
- refreshStoreReviewStatus: only write preExisting=true when online >= submitted
- pollStoreReviewStatus: same guard for UNDER_REVIEW/REJECTED → ONLINE transitions
- All per-store query methods (Huawei, Xiaomi, OPPO, VIVO, Honor): only set
nonCurrentRelease=true when onlineVersionCode > submittedCode
- Fix pre-existing compilation errors: replace findByAppKeyAndStoreType with
findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add composite unique constraint (app_key, device_id) on DeviceEntity
- Remove global unique constraint from device_id column
- Update DeviceRepository: findByAppKeyAndDeviceId returns Optional,
findByDeviceId returns List for multi-app lookups
- Update DeviceService.register/verify to scope lookups by appKey
so same physical device can register independently for each app
- Update LicenseInternalController.getDevice to return list
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- DeviceService.register(): update appKey when device switches to a different app
and adjust registered device counters for old/new appKey
- LicenseAdminController: fix updateAppLicense parameter count mismatch
- AppController: add POST /api/apps/license/parse endpoint for license file decryption
- SecurityCenterView: add License file parser UI with upload and paste support
- appApi: add parseLicenseFile() method
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>