refactor(backend): better code quality, fix timeout issue, fix website eat port 3000, fix nginx wrong point, better docker compose file, moving some file and change some import, update package dependency etc.

This commit is contained in:
2026-07-06 21:44:30 +07:00 Unverified
parent 6a4f06f5aa
commit 05cf38d020
11 changed files with 238 additions and 198 deletions
+28 -52
View File
@@ -1,3 +1,4 @@
import { unstable_cache } from "next/cache";
import { getYoutubeSubscriberCount } from "./youtube";
import { getRobloxFollowerCount } from "./roblox";
import { getDiscordMemberCount } from "./discord";
@@ -5,17 +6,7 @@ import { getTiktokProfile, type TiktokProfile } from "./tiktok";
export type { TiktokProfile };
export interface FollowerCounts {
youtube: number | null;
roblox: number | null;
discord: number | null;
tiktok: number | null;
}
export interface FollowerInfo {
count: number;
label: string;
}
import { FollowerCounts } from "./utils";
const CACHE_KEY = "erika:follower_counts";
const CACHE_KEY_TIKTOK = "erika:tiktok_profile";
@@ -26,6 +17,28 @@ export interface FetchResult {
tiktokProfile: TiktokProfile;
}
const getFollowerCountsFromAPIs = unstable_cache(
async (): Promise<FetchResult> => {
const [youtube, roblox, discord, tiktokProfileResult] = await Promise.all([
getYoutubeSubscriberCount(),
getRobloxFollowerCount(),
getDiscordMemberCount(),
getTiktokProfile(),
]);
const counts: FollowerCounts = {
youtube,
roblox,
discord,
tiktok: tiktokProfileResult.followerCount,
};
return { counts, tiktokProfile: tiktokProfileResult };
},
['follower-counts-api'],
{ revalidate: 3600, tags: ['follower-counts-api'] }
);
export async function getFollowerCounts(): Promise<FetchResult> {
try {
const { getRedisClient } = await import("@/lib/redis");
@@ -44,55 +57,18 @@ export async function getFollowerCounts(): Promise<FetchResult> {
// Redis unavailable, fall through to fetch
}
const [youtube, roblox, discord, tiktokProfileResult] = await Promise.all([
getYoutubeSubscriberCount(),
getRobloxFollowerCount(),
getDiscordMemberCount(),
getTiktokProfile(),
]);
const counts: FollowerCounts = {
youtube,
roblox,
discord,
tiktok: tiktokProfileResult.followerCount,
};
const result = await getFollowerCountsFromAPIs();
try {
const { getRedisClient } = await import("@/lib/redis");
const redis = await getRedisClient();
await Promise.all([
redis.set(CACHE_KEY, JSON.stringify(counts), { ex: CACHE_TTL }),
redis.set(CACHE_KEY_TIKTOK, JSON.stringify(tiktokProfileResult), { ex: CACHE_TTL }),
redis.set(CACHE_KEY, JSON.stringify(result.counts), { ex: CACHE_TTL }),
redis.set(CACHE_KEY_TIKTOK, JSON.stringify(result.tiktokProfile), { ex: CACHE_TTL }),
]);
} catch {
// Redis unavailable, skip caching
}
return { counts, tiktokProfile: tiktokProfileResult };
return result;
}
const followerLabels: Record<keyof FollowerCounts, string> = {
youtube: "ผู้ติดตาม",
roblox: "เพื่อน",
discord: "สมาชิก",
tiktok: "ผู้ติดตาม",
};
export function getCountForLink(name: string, counts: FollowerCounts): FollowerInfo | null {
const key = name.toLowerCase();
for (const [platform, label] of Object.entries(followerLabels)) {
const count = counts[platform as keyof FollowerCounts];
if (key.includes(platform) && count !== null) {
return { count, label };
}
}
return null;
}
export function formatCount(n: number): string {
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
return n.toString();
}
+35
View File
@@ -0,0 +1,35 @@
export interface FollowerCounts {
youtube: number | null;
roblox: number | null;
discord: number | null;
tiktok: number | null;
}
export interface FollowerInfo {
count: number;
label: string;
}
export const followerLabels: Record<keyof FollowerCounts, string> = {
youtube: "ผู้ติดตาม",
roblox: "เพื่อน",
discord: "สมาชิก",
tiktok: "ผู้ติดตาม",
};
export function getCountForLink(name: string, counts: FollowerCounts): FollowerInfo | null {
const key = name.toLowerCase();
for (const [platform, label] of Object.entries(followerLabels)) {
const count = counts[platform as keyof FollowerCounts];
if (key.includes(platform) && count !== null) {
return { count, label };
}
}
return null;
}
export function formatCount(n: number): string {
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
return n.toString();
}