diff --git a/apps/backend/src/services/session/session-proof-beijing-time.js b/apps/backend/src/services/session/session-proof-beijing-time.js
deleted file mode 100644
index 31213cfc..00000000
--- a/apps/backend/src/services/session/session-proof-beijing-time.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// @ts-nocheck
-
-import {
- BAIDU_BEIJING_TIME_URL,
- BEIJING_TIME_PROOF_CLIP,
- BEIJING_TIME_PROOF_VIEWPORT,
-} from './session-proof-constants.js'
-
-export async function captureBeijingTimeProof(browserContext, { screenshotPath }) {
- const proofPage = await browserContext.newPage()
-
- try {
- await proofPage.setViewportSize(BEIJING_TIME_PROOF_VIEWPORT)
- await proofPage.goto(BAIDU_BEIJING_TIME_URL, { waitUntil: 'domcontentloaded' })
- await proofPage.waitForTimeout(3_000)
- await proofPage.evaluate(() => {
- window.scrollTo(0, 0)
- })
- await proofPage.screenshot({
- path: screenshotPath,
- clip: BEIJING_TIME_PROOF_CLIP,
- })
-
- return {
- screenshotPath,
- pageUrl: BAIDU_BEIJING_TIME_URL,
- }
- } finally {
- await proofPage.close().catch(() => null)
- }
-}
diff --git a/apps/backend/src/services/session/session-proof-beijing-time.ts b/apps/backend/src/services/session/session-proof-beijing-time.ts
new file mode 100644
index 00000000..4805a51b
--- /dev/null
+++ b/apps/backend/src/services/session/session-proof-beijing-time.ts
@@ -0,0 +1,55 @@
+///
+
+import {
+ BAIDU_BEIJING_TIME_URL,
+ BEIJING_TIME_PROOF_CLIP,
+ BEIJING_TIME_PROOF_VIEWPORT,
+} from './session-proof-constants.js'
+
+type BrowserPageLike = {
+ setViewportSize: (viewport: { width: number; height: number }) => Promise
+ goto: (url: string, options?: { waitUntil?: string }) => Promise
+ waitForTimeout: (milliseconds: number) => Promise
+ evaluate: (callback: () => unknown) => Promise
+ screenshot: (options: {
+ path: string
+ clip: { x: number; y: number; width: number; height: number }
+ }) => Promise
+ close: () => Promise
+}
+
+type BrowserContextLike = {
+ newPage: () => Promise
+}
+
+export type BeijingTimeProof = {
+ screenshotPath: string
+ pageUrl: string
+}
+
+export async function captureBeijingTimeProof(
+ browserContext: BrowserContextLike,
+ { screenshotPath }: { screenshotPath: string },
+): Promise {
+ const proofPage = await browserContext.newPage()
+
+ try {
+ await proofPage.setViewportSize(BEIJING_TIME_PROOF_VIEWPORT)
+ await proofPage.goto(BAIDU_BEIJING_TIME_URL, { waitUntil: 'domcontentloaded' })
+ await proofPage.waitForTimeout(3_000)
+ await proofPage.evaluate(() => {
+ window.scrollTo(0, 0)
+ })
+ await proofPage.screenshot({
+ path: screenshotPath,
+ clip: BEIJING_TIME_PROOF_CLIP,
+ })
+
+ return {
+ screenshotPath,
+ pageUrl: BAIDU_BEIJING_TIME_URL,
+ }
+ } finally {
+ await proofPage.close().catch(() => null)
+ }
+}
diff --git a/apps/backend/src/services/session/session-proof-constants.js b/apps/backend/src/services/session/session-proof-constants.ts
similarity index 82%
rename from apps/backend/src/services/session/session-proof-constants.js
rename to apps/backend/src/services/session/session-proof-constants.ts
index ea2e2785..0b80f9f0 100644
--- a/apps/backend/src/services/session/session-proof-constants.js
+++ b/apps/backend/src/services/session/session-proof-constants.ts
@@ -1,4 +1,6 @@
export const BAIDU_BEIJING_TIME_URL = 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%8C%97%E4%BA%AC%E6%97%B6%E9%97%B4&fenlei=256&rsv_pq=0xa7d529b30000a6eb&rsv_t=2d404COdLspTa8jnKQl%2FyCU%2BSCmRyb%2BvSqxxjk%2B7E1scokLYTuDbehaQ0Dvq&rqlang=en&rsv_enter=1&rsv_dl=ih_0&rsv_sug3=1&rsv_sug1=1&rsv_sug7=001&rsv_sug2=1&rsv_btype=i&rsp=0&rsv_sug9=es_2_1&rsv_sug=1'
+export type RedeemProofMode = 'full' | 'basic' | 'off'
+
export const BEIJING_TIME_PROOF_VIEWPORT = { width: 1440, height: 860 }
export const BEIJING_TIME_PROOF_CLIP = {
x: 0,
@@ -6,4 +8,4 @@ export const BEIJING_TIME_PROOF_CLIP = {
width: BEIJING_TIME_PROOF_VIEWPORT.width,
height: 620,
}
-export const DEFAULT_REDEEM_PROOF_MODE = 'full'
+export const DEFAULT_REDEEM_PROOF_MODE: RedeemProofMode = 'full'
diff --git a/apps/backend/src/services/session/session-proof-mode.js b/apps/backend/src/services/session/session-proof-mode.ts
similarity index 53%
rename from apps/backend/src/services/session/session-proof-mode.js
rename to apps/backend/src/services/session/session-proof-mode.ts
index ffc12500..790ef3a6 100644
--- a/apps/backend/src/services/session/session-proof-mode.js
+++ b/apps/backend/src/services/session/session-proof-mode.ts
@@ -1,10 +1,18 @@
-// @ts-nocheck
-
import { runtimeConfig } from '../../config/runtime.js'
-import { DEFAULT_REDEEM_PROOF_MODE } from './session-proof-constants.js'
+import { DEFAULT_REDEEM_PROOF_MODE, type RedeemProofMode } from './session-proof-constants.js'
-export function resolveRedeemProofMode(rawMode = runtimeConfig.redeem.proofMode) {
+type RedeemResultForProof = {
+ classification?: {
+ success?: boolean
+ }
+ redeem?: {
+ iRet?: number | string
+ ret?: number | string
+ }
+} | null | undefined
+
+export function resolveRedeemProofMode(rawMode: unknown = runtimeConfig.redeem.proofMode): RedeemProofMode {
const normalized = String(rawMode || '')
.trim()
.toLowerCase()
@@ -16,7 +24,7 @@ export function resolveRedeemProofMode(rawMode = runtimeConfig.redeem.proofMode)
return DEFAULT_REDEEM_PROOF_MODE
}
-export function shouldCaptureBeijingTimeProof(finalResult) {
+export function shouldCaptureBeijingTimeProof(finalResult: RedeemResultForProof): boolean {
if (finalResult?.classification?.success === true) {
return true
}
diff --git a/apps/backend/src/services/session/session-proof-paths.js b/apps/backend/src/services/session/session-proof-paths.ts
similarity index 58%
rename from apps/backend/src/services/session/session-proof-paths.js
rename to apps/backend/src/services/session/session-proof-paths.ts
index 83876666..e8202379 100644
--- a/apps/backend/src/services/session/session-proof-paths.js
+++ b/apps/backend/src/services/session/session-proof-paths.ts
@@ -1,6 +1,14 @@
import path from 'node:path'
-export function buildArtifactPaths(outputDir) {
+export type RedeemArtifactPaths = {
+ redeemPageScreenshotPath: string
+ beijingTimeScreenshotPath: string
+ screenshotPath: string
+ htmlPath: string
+ resultPath: string
+}
+
+export function buildArtifactPaths(outputDir: string): RedeemArtifactPaths {
return {
redeemPageScreenshotPath: path.join(outputDir, 'redeem-page.png'),
beijingTimeScreenshotPath: path.join(outputDir, 'beijing-time.png'),
diff --git a/docs/backend-typescript-migration-plan.md b/docs/backend-typescript-migration-plan.md
index 88d109b2..af2a2f05 100644
--- a/docs/backend-typescript-migration-plan.md
+++ b/docs/backend-typescript-migration-plan.md
@@ -397,6 +397,17 @@
- `npm run typecheck`
- `npm run build`
- `npm test` 共 139 个用例通过
+74. 腾讯浏览器会话 proof 基础模块迁移到 `.ts`:
+ - `src/services/session/session-proof-constants.ts`
+ - `src/services/session/session-proof-paths.ts`
+ - `src/services/session/session-proof-mode.ts`
+ - `src/services/session/session-proof-beijing-time.ts`
+75. 兑换凭证模式、artifact 路径、北京时间截图浏览器上下文与截图返回值已显式类型化
+76. Docker 内验证通过:
+ - `src/services/session/session-proof.test.js` 共 4 个用例通过
+ - `npm run typecheck`
+ - `npm run build`
+ - `npm test` 共 139 个用例通过
## 下一步建议