Commit Graph

4 Commits

Author SHA1 Message Date
hailin e6f864d409 fix(version-service+gateway+app): fix APK download 404 and SHA-256 false failure
Three coordinated fixes to make in-app APK download work end-to-end:

1. version-service/main.ts: serve uploaded files as static assets via
   NestExpressApplication.useStaticAssets('/data/versions', prefix:
   '/downloads/versions'), so GET /downloads/versions/{platform}/{file}
   returns the actual APK stored in the Docker volume.

2. kong.yml: add /downloads/versions route to Kong so requests from
   the Flutter app can reach version-service through the API gateway.
   Previously only /api/v1/versions and /api/app/version were routed;
   the download URL returned by the check endpoint was unreachable (404).

3. download_manager.dart: skip SHA-256 verification when sha256Expected
   is empty string. The check endpoint always returns sha256:"" because
   version-service doesn't store file hashes. The previous code compared
   actual_hash == "" which always failed, causing the downloaded file to
   be deleted after a successful download.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 06:04:27 -08:00
hailin 141c6e984d feat(version-service): add GET /api/app/version/check endpoint for Flutter app
Flutter VersionChecker was calling GET /api/app/version/check but this
endpoint didn't exist — only the admin CRUD /api/v1/versions was there.

New: AppVersionCheckController (@Controller('api/app/version'))
  GET /api/app/version/check?platform=android&current_version_code=N
  - Finds latest enabled version for the platform (highest buildNumber)
  - Returns { needUpdate: false } when already up to date
  - Returns full VersionInfo payload when update is available

Response fields match Flutter VersionInfo.fromJson exactly:
  needUpdate, version, versionCode, downloadUrl, fileSize,
  fileSizeFriendly (computed), sha256 (empty — not stored),
  forceUpdate, updateLog, releaseDate

Also: AppVersionRepository.findLatestEnabled(platform) — queries all
enabled versions for platform, picks the one with the highest buildNumber
(parsed as int, robust against varchar storage).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 05:24:04 -08:00
hailin 260195db50 fix(version-service): use DatabaseModule.forRoot() for correct build path
The entrypoint.sh expects dist/services/${SERVICE_NAME}/src/main, but
nest build with inline TypeORM config produces dist/main directly.
Using DatabaseModule from @it0/database forces tsc to emit the nested
path structure (since it references shared packages), matching the
entrypoint path convention used by all other services.

Also gains SnakeNamingStrategy and autoLoadEntities from the shared module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:04:12 -08:00
hailin f6dffe02c5 feat: add version-service for IT0 App version management
New NestJS microservice (port 3009) providing complete version management
API for IT0 App, designed to integrate with the existing mobile-upgrade
frontend (update.szaiai.com).

Backend — packages/services/version-service/ (9 new files):
- AppVersion entity: platform (ANDROID/IOS), versionName, buildNumber,
  changelog, downloadUrl, fileSize, isForceUpdate, isEnabled, minOsVersion
- REST controller with 8 endpoints:
  GET/POST /api/v1/versions — list (with platform/disabled filters) & create
  GET/PUT/DELETE /api/v1/versions/:id — single CRUD
  PATCH /api/v1/versions/:id/toggle — enable/disable
  POST /api/v1/versions/upload — multipart APK/IPA upload (500MB limit)
  POST /api/v1/versions/parse — extract version info from APK/IPA
- File storage: /data/versions/{platform}/ via Docker volume
- APK/IPA parsing: app-info-parser package
- Database: public.app_versions table (non-tenant, platform-level)
- No JWT auth (internal version management, consistent with existing apps)

Infrastructure changes:
- Dockerfile.service: added version-service package.json COPY lines
- docker-compose.yml: version-service container (13009:3009), version_data
  volume, api-gateway depends_on
- kong.yml: version-service route (/api/v1/versions), CORS origin for
  update.szaiai.com (mobile-upgrade frontend domain)

Deployment note: nginx needs /downloads/versions/ location + client_max_body_size 500m

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 07:48:31 -08:00