chore(frontend): introduce prettier + eslint and prune unused code
Backend CI / Backend (push) Has been cancelled
Frontend CI / Frontend (push) Failing after 1m39s

- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports)
- Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier
- Add root scripts: format, format:check, lint, lint:fix
- Reformat 257 files across admin-web, ops-web, desktop-client, packages
- Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters
- Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex
- Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 20:39:09 +08:00
parent 21c7892ee4
commit 162abdc97c
258 changed files with 42261 additions and 37556 deletions
+96 -90
View File
@@ -1,14 +1,14 @@
import { defineStore } from "pinia";
import { computed, ref } from "vue";
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import type { LoginRequest, UserInfo } from "@geo/shared-types";
import type { LoginRequest, UserInfo } from '@geo/shared-types'
import {
authApi,
isAuthSessionExpiredError,
refreshStoredAuthSession,
shouldRefreshAccessToken,
} from "@/lib/api";
} from '@/lib/api'
import {
clearStoredSession,
readStoredSession,
@@ -16,175 +16,181 @@ import {
setStoredUser,
subscribeStoredSession,
type SessionSnapshot,
} from "@/lib/session";
} from '@/lib/session'
export const useAuthStore = defineStore("auth", () => {
const accessToken = ref<string | null>(null);
const refreshToken = ref<string | null>(null);
const accessTokenExpiresAt = ref<number | null>(null);
const user = ref<UserInfo | null>(null);
const initialized = ref(false);
let unsubscribe: (() => void) | null = null;
let refreshTimer: number | null = null;
let lifecycleRefreshRegistered = false;
export const useAuthStore = defineStore('auth', () => {
const accessToken = ref<string | null>(null)
const refreshToken = ref<string | null>(null)
const accessTokenExpiresAt = ref<number | null>(null)
const user = ref<UserInfo | null>(null)
const initialized = ref(false)
let unsubscribe: (() => void) | null = null
let refreshTimer: number | null = null
let lifecycleRefreshRegistered = false
function clearRefreshTimer(): void {
if (refreshTimer) {
window.clearTimeout(refreshTimer);
refreshTimer = null;
window.clearTimeout(refreshTimer)
refreshTimer = null
}
}
function scheduleRefresh(): void {
clearRefreshTimer();
if (!refreshToken.value || typeof window === "undefined") {
return;
clearRefreshTimer()
if (!refreshToken.value || typeof window === 'undefined') {
return
}
const nextRefreshAt = accessTokenExpiresAt.value
? accessTokenExpiresAt.value * 1000 - 2 * 60 * 1000
: Date.now() + 30 * 1000;
const delay = Math.max(30 * 1000, nextRefreshAt - Date.now());
: Date.now() + 30 * 1000
const delay = Math.max(30 * 1000, nextRefreshAt - Date.now())
refreshTimer = window.setTimeout(() => {
void refreshSession();
}, delay);
void refreshSession()
}, delay)
}
function sync(snapshot: SessionSnapshot = readStoredSession()): void {
accessToken.value = snapshot.accessToken;
refreshToken.value = snapshot.refreshToken;
accessTokenExpiresAt.value = snapshot.accessTokenExpiresAt;
user.value = snapshot.user;
scheduleRefresh();
accessToken.value = snapshot.accessToken
refreshToken.value = snapshot.refreshToken
accessTokenExpiresAt.value = snapshot.accessTokenExpiresAt
user.value = snapshot.user
scheduleRefresh()
}
async function refreshSession(): Promise<void> {
if (!refreshToken.value) {
return;
return
}
try {
await refreshStoredAuthSession(refreshToken.value);
await refreshStoredAuthSession(refreshToken.value)
} catch (error) {
if (isAuthSessionExpiredError(error)) {
clearStoredSession({ notifyAuthExpired: true });
return;
clearStoredSession({ notifyAuthExpired: true })
return
}
scheduleRefreshRetry();
scheduleRefreshRetry()
}
}
function scheduleRefreshRetry(): void {
clearRefreshTimer();
if (!refreshToken.value || typeof window === "undefined") {
return;
clearRefreshTimer()
if (!refreshToken.value || typeof window === 'undefined') {
return
}
refreshTimer = window.setTimeout(() => {
void refreshSession();
}, 60 * 1000);
void refreshSession()
}, 60 * 1000)
}
async function refreshSessionIfNeeded(minRemainingMs = 2 * 60 * 1000): Promise<void> {
if (!refreshToken.value) {
return;
return
}
if (!accessToken.value || shouldRefreshAccessToken(accessTokenExpiresAt.value, minRemainingMs)) {
await refreshSession();
if (
!accessToken.value ||
shouldRefreshAccessToken(accessTokenExpiresAt.value, minRemainingMs)
) {
await refreshSession()
}
}
function registerLifecycleRefresh(): void {
if (lifecycleRefreshRegistered || typeof window === "undefined") {
return;
if (lifecycleRefreshRegistered || typeof window === 'undefined') {
return
}
lifecycleRefreshRegistered = true;
window.addEventListener("focus", () => {
void refreshSessionIfNeeded();
});
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
void refreshSessionIfNeeded();
lifecycleRefreshRegistered = true
window.addEventListener('focus', () => {
void refreshSessionIfNeeded()
})
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
void refreshSessionIfNeeded()
}
});
})
}
async function bootstrap(): Promise<void> {
if (!unsubscribe) {
unsubscribe = subscribeStoredSession(sync);
unsubscribe = subscribeStoredSession(sync)
}
sync();
registerLifecycleRefresh();
sync()
registerLifecycleRefresh()
try {
if (refreshToken.value) {
await refreshSessionIfNeeded(Number.POSITIVE_INFINITY);
await refreshSessionIfNeeded(Number.POSITIVE_INFINITY)
}
if (accessToken.value) {
const currentUser = await authApi.me();
setStoredUser(currentUser);
const currentUser = await authApi.me()
setStoredUser(currentUser)
}
} catch (error) {
if (isAuthSessionExpiredError(error)) {
clearStoredSession({ notifyAuthExpired: true });
clearStoredSession({ notifyAuthExpired: true })
}
}
initialized.value = true;
initialized.value = true
}
let loginPromise: Promise<UserInfo> | null = null;
let loginPromise: Promise<UserInfo> | null = null
async function login(payload: LoginRequest): Promise<UserInfo> {
if (loginPromise) {
return loginPromise;
return loginPromise
}
const loginPayload = { ...payload };
loginPromise = authApi.login(loginPayload).then((response) => {
setStoredTokens({
accessToken: response.access_token,
refreshToken: response.refresh_token,
expiresAt: response.expires_at,
});
setStoredUser(response.user);
return response.user;
}).finally(() => {
loginPromise = null;
});
const loginPayload = { ...payload }
loginPromise = authApi
.login(loginPayload)
.then((response) => {
setStoredTokens({
accessToken: response.access_token,
refreshToken: response.refresh_token,
expiresAt: response.expires_at,
})
setStoredUser(response.user)
return response.user
})
.finally(() => {
loginPromise = null
})
return loginPromise;
return loginPromise
}
async function logout(): Promise<void> {
try {
if (accessToken.value) {
await authApi.logout();
await authApi.logout()
}
} finally {
clearStoredSession();
clearStoredSession()
}
}
const isAuthenticated = computed(() => Boolean(accessToken.value && user.value));
const membership = computed(() => user.value?.membership ?? null);
const isAuthenticated = computed(() => Boolean(accessToken.value && user.value))
const membership = computed(() => user.value?.membership ?? null)
const isMembershipBlocked = computed(() => {
const value = membership.value;
const value = membership.value
return Boolean(
value?.blocked ||
value?.blocked_reason === "user_disabled" ||
value?.status === "expired" ||
value?.blocked_reason === "trial_plan_expired" ||
value?.blocked_reason === "subscription_required" ||
value?.blocked_reason === "subscription_inactive",
);
});
const kolProfile = computed(() => user.value?.kol_profile ?? null);
const isActiveKol = computed(() => kolProfile.value?.status === "active");
value?.blocked_reason === 'user_disabled' ||
value?.status === 'expired' ||
value?.blocked_reason === 'trial_plan_expired' ||
value?.blocked_reason === 'subscription_required' ||
value?.blocked_reason === 'subscription_inactive',
)
})
const kolProfile = computed(() => user.value?.kol_profile ?? null)
const isActiveKol = computed(() => kolProfile.value?.status === 'active')
return {
accessToken,
@@ -200,5 +206,5 @@ export const useAuthStore = defineStore("auth", () => {
bootstrap,
login,
logout,
};
});
}
})
+2 -3
View File
@@ -1,4 +1,3 @@
import { createPinia } from "pinia";
export const pinia = createPinia();
import { createPinia } from 'pinia'
export const pinia = createPinia()