fix(chat): fold natal reports and drop homepage topic cards
Homepage no longer waits on /api/onboarding for six starter questions. Natal answers show the spoken layer first; the Level 2 skeleton sits in a collapsed 完整分析 block. Wide tables scroll sideways on a phone. Form inputs are 16px so iOS does not zoom on focus.
This commit is contained in:
@@ -1353,7 +1353,7 @@ export async function POST(request: Request) {
|
||||
content: consultationUserTurnContent({
|
||||
currentTime: currentTimeContext(requestTime),
|
||||
name,
|
||||
instruction: "先用 3–6 句口语直接回答下面的问题,不要加标题;然后再按 skill Level 2 骨架写:原始结构、六步宫位、Yoga 表、时机、综合、文末技法审计表,最后才是现代生活。骨架不可省略。星盘事实只使用系统里已经注入的计算结果,不要复述内部字段、JSON 或再跑一遍咨询流程。",
|
||||
instruction: "先用 3–6 句口语直接回答下面的问题,不要加标题;形状为一句结论、2–3 条短要点(每条完整句子、不超过 30 字)、一句下一步,总量不超过 400 字;然后再按 skill Level 2 骨架写:原始结构、六步宫位、Yoga 表、时机、综合、文末技法审计表,最后才是现代生活。骨架不可省略。星盘事实只使用系统里已经注入的计算结果,不要复述内部字段、JSON 或再跑一遍咨询流程。",
|
||||
summaryText: historyWindow.summaryText,
|
||||
question: resolvedQuestion.modelQuestion,
|
||||
}),
|
||||
@@ -1377,7 +1377,7 @@ export async function POST(request: Request) {
|
||||
content: consultationUserTurnContent({
|
||||
currentTime: currentTimeContext(requestTime),
|
||||
name,
|
||||
instruction: "先用 3–6 句口语直接回答下面的问题,不要加标题;然后再按 skill Level 2 骨架写:原始结构、六步宫位、Yoga 表、时机、综合、文末技法审计表,最后才是现代生活。骨架不可省略。星盘事实只使用系统里已经注入的计算结果,不要复述内部字段、JSON 或再跑一遍咨询流程。",
|
||||
instruction: "先用 3–6 句口语直接回答下面的问题,不要加标题;形状为一句结论、2–3 条短要点(每条完整句子、不超过 30 字)、一句下一步,总量不超过 400 字;然后再按 skill Level 2 骨架写:原始结构、六步宫位、Yoga 表、时机、综合、文末技法审计表,最后才是现代生活。骨架不可省略。星盘事实只使用系统里已经注入的计算结果,不要复述内部字段、JSON 或再跑一遍咨询流程。",
|
||||
summaryText: historyWindow.summaryText,
|
||||
question: resolvedQuestion.modelQuestion,
|
||||
}),
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
import {
|
||||
createOnboardingPost,
|
||||
type OnboardingProfileRepository,
|
||||
} from "@/lib/onboarding-post";
|
||||
import { consultationDomainDefinition } from "@/lib/consultation-domain-registry";
|
||||
import { onboardingSuggestionThemes } from "@/lib/onboarding-payload";
|
||||
import { createAdminSupabaseClient } from "@/lib/supabase/admin";
|
||||
import { createServerSupabaseClient } from "@/lib/supabase/server";
|
||||
import { getOnboardingAgent } from "@/mastra";
|
||||
import { loadLanguageModelCatalog } from "@/lib/model-catalog";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
// Ten questions in one call take materially longer than the previous three.
|
||||
export const maxDuration = 60;
|
||||
|
||||
function createProfileRepository(
|
||||
admin: ReturnType<typeof createAdminSupabaseClient>,
|
||||
): OnboardingProfileRepository {
|
||||
return {
|
||||
async loadProfile(userId) {
|
||||
return admin
|
||||
.from("profiles")
|
||||
.select("id,name,birth_date,birth_time,reported_birth_time,active_birth_time,birth_time_source,birth_time_period,declared_window_start,declared_window_end,birth_time_clue,uncertainty_before_minutes,uncertainty_after_minutes,birth_time_status,country_code,province_code,city_code,district_code,latitude,longitude,timezone_offset,birth_place_label,birth_place_type,birth_place_provider,birth_place_provider_id,timezone_id,timezone_source,ayanamsa,onboarding_payload,onboarding_version,onboarding_generated_at")
|
||||
.eq("id", userId)
|
||||
.maybeSingle();
|
||||
},
|
||||
async claimProfile(command) {
|
||||
let claim = admin
|
||||
.from("profiles")
|
||||
.update({
|
||||
onboarding_version: command.pendingVersion,
|
||||
onboarding_generated_at: command.claimedAt,
|
||||
})
|
||||
.eq("id", command.userId);
|
||||
claim = command.expectedVersion === null
|
||||
? claim.is("onboarding_version", null)
|
||||
: claim.eq("onboarding_version", command.expectedVersion);
|
||||
claim = command.expectedGeneratedAt === null
|
||||
? claim.is("onboarding_generated_at", null)
|
||||
: claim.eq("onboarding_generated_at", command.expectedGeneratedAt);
|
||||
return claim.select("id").maybeSingle();
|
||||
},
|
||||
async completeProfile(command) {
|
||||
return admin
|
||||
.from("profiles")
|
||||
.update({
|
||||
onboarding_payload: command.payload,
|
||||
onboarding_version: command.readyVersion,
|
||||
onboarding_generated_at: command.generatedAt,
|
||||
})
|
||||
.eq("id", command.userId)
|
||||
.eq("onboarding_version", command.expectedPendingVersion)
|
||||
.select("id")
|
||||
.maybeSingle();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const POST = createOnboardingPost({
|
||||
openSession: async () => {
|
||||
const supabase = await createServerSupabaseClient();
|
||||
const admin = createAdminSupabaseClient();
|
||||
const { data: { user }, error } = await supabase.auth.getUser();
|
||||
return {
|
||||
userId: user?.id ?? null,
|
||||
authError: Boolean(error),
|
||||
repository: createProfileRepository(admin),
|
||||
};
|
||||
},
|
||||
generateText: async (name, signal) => {
|
||||
const preferredModelId = process.env.ONBOARDING_MODEL_ID?.trim() || "deepseek-v4-flash";
|
||||
const catalog = await loadLanguageModelCatalog();
|
||||
const model = catalog.models.find((entry) => entry.id === preferredModelId)
|
||||
?? catalog.models.find((entry) => entry.id === catalog.defaultModelId)
|
||||
?? null;
|
||||
if (!model) return null;
|
||||
const result = await getOnboardingAgent(model).generate([
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
name ? `用户称呼:${name.slice(0, 80)}` : "用户未填写称呼。",
|
||||
`需要的主题,按此顺序各写一个问题:${onboardingSuggestionThemes.join("、")}`,
|
||||
...onboardingSuggestionThemes.map((theme) => {
|
||||
const domain = consultationDomainDefinition(theme);
|
||||
return `- ${theme}(${domain.label}):${domain.claimBoundary}`;
|
||||
}),
|
||||
"只返回 suggestions 数组,不要欢迎语。",
|
||||
].join("\n"),
|
||||
},
|
||||
], { abortSignal: signal });
|
||||
return result.text;
|
||||
},
|
||||
now: () => new Date(),
|
||||
warn: (message, detail) => console.warn(message, detail),
|
||||
});
|
||||
Reference in New Issue
Block a user