diff --git a/.githooks/post-commit b/.githooks/post-commit
new file mode 100755
index 00000000..8d2eea5b
--- /dev/null
+++ b/.githooks/post-commit
@@ -0,0 +1,23 @@
+#!/bin/sh
+# Post-commit hook: 本地提交后自动执行 Web 预发布脚本。
+
+set -eu
+
+SCRIPT_PATH="scripts/release/pre_release_web.sh"
+
+if [ "${COZSWEET_SKIP_POST_COMMIT_PRE_RELEASE:-}" = "1" ]; then
+ echo "=== post-commit: skip pre-release hook (nested git operation) ==="
+ exit 0
+fi
+
+REPO_TOPLEVEL="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
+cd "$REPO_TOPLEVEL"
+
+if [ ! -f "$SCRIPT_PATH" ]; then
+ echo "=== post-commit: script not found: $SCRIPT_PATH ===" >&2
+ exit 1
+fi
+
+echo "=== post-commit: running $SCRIPT_PATH ==="
+export COZSWEET_SKIP_POST_COMMIT_PRE_RELEASE=1
+bash "$SCRIPT_PATH"
diff --git a/src/app/sidebar/sidebar-screen.tsx b/src/app/sidebar/sidebar-screen.tsx
index a8845b96..719cfef4 100644
--- a/src/app/sidebar/sidebar-screen.tsx
+++ b/src/app/sidebar/sidebar-screen.tsx
@@ -1,8 +1,10 @@
"use client";
import { signOut } from "next-auth/react";
+import { useRouter } from "next/navigation";
import { MobileShell, SettingsSection } from "@/app/_components/core";
+import { ROUTES } from "@/router/routes";
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { useUserDispatch, useUserState } from "@/stores/user/user-context";
@@ -29,6 +31,7 @@ const FALLBACK_USERNAME = "User name";
* 原始 Dart: lib/ui/sidebar/sidebar_screen.dart + profile_view.dart
*/
export function SidebarScreen() {
+ const router = useRouter();
const user = useUserState();
const userDispatch = useUserDispatch();
const auth = useAuthState();
@@ -59,7 +62,7 @@ export function SidebarScreen() {
- {/* 用户信息区:三种状态
+ {/* 用户信息区:三种状态 */}
router.push(ROUTES.subscription)}
/>
- */}
+
{sidebarState !== "guest" ? (
diff --git a/src/utils/facebook-graph.ts b/src/data/services/facebook-graph.ts
similarity index 85%
rename from src/utils/facebook-graph.ts
rename to src/data/services/facebook-graph.ts
index fd2bbd06..ee4bb06d 100644
--- a/src/utils/facebook-graph.ts
+++ b/src/data/services/facebook-graph.ts
@@ -6,22 +6,13 @@
* / email / picture),把 pictureUrl 写入 `UserStorage.setAvatarUrl()`、
* id 写入 `AuthStorage.setFacebookId()`。
*
- * 为什么不依赖后端返回的 avatarUrl?
- * - 后端可能未抓取 / 未存头像
- * - 头像有时效性(用户改 Facebook 头像),前端直接拉最新的
- * - Facebook ID 也独立存一份(与后端 userId 解耦,给 deep link 用)
- *
- * 不引入 Facebook SDK(window.FB)—— 减少前端 bundle 体积,Graph API
- * 单次 HTTP 调用即可拿到所有字段。SDK 加载慢、还要管 init。
- *
* 端点:`https://graph.facebook.com/me?fields=id,name,email,picture.type(large)&access_token=...`
* - `picture.type(large)` 返回 ~200px 头像 URL(默认 square 50px 太小)
* - 不指定 version 走最新稳定版
* - 不需要 appId / appSecret(accessToken 自身就是凭证)
*/
-import { FacebookUserData } from "@/data/dto/auth/facebook_user_data";
-import { Logger } from "./logger";
-import { Result, toError } from "./result";
+import { FacebookUserData } from "@/data/dto/auth";
+import { Logger, Result, toError } from "@/utils";
const log = new Logger("FacebookGraph");
diff --git a/src/data/services/index.ts b/src/data/services/index.ts
index 32e0f8a0..36f36e18 100644
--- a/src/data/services/index.ts
+++ b/src/data/services/index.ts
@@ -10,6 +10,7 @@ export * from "./api/http_client";
export * from "./api/metrics_api";
export * from "./api/response_helper";
export * from "./api/user_api";
+export * from "./facebook-graph";
export * from "../../core/net/config/api_config";
export * from "../../core/net/interceptor/auth_refresh_interceptor";
export * from "../../core/net/interceptor/logging_interceptor";
diff --git a/src/stores/auth/auth-actors.ts b/src/stores/auth/auth-actors.ts
index 9e6e179f..32c788d8 100644
--- a/src/stores/auth/auth-actors.ts
+++ b/src/stores/auth/auth-actors.ts
@@ -7,9 +7,10 @@ import { AuthPlatform, type AuthProvider } from "@/lib/auth/auth_platform";
import type { LoginStatus } from "@/data/dto/auth";
import { authRepository } from "@/data/repositories/auth_repository";
import type { IAuthRepository } from "@/data/repositories/interfaces";
+import { fetchFacebookUserData } from "@/data/services";
import { AuthStorage } from "@/data/storage/auth/auth_storage";
import { UserStorage } from "@/data/storage/user/user_storage";
-import { deviceIdentifier, fetchFacebookUserData, Logger, Result } from "@/utils";
+import { deviceIdentifier, Logger, Result } from "@/utils";
import { readGuestId } from "./auth-helpers";
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 42003f51..198ab859 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -6,7 +6,6 @@ export * from "./app-env";
export * from "./browser-detect";
export * from "./date";
export * from "./device_identifier";
-export * from "./facebook-graph";
export * from "./logger";
export * from "./platform-detect";
export * from "./pwa";