haixunMaster/lib/types/style-profile.ts

90 lines
2.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const STYLE_8D_KEYS = [
"d1Tone",
"d2Structure",
"d3Interaction",
"d4Topics",
"d5Rhythm",
"d6Visual",
"d7Conversion",
"d8Risk",
] as const;
export type Style8DKey = (typeof STYLE_8D_KEYS)[number];
export const STYLE_8D_LABELS: Record<Style8DKey, string> = {
d1Tone: "D1 語氣人格",
d2Structure: "D2 結構模板",
d3Interaction: "D3 互動方式",
d4Topics: "D4 主題分布",
d5Rhythm: "D5 發文節奏",
d6Visual: "D6 視覺語法",
d7Conversion: "D7 轉換方式",
d8Risk: "D8 風險紅線",
};
export interface StoredStyle8DProfile {
username: string;
analyzedAt: string;
postCount: number;
engagement: {
measuredPosts: number;
medianInteractions: number;
averageInteractions: number;
postsAboveThreshold: number;
threshold: number;
verdict: "strong" | "usable" | "unknown";
};
analysis: Record<Style8DKey, { summary: string; evidence: string[] }>;
personaDraft: string;
}
export function createEmptyStyle8DProfile(username = ""): StoredStyle8DProfile {
const emptyDimension = () => ({ summary: "", evidence: [] as string[] });
return {
username,
analyzedAt: "",
postCount: 0,
engagement: {
measuredPosts: 0,
medianInteractions: 0,
averageInteractions: 0,
postsAboveThreshold: 0,
threshold: 10,
verdict: "unknown",
},
analysis: {
d1Tone: emptyDimension(),
d2Structure: emptyDimension(),
d3Interaction: emptyDimension(),
d4Topics: emptyDimension(),
d5Rhythm: emptyDimension(),
d6Visual: emptyDimension(),
d7Conversion: emptyDimension(),
d8Risk: emptyDimension(),
},
personaDraft: "",
};
}
export function parseStyle8DProfile(raw?: string | null): StoredStyle8DProfile | null {
if (!raw?.trim()) return null;
try {
const value = JSON.parse(raw) as StoredStyle8DProfile;
if (!value?.analysis) return null;
return value;
} catch {
return null;
}
}
export function buildStyle8DPromptBlock(raw?: string | null): string | null {
const profile = parseStyle8DProfile(raw);
if (!profile) return null;
const dimensions = STYLE_8D_KEYS.map((key) => {
const summary = profile.analysis[key]?.summary?.trim();
return summary ? `${STYLE_8D_LABELS[key]}${summary}` : null;
}).filter(Boolean);
if (dimensions.length === 0) return null;
return `【8D 風格策略】\n產文與回覆都必須遵守\n${dimensions.join("\n")}`;
}