feat: Add Vertex AI Chinese translation support#42
Conversation
Implement complete Chinese localization for KickWatch: **Database Schema:** - Add `name_zh`, `blurb_zh`, `creator_name_zh` to Campaign model - Add `name_zh` to Category model **Vertex AI Translation Service:** - New TranslatorService using Vertex AI Gemini 2.0 Flash - Batch translation (10 campaigns per API call) to optimize costs - Uses GCP startup credits from rescience-lab-465304 project - Automatic translation during nightly crawl and backfill **Category Localization:** - All 14 root categories with Chinese names - 12 subcategories with Chinese names **Configuration:** - Add VERTEX_AI_PROJECT_ID and VERTEX_AI_LOCATION env vars - Service account credentials via GOOGLE_SERVICE_ACCOUNT_JSON - AWS Secrets Manager integration ready **Infrastructure:** - GCP Project: rescience-lab-465304 - Service Account: kickwatch-translator@rescience-lab-465304.iam.gserviceaccount.com - AWS Secrets: kickwatch-dev/google-service-account, kickwatch-dev/vertex-ai-config **Technical Details:** - Translator gracefully degrades if not configured (no blocking) - Continues crawl even if translation fails - Temperature=0.3 for consistent translations - 500ms delay between batches to avoid rate limits Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update iOS app to display translated Chinese content: **CampaignDTO & CategoryDTO:** - Add `name_zh`, `blurb_zh`, `creator_name_zh` fields - Add computed properties `displayName`, `displayBlurb`, `displayCreatorName` - Automatically fallback to English if Chinese translation unavailable **Views Updated:** - CampaignRowView: Use displayName/displayCreatorName - CampaignDetailView: Use displayName/displayBlurb/displayCreatorName - DiscoverView: Use displayName for categories - WatchlistView: Updated DTO initialization **User Experience:** - Chinese content shows first when available - Seamless fallback to English - No code changes needed when backend adds translations Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add Vertex AI configuration to GitHub Actions workflow: - VERTEX_AI_PROJECT_ID=rescience-lab-465304 - VERTEX_AI_LOCATION=us-central1 - GOOGLE_SERVICE_ACCOUNT_JSON from AWS Secrets Manager This enables automatic Chinese translation during nightly crawls. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Jing-yilin
left a comment
There was a problem hiding this comment.
- P1 -
ios/KickWatch/Tests/MockAPIClient.swift:102
The new CampaignDTO initializer now requires name_zh, blurb_zh, and creator_name_zh, but the shared test factory was not updated. As a result the iOS test target does not compile anymore. Repro:
cd ios && xcodegen generate
xcodebuild test -project KickWatch.xcodeproj -scheme KickWatch -destination "platform=iOS Simulator,name=iPhone 17,OS=26.2" CODE_SIGNING_ALLOWED=NO DEVELOPMENT_TEAM=7Q28CBP3S5
That fails with missing arguments for parameters 'name_zh', 'blurb_zh', 'creator_name_zh' in call from MockAPIClient.swift.
- P1 -
ios/KickWatch/Sources/Services/APIClient.swift:41-61,backend/internal/model/model.go:13-26,57
The Chinese-first fallback currently uses nil-coalescing (name_zh ?? name, etc.), but the backend model fields are plain Go strings. For untranslated rows JSON will contain empty strings, not null, and Swift decodes "" into a non-nil String?. That means existing campaigns/categories without a translation will prefer the empty localized field over the English one, so names can render blank and creator rows can become by until every record is backfilled. The fallback needs to treat empty strings as missing.
- P2 -
backend/internal/service/cron.go:84-88
syncCategories() still only upserts name and parent_id. Because ListCategories() serves directly from the DB once any category rows exist, upgraded environments with already-seeded categories will never get name_zh populated, so the new localized category chips will not show up there.
Test results:
cd backend && go test ./...✅- iOS unit tests/build ❌ (compile failure above)
Fixes 3 issues identified in PR #42 code review: 1. MockAPIClient.swift: Add missing Chinese fields (name_zh, blurb_zh, creator_name_zh) to CampaignDTO test factory 2. APIClient.swift: Handle empty string fallback in computed properties. Backend emits empty strings for untranslated fields, so nil-coalescing alone is insufficient. Check for both nil AND empty string. 3. cron.go: Include name_zh in syncCategories() upsert columns so existing category rows get Chinese names on deployment Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Summary
Add complete Chinese localization for KickWatch using Vertex AI to automatically translate all Kickstarter campaign content.
Changes
Backend
name_zh,blurb_zh,creator_name_zhfields to Campaign modelname_zhfield to Category modelInfrastructure
rescience-lab-465304kickwatch-translator@rescience-lab-465304.iam.gserviceaccount.comkickwatch-dev/google-service-account(credentials)kickwatch-dev/vertex-ai-config(project config)Cost Control
Deployment Configuration
Add these environment variables to ECS task definition:
{ "name": "VERTEX_AI_PROJECT_ID", "value": "rescience-lab-465304" }, { "name": "VERTEX_AI_LOCATION", "value": "us-central1" }, { "name": "GOOGLE_SERVICE_ACCOUNT_JSON", "valueFrom": "arn:aws:secretsmanager:us-east-2:739654145647:secret:kickwatch-dev/google-service-account" }TODO
Testing Plan
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com