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
@@ -73,6 +73,17 @@ import com.osglab.account.features.content.repositories.ContentRepository
import com.osglab.account.features.content.repositories.ExposedContentRepository
import com.osglab.account.features.content.routes.contentRoutes
import com.osglab.account.features.content.services.ContentService
import com.osglab.account.features.content.feed.ExposedHintFeedRepository
import com.osglab.account.features.content.feed.HintFeedRepository
import com.osglab.account.features.content.feed.HintFeedGenerationLock
import com.osglab.account.features.content.feed.HintFeedScheduler
import com.osglab.account.features.content.feed.HintFeedService
import com.osglab.account.features.content.feed.MysqlHintFeedGenerationLock
import com.osglab.account.features.content.feed.sources.BaselineHintSource
import com.osglab.account.features.content.feed.sources.GoogleFeedHintSource
import com.osglab.account.features.content.feed.sources.HolidayHintSource
import com.osglab.account.features.content.feed.sources.TopHubHintSource
import com.osglab.account.features.content.feed.sources.WeatherHintSource
import com.osglab.account.features.gateway.adapters.CreditReservationAdapter
import com.osglab.account.features.gateway.adapters.SessionIdentityAdapter
import com.osglab.account.features.gateway.GatewaySettings
@@ -267,6 +278,12 @@ fun Application.module() {
null
}
if (appConfig.hintFeed.enabled) {
launch {
koin.get<HintFeedScheduler>().run()
}
}
launch {
while (isActive) {
try {
@@ -349,6 +366,7 @@ fun Application.module() {
operatorService = koin.get(),
auditService = koin.get(),
contentService = koin.get(),
hintFeedService = koin.get(),
)
}
}
@@ -426,6 +444,25 @@ fun accountServerModule(config: AppConfig): Module = module {
single { AdminGrantService(get()) }
single<ContentRepository> { ExposedContentRepository(get()) }
single { ContentService(get()) }
single<HintFeedRepository> { ExposedHintFeedRepository(get()) }
single<HintFeedGenerationLock> { MysqlHintFeedGenerationLock(get()) }
single {
val client = get<HttpClient>()
HintFeedService(
repository = get(),
contentService = get(),
generationLock = get(),
sources = listOf(
BaselineHintSource(),
HolidayHintSource(client),
WeatherHintSource(client),
TopHubHintSource(client, config.hintFeed.topHubApiKey),
GoogleFeedHintSource(client),
),
config = config.hintFeed,
)
}
single { HintFeedScheduler(get()) }
single<AppleJwksProvider> {
RemoteAppleJwksProvider(get(), config.apple.jwksUrl)
}