Files
teaching-feedback-assistant/pages/profile/index.ts
shay7sev a875fe9f63 feat(observability): add structured application logging
Emit correlated JSON logs from the API and FunASR services, propagate request IDs to the client, and configure bounded opt-in Docker logging.

Document the host-wide Grafana/Loki query workflow and keep observability deployment ownership outside the application repository.
2026-07-22 13:52:40 +08:00

117 lines
3.1 KiB
TypeScript

import {
copyApiRequestId,
ensureAuthentication,
getApiBaseUrl,
getApiErrorMessage,
getApiRequestId,
getHealth,
setApiBaseUrl
} from '../../utils/api'
type InputEvent = { detail: { value: string } }
Page({
data: {
apiBaseUrl: getApiBaseUrl(),
connectionText: '尚未检测',
connectionTone: 'idle',
connectionRequestId: '',
testing: false,
authText: '尚未登录',
authTone: 'idle',
authUserId: '',
authRequestId: ''
},
onShow() {
this.getTabBar()?.setData({ selected: 3 })
this.setData({ apiBaseUrl: getApiBaseUrl() })
void this.checkConnection()
void this.checkAuthentication()
},
onUrlInput(event: InputEvent) {
this.setData({ apiBaseUrl: event.detail.value })
},
async saveAndCheck() {
try {
const apiBaseUrl = setApiBaseUrl(this.data.apiBaseUrl)
this.setData({ apiBaseUrl })
await this.checkConnection()
await this.checkAuthentication()
} catch (error) {
this.setData({
connectionText: getApiErrorMessage(error),
connectionTone: 'error',
connectionRequestId: getApiRequestId(error)
})
}
},
async checkConnection() {
this.setData({
testing: true,
connectionText: '正在检测服务...',
connectionTone: 'idle',
connectionRequestId: ''
})
try {
const health = await getHealth()
let connectionText = '服务、数据库和语音转录正常'
let connectionTone = 'success'
if (!health.databaseConfigured) {
connectionText = '服务正常,数据库尚未配置'
connectionTone = 'warning'
} else if (!health.speechConfigured) {
connectionText = '服务和数据库正常,语音转录尚未配置'
connectionTone = 'warning'
} else if (!health.speechAvailable) {
connectionText = '服务和数据库正常,本地语音模型尚未就绪'
connectionTone = 'warning'
} else if (!health.wechatAuthConfigured) {
connectionText = '服务正常,微信登录尚未配置'
connectionTone = 'warning'
}
this.setData({
connectionText,
connectionTone,
connectionRequestId: ''
})
} catch (error) {
this.setData({
connectionText: getApiErrorMessage(error),
connectionTone: 'error',
connectionRequestId: getApiRequestId(error)
})
} finally {
this.setData({ testing: false })
}
},
async checkAuthentication() {
this.setData({ authText: '正在登录...', authTone: 'idle', authUserId: '', authRequestId: '' })
try {
const session = await ensureAuthentication()
this.setData({
authText: '微信身份已登录',
authTone: 'success',
authUserId: session.userId,
authRequestId: ''
})
} catch (error) {
this.setData({
authText: getApiErrorMessage(error),
authTone: 'error',
authUserId: '',
authRequestId: getApiRequestId(error)
})
}
},
copyRequestId(event: WechatMiniprogram.TouchEvent) {
const { requestId } = event.currentTarget.dataset as { requestId: string }
copyApiRequestId(requestId)
}
})