feat: P1 合盘/星座/问答与测测完整设计包及模拟器取证工具

落地 synastry/star/ask API 与 H5 页面,补齐 cece-frontend-re complete-design 证据文档,并加入 Android 模拟器截图抓取脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-03 11:37:53 +08:00
co-authored by Cursor
parent 15a9db374a
commit bd22d9dddd
248 changed files with 26309 additions and 842 deletions
+2
View File
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS ask_messages;
DROP TABLE IF EXISTS ask_threads;
+23
View File
@@ -0,0 +1,23 @@
-- Ask threads & messages (AI 成长助手)
CREATE TABLE IF NOT EXISTS ask_threads (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id),
profile_id uuid NOT NULL REFERENCES profiles(id),
scene varchar(32) NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz NULL
);
CREATE INDEX IF NOT EXISTS idx_ask_threads_user_id ON ask_threads(user_id);
CREATE INDEX IF NOT EXISTS idx_ask_threads_profile_id ON ask_threads(profile_id);
CREATE TABLE IF NOT EXISTS ask_messages (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
thread_id uuid NOT NULL REFERENCES ask_threads(id),
role varchar(16) NOT NULL CHECK (role IN ('user', 'assistant')),
content text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz NULL
);
CREATE INDEX IF NOT EXISTS idx_ask_messages_thread_id ON ask_messages(thread_id);
@@ -0,0 +1,2 @@
DELETE FROM scale_questions WHERE scale_id = '22222222-2222-2222-2222-222222222222';
DELETE FROM scales WHERE id = '22222222-2222-2222-2222-222222222222';
@@ -0,0 +1,30 @@
-- Second 探索测试: emotion pattern
INSERT INTO scales (id, slug, title, description, status)
VALUES (
'22222222-2222-2222-2222-222222222222',
'emotion-pattern',
'情感模式探索',
'了解你在情绪起伏时的调节偏好,生成探索结果标签。',
'published'
) ON CONFLICT (slug) DO NOTHING;
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222222', 1,
'{"prompt":"情绪上来时,你通常先做什么?","options":[{"key":"A","text":"说出感受,让对方知道"},{"key":"B","text":"先让自己平静下来"},{"key":"C","text":"去做一件能消耗精力的事"}]}'
WHERE NOT EXISTS (
SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222222' AND sort=1 AND deleted_at IS NULL
);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222222', 2,
'{"prompt":"压力很大的一周,什么最能帮到你?","options":[{"key":"A","text":"有人认真听你说完"},{"key":"B","text":"稳定的作息与熟悉的节奏"},{"key":"C","text":"把事情拆开并行动起来"}]}'
WHERE NOT EXISTS (
SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222222' AND sort=2 AND deleted_at IS NULL
);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222222', 3,
'{"prompt":"和亲近的人冷战时,你更倾向?","options":[{"key":"A","text":"主动表达委屈与需要"},{"key":"B","text":"先降温,等双方都稳住"},{"key":"C","text":"用具体行动修复关系"}]}'
WHERE NOT EXISTS (
SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222222' AND sort=3 AND deleted_at IS NULL
);
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS image_card_quotas;
DROP TABLE IF EXISTS moods;
@@ -0,0 +1,21 @@
-- Companion moods + (optional) image-card daily quota counter
CREATE TABLE IF NOT EXISTS moods (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id),
day date NOT NULL,
score int NULL CHECK (score IS NULL OR (score >= 1 AND score <= 5)),
note text NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz NULL,
UNIQUE (user_id, day)
);
CREATE INDEX IF NOT EXISTS idx_moods_user_id ON moods(user_id);
CREATE TABLE IF NOT EXISTS image_card_quotas (
user_id uuid NOT NULL REFERENCES users(id),
day date NOT NULL,
used int NOT NULL DEFAULT 0,
PRIMARY KEY (user_id, day)
);
@@ -0,0 +1,6 @@
DROP TABLE IF EXISTS favorites;
DROP TABLE IF EXISTS growth_checkins;
DROP TABLE IF EXISTS growth_plans;
-- scale seeds left in place (safe); delete by id if rolling back hard:
-- DELETE FROM scale_questions WHERE scale_id LIKE '22222222%';
-- DELETE FROM scales WHERE id LIKE '22222222%';
@@ -0,0 +1,115 @@
-- Growth plans + favorites; scale matrix seeds (≥8 official scales)
CREATE TABLE IF NOT EXISTS growth_plans (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id),
title text NOT NULL,
focus text NOT NULL DEFAULT '',
status varchar(32) NOT NULL DEFAULT 'active',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz NULL
);
CREATE INDEX IF NOT EXISTS idx_growth_plans_user_id ON growth_plans(user_id);
CREATE TABLE IF NOT EXISTS growth_checkins (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
plan_id uuid NOT NULL REFERENCES growth_plans(id),
user_id uuid NOT NULL REFERENCES users(id),
day date NOT NULL,
note text NULL,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (plan_id, day)
);
CREATE INDEX IF NOT EXISTS idx_growth_checkins_user_id ON growth_checkins(user_id);
CREATE TABLE IF NOT EXISTS favorites (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id),
kind varchar(32) NOT NULL,
ref_id uuid NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (user_id, kind, ref_id)
);
-- Helper: insert scale if missing (ids fixed for idempotency)
INSERT INTO scales (id, slug, title, description, status) VALUES
('22222222-2222-2222-2222-222222222201', 'mbti-lite', '人格类型探索', '了解能量来源与决策偏好的轻量探索。', 'published'),
('22222222-2222-2222-2222-222222222202', 'enneagram-lite', '动机模式探索', '觉察内在动机与压力反应。', 'published'),
('22222222-2222-2222-2222-222222222203', 'bigfive-lite', '性格五维探索', '稳定特质的自我速览。', 'published'),
('22222222-2222-2222-2222-222222222204', 'love-style', '亲密互动探索', '亲密关系中的表达与边界偏好。', 'published'),
('22222222-2222-2222-2222-222222222205', 'eq-lite', '情绪觉察探索', '识别与调节情绪的习惯。', 'published'),
('22222222-2222-2222-2222-222222222206', 'stress-index', '压力负荷探索', '近期压力与恢复方式。', 'published'),
('22222222-2222-2222-2222-222222222207', 'career-interest', '职业兴趣探索', '工作动力与环境偏好。', 'published')
ON CONFLICT (slug) DO NOTHING;
-- Questions: 3 each (MVP); scoring handled by existing engine via option keys
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222201', 1, '{"prompt":"周末充电,你更想?","options":[{"key":"E","text":"和朋友见面聊天"},{"key":"I","text":"独处安静恢复"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222201' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222201', 2, '{"prompt":"做决定时你更看重?","options":[{"key":"T","text":"逻辑与公平"},{"key":"F","text":"感受与关系"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222201' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222201', 3, '{"prompt":"面对计划,你更倾向?","options":[{"key":"J","text":"提前安排清楚"},{"key":"P","text":"保持弹性随机"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222201' AND sort=3);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222202', 1, '{"prompt":"压力大时你最先?","options":[{"key":"A","text":"想把事情做对"},{"key":"B","text":"想被理解和支持"},{"key":"C","text":"想先躲开冲突"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222202' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222202', 2, '{"prompt":"你最在意别人怎么看你?","options":[{"key":"A","text":"是否可靠靠谱"},{"key":"B","text":"是否温暖有情"},{"key":"C","text":"是否独特有想法"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222202' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222202', 3, '{"prompt":"成长路上你常提醒自己?","options":[{"key":"A","text":"再努力一点就好"},{"key":"B","text":"别忽略自己的感受"},{"key":"C","text":"保持真实就好"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222202' AND sort=3);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222203', 1, '{"prompt":"新环境里你通常?","options":[{"key":"O","text":"好奇尝试新事物"},{"key":"C","text":"先观察再行动"},{"key":"E","text":"主动认识新朋友"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222203' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222203', 2, '{"prompt":"做事风格更接近?","options":[{"key":"C","text":"有条理、按计划"},{"key":"A","text":"随情境灵活调整"},{"key":"N","text":"容易想很多细节"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222203' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222203', 3, '{"prompt":"相处中你更常?","options":[{"key":"A","text":"温和配合"},{"key":"E","text":"直接表达立场"},{"key":"O","text":"提出新点子"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222203' AND sort=3);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222204', 1, '{"prompt":"亲密关系里你更需要?","options":[{"key":"A","text":"稳定陪伴与承诺"},{"key":"B","text":"深度交流与共鸣"},{"key":"C","text":"各自空间与自由"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222204' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222204', 2, '{"prompt":"发生误解时你会?","options":[{"key":"A","text":"尽快说开"},{"key":"B","text":"先冷静再谈"},{"key":"C","text":"用行动表达关心"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222204' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222204', 3, '{"prompt":"表达喜欢时你更习惯?","options":[{"key":"A","text":"说出来"},{"key":"B","text":"做具体的事"},{"key":"C","text":"制造共同回忆"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222204' AND sort=3);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222205', 1, '{"prompt":"情绪上来时你最先?","options":[{"key":"A","text":"能叫出它的名字"},{"key":"B","text":"想马上做点什么压下去"},{"key":"C","text":"不太确定自己怎么了"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222205' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222205', 2, '{"prompt":"朋友难过时你更会?","options":[{"key":"A","text":"陪着听"},{"key":"B","text":"给建议"},{"key":"C","text":"一起转移注意"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222205' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222205', 3, '{"prompt":"调节自己时最有效的是?","options":[{"key":"A","text":"散步或运动"},{"key":"B","text":"写下来或说出来"},{"key":"C","text":"睡一觉再说"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222205' AND sort=3);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222206', 1, '{"prompt":"最近一周睡眠?","options":[{"key":"A","text":"大体规律"},{"key":"B","text":"时好时坏"},{"key":"C","text":"经常不足"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222206' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222206', 2, '{"prompt":"任务堆积时你?","options":[{"key":"A","text":"列清单逐个清"},{"key":"B","text":"先做紧迫的"},{"key":"C","text":"容易拖延焦虑"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222206' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222206', 3, '{"prompt":"恢复精力最依赖?","options":[{"key":"A","text":"运动与日照"},{"key":"B","text":"社交倾诉"},{"key":"C","text":"独处安静"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222206' AND sort=3);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222207', 1, '{"prompt":"理想工作更像?","options":[{"key":"A","text":"创造与表达"},{"key":"B","text":"帮助与支持他人"},{"key":"C","text":"分析与解决问题"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222207' AND sort=1);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222207', 2, '{"prompt":"团队里你自然扮演?","options":[{"key":"A","text":"提出方向的人"},{"key":"B","text":"协调氛围的人"},{"key":"C","text":"把细节落地的人"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222207' AND sort=2);
INSERT INTO scale_questions (scale_id, sort, body)
SELECT '22222222-2222-2222-2222-222222222207', 3, '{"prompt":"职业选择你最在意?","options":[{"key":"A","text":"意义感"},{"key":"B","text":"成长空间"},{"key":"C","text":"稳定与平衡"}]}'
WHERE NOT EXISTS (SELECT 1 FROM scale_questions WHERE scale_id='22222222-2222-2222-2222-222222222207' AND sort=3);
@@ -0,0 +1,2 @@
-- no-op: birth_place may pre-exist from 000001
SELECT 1;
@@ -0,0 +1,2 @@
-- birth_place already on profiles from init; ensure column exists for older DBs.
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS birth_place varchar(128) NULL;
@@ -0,0 +1,5 @@
DROP TABLE IF EXISTS synastry_invites;
DROP INDEX IF EXISTS idx_profiles_geo_visible;
ALTER TABLE profiles DROP COLUMN IF EXISTS geo_visible;
ALTER TABLE profiles DROP COLUMN IF EXISTS geo_lng;
ALTER TABLE profiles DROP COLUMN IF EXISTS geo_lat;
@@ -0,0 +1,22 @@
-- Synastry social: profile geo + invite tokens
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS geo_lat double precision NULL;
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS geo_lng double precision NULL;
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS geo_visible boolean NOT NULL DEFAULT false;
CREATE TABLE IF NOT EXISTS synastry_invites (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
token varchar(64) NOT NULL UNIQUE,
host_user_id uuid NOT NULL REFERENCES users(id),
host_profile_id uuid NOT NULL REFERENCES profiles(id),
expires_at timestamptz NOT NULL,
guest_user_id uuid NULL REFERENCES users(id),
guest_profile_id uuid NULL REFERENCES profiles(id),
report_id uuid NULL REFERENCES growth_reports(id),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz NULL
);
CREATE INDEX IF NOT EXISTS idx_synastry_invites_token ON synastry_invites(token);
CREATE INDEX IF NOT EXISTS idx_synastry_invites_host ON synastry_invites(host_user_id);
CREATE INDEX IF NOT EXISTS idx_profiles_geo_visible ON profiles(geo_visible) WHERE geo_visible = true AND deleted_at IS NULL;