Migrate AI Hint feed generation

Bring dynamic hint generation into the account service while preserving the legacy key.osglab.com deployment for existing clients.
This commit is contained in:
Rocky
2026-08-21 15:17:15 +08:00
parent d0abe27623
commit 454ba8ddc5
40 changed files with 2838 additions and 10 deletions
@@ -3,6 +3,7 @@ package com.osglab.account.config
import com.osglab.account.features.storekit.domain.StoreKitProduct
import io.ktor.server.config.ApplicationConfig
import java.net.URI
import java.time.ZoneId
import java.util.Base64
import java.util.UUID
@@ -21,6 +22,7 @@ data class AppConfig(
val providers: ProvidersConfig,
val integrity: IntegrityConfig,
val admin: AdminConfig = AdminConfig(),
val hintFeed: HintFeedConfig = HintFeedConfig(),
) {
val isProduction: Boolean = environment == Environment.PRODUCTION
@@ -187,6 +189,18 @@ data class AppConfig(
100_000,
),
)
val hintFeed = HintFeedConfig(
enabled = config.booleanOrDefault("app.hintFeed.enabled", false),
topHubApiKey = config.optionalSecret(
"app.hintFeed.topHubApiKey",
production = false,
),
zoneId = config.valueOrDefault("app.hintFeed.zoneId", "UTC").let { raw ->
runCatching { ZoneId.of(raw) }.getOrElse { cause ->
throw ConfigValidationException("app.hintFeed.zoneId must be a valid time zone", cause)
}
},
)
require(session.hmacSecret.size >= MIN_HMAC_SECRET_BYTES) {
"app.session.secret must contain at least $MIN_HMAC_SECRET_BYTES bytes"
@@ -329,6 +343,7 @@ data class AppConfig(
providers = providers,
integrity = integrity,
admin = admin,
hintFeed = hintFeed,
)
}
}
@@ -371,6 +386,12 @@ data class AntiAbuseConfig(
val tombstoneRetentionDays: Long,
)
data class HintFeedConfig(
val enabled: Boolean = false,
val topHubApiKey: String? = null,
val zoneId: ZoneId = ZoneId.of("UTC"),
)
data class AppleConfig(
val teamId: String?,
val keyId: String?,