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
+145
View File
@@ -726,6 +726,69 @@ paths:
"204": { description: Skill disabled }
"403": { description: SUPER_ADMIN role and valid CSRF are required }
"404": { description: Skill was not found }
/v1/admin/content/hints/generation/settings:
get:
security:
- adminMtls: []
adminSession: []
summary: Return non-secret AI Hint generation settings
responses:
"200":
description: Current generation settings and secret availability flags
content:
application/json:
schema: { $ref: "#/components/schemas/HintFeedSettings" }
"403": { description: SUPER_ADMIN or SUPPORT role is required }
put:
security:
- adminMtls: []
adminSession: []
summary: Update non-secret AI Hint generation settings
parameters:
- $ref: "#/components/parameters/AdminCsrf"
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UpdateHintFeedSettingsRequest" }
responses:
"200":
description: Updated generation settings
content:
application/json:
schema: { $ref: "#/components/schemas/HintFeedSettings" }
"400": { description: Settings are invalid }
"403": { description: SUPER_ADMIN role and valid CSRF are required }
/v1/admin/content/hints/generation/status:
get:
security:
- adminMtls: []
adminSession: []
summary: Return AI Hint generation and scheduler status
responses:
"200":
description: Durable generation status and current pack versions
content:
application/json:
schema: { $ref: "#/components/schemas/HintFeedGenerationStatus" }
"403": { description: SUPER_ADMIN or SUPPORT role is required }
/v1/admin/content/hints/generation/regenerate:
post:
security:
- adminMtls: []
adminSession: []
summary: Generate and atomically publish both AI Hint locale packs
parameters:
- $ref: "#/components/parameters/AdminCsrf"
responses:
"200":
description: Both locale packs were generated and published
content:
application/json:
schema: { $ref: "#/components/schemas/HintFeedGenerationResponse" }
"403": { description: SUPER_ADMIN role and valid CSRF are required }
"409": { description: A generation is already in progress }
"502": { description: Generation failed and the previous packs remain published }
/v1/admin/content/hints/{locale}:
get:
security:
@@ -1186,6 +1249,8 @@ paths:
- CONTENT_SKILL_ENABLED
- CONTENT_SKILL_DISABLED
- CONTENT_HINT_PACK_PUBLISHED
- CONTENT_HINT_FEED_SETTINGS_UPDATED
- CONTENT_HINT_FEED_GENERATED
- name: result
in: query
schema: { type: string, enum: [success, rejected] }
@@ -1605,6 +1670,86 @@ components:
type: object
additionalProperties:
type: [string, "null"]
sources:
type: object
additionalProperties:
type: array
items: { type: string }
HintFeedSettings:
type: object
additionalProperties: false
required:
- enabled
- topHubApiKeyConfigured
- generationIntervalHours
- holidayCountriesZh
- holidayCountriesEn
- weatherCitiesZh
- weatherCitiesEn
- googleTrendsGeos
properties:
enabled: { type: boolean }
topHubApiKeyConfigured: { type: boolean }
generationIntervalHours: { type: integer, minimum: 1, maximum: 168 }
holidayCountriesZh: { type: string, minLength: 2, maxLength: 255 }
holidayCountriesEn: { type: string, minLength: 2, maxLength: 255 }
weatherCitiesZh: { type: string, minLength: 1, maxLength: 2000 }
weatherCitiesEn: { type: string, minLength: 1, maxLength: 2000 }
googleTrendsGeos: { type: string, minLength: 2, maxLength: 255 }
UpdateHintFeedSettingsRequest:
type: object
additionalProperties: false
required:
- generationIntervalHours
- holidayCountriesZh
- holidayCountriesEn
- weatherCitiesZh
- weatherCitiesEn
- googleTrendsGeos
properties:
generationIntervalHours: { type: integer, minimum: 1, maximum: 168 }
holidayCountriesZh: { type: string, minLength: 2, maxLength: 255 }
holidayCountriesEn: { type: string, minLength: 2, maxLength: 255 }
weatherCitiesZh: { type: string, minLength: 1, maxLength: 2000 }
weatherCitiesEn: { type: string, minLength: 1, maxLength: 2000 }
googleTrendsGeos: { type: string, minLength: 2, maxLength: 255 }
HintFeedGenerationStatus:
type: object
additionalProperties: false
required:
- enabled
- outcome
- intervalHours
- topHubApiKeyConfigured
properties:
enabled: { type: boolean }
outcome: { type: string, enum: [IDLE, RUNNING, SUCCEEDED, FAILED] }
intervalHours: { type: integer, minimum: 1, maximum: 168 }
lastStartedAt: { type: string, format: date-time }
lastCompletedAt: { type: string, format: date-time }
lastErrorCode: { type: string, maxLength: 64 }
nextScheduledAt: { type: string, format: date-time }
topHubApiKeyConfigured: { type: boolean }
zhVersion: { type: integer, minimum: 1 }
zhCardCount: { type: integer, minimum: 0, maximum: 40 }
enVersion: { type: integer, minimum: 1 }
enCardCount: { type: integer, minimum: 0, maximum: 40 }
HintFeedGenerationResponse:
type: object
additionalProperties: false
required: [generationId, generatedAt, zh, en]
properties:
generationId: { type: string, format: uuid }
generatedAt: { type: string, format: date-time }
zh: { $ref: "#/components/schemas/HintFeedPackGenerationResult" }
en: { $ref: "#/components/schemas/HintFeedPackGenerationResult" }
HintFeedPackGenerationResult:
type: object
additionalProperties: false
required: [version, cardCount]
properties:
version: { type: integer, minimum: 1 }
cardCount: { type: integer, minimum: 0, maximum: 40 }
AdminSessionState:
type: object
additionalProperties: false