跳到主要内容

用户界面实现指引

本文档是 Reflekt Health 项目的 UI 实现指南,为前端开发提供技术规范、Mock 数据规范、API 联调方式和跨端共享约定。

重要说明:本文档基于 docs/archon/docs/ 目录下的需求文档编写,不引用 reflekt-health-prd 仓库的任何目录结构作为实现依据。实际代码仓库的目录结构由对应开发团队自行定义。

核心参考文档(均为 docs/archon/docs/ 下的需求文档):


1. 三端定位与技术栈

详见 软件端划分与特征定义 §2。

1.1 平台概览

平台技术栈设备尺寸用户角色技术特点
Family App(Family App)UniApp + Vue 3 + TypeScript390×844px(iPhone 16 Pro)子女/家属(35~55 岁)一套代码编译 iOS/Android 双端
Luma App(Luma 智能音箱)原生 Android(Kotlin) + Web 前端1280×800px(音箱屏幕)老年人(65~85 岁)语音优先,屏幕辅助,嵌入式固件
Admin(管理后台)Vue 3 + TypeScript + ElementPlusPC Web(最小 1024px)运营团队响应式 Web

1.2 目录结构约定

以下目录结构为实现指引,源自 docs/archon/docs/ 需求文档,非实际代码仓库路径。 实际代码仓库的目录由开发团队自行组织。

# Family App
fap-app/
├── src/
│ ├── pages/
│ │ ├── auth/login.vue # 登录页
│ │ ├── auth/register.vue # 注册页
│ │ ├── home/index.vue # 首页多状态(calm/alert/reminder/family/offline/help)
│ │ ├── devices/ # 设备管理
│ │ ├── messages/ # 消息中心
│ │ └── profile/ # 个人设置
│ ├── components/
│ │ ├── HeroCard.vue # 状态 Hero 卡片
│ │ ├── QuickSend.vue # Quick Send 网格
│ │ ├── BottomNav.vue # 底部导航
│ │ └── ElderAvatar.vue # 老人头像(状态环+状态点)
│ ├── styles/
│ │ └── tokens.css # 设计令牌(来自 ui_design_specification.md §1.1)
│ ├── api/
│ │ └── index.ts # 请求封装(JWT Token、响应拦截)
│ └── mocks/
│ ├── browser.ts
│ ├── handlers.ts
│ └── data/
│ ├── family.json # 首页状态 Mock
│ ├── alert.json # 告警 Mock
│ └── device.json # 设备 Mock
├── package.json
└── uni-app.config.js

# Luma App
luma-firmware/
├── app/
│ ├── src/main/kotlin/
│ │ ├── service/
│ │ │ ├── WebSocketService.kt # WebSocket 通信
│ │ │ ├── TTSService.kt # TTS 播报
│ │ │ └── WakeWordService.kt # 语音唤醒
│ │ └── ui/screen/ # 屏幕状态管理
│ └── src/main/assets/
│ └── screens/
│ ├── home_calm.html # 首页-正常状态(CALM)
│ ├── home_alert.html # 首页-预警询问(ALERT)
│ ├── home_offline.html # 首页-离线状态(OFFLINE)
│ ├── home_help.html # 首页-紧急帮助(HELP)
│ └── ... # 更多屏幕见 user_interface_structure.md §2
└── build.gradle

# Admin 管理后台
admin-web/
├── src/
│ ├── views/ # 页面视图
│ ├── api/ # 接口调用层
│ ├── store/ # Pinia 状态管理
│ └── router/ # Vue Router
├── mocks/
│ ├── handlers.ts
│ └── data/
└── package.json

1.3 页面文件命名规范(强制)

详见 user_interface_structure.md §命名规范

所有 UI 页面文件必须使用全小写 + 下划线分隔符,不得出现大写字母。

  • ✅ 正确:home_calmhome_alertdevices
  • ❌ 错误:HomeCalmHomeAlertDevices

2. Family App 实现规范

2.1 技术栈详解

层级技术选型说明
跨端框架UniApp + Vue 3 + TypeScript一套代码编译至 iOS / Android
样式方案CSS Variables + Scoped CSS共享设计令牌,不依赖 Tailwind
状态管理PiniaUniApp 官方推荐
HTTP 客户端uni.requestAPI 调用统一出口
推送 SDKuni-app-push(APNs + FCM)iOS APNs / Android FCM 双端
页面路由UniApp Router(pages.json声明式路由,路由守卫鉴权
MockMSW(Mock Service Worker)拦截请求,本地开发不依赖后端
构建输出iOS .ipa / Android .apk / .aabApp Store / Google Play

禁止使用:jQuery、Zepto、Bootstrap(不符合适老化要求)。

2.2 设计令牌接入

ui_design_specification.md §1.1 提取设计令牌,转换为项目中的 CSS 变量文件(tokens.css):

/* tokens.css — 从 ui_design_specification.md §1.1 提取 */

:root {
/* 墨色系列(文字) */
--ink: #1A1814;
--ink-mid: #4A4540;
--ink-soft: #7A7570;
--ink-dim: #B0AAA5;

/* 纸张系列(背景) */
--paper: #F8F6F2;
--paper2: #F0EDE8;
--paper3: #E8E4DE;
--white: #FFFFFF;

/* 状态色 */
--green: #4A8A5A;
--green-light: #EAF4EF;
--amber: #8A7040;
--amber-light: #FEF3C7;
--red: #9A5040;
--red-light: #FEF2F2;
--blue: #3D6B9A;
--blue-light: #EFF6FF;

/* 字体 */
--font-display: 'Fraunces', Georgia, serif;
--font-body: 'DM Sans', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;

/* 动画缓动 */
--ease-spring: cubic-bezier(0.22, 1, 0.36, 1);
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

始终使用 CSS 变量,禁止硬编码色值

/* ✅ 正确 */
background-color: var(--green-light);
color: var(--ink);
font-family: var(--font-display);

/* ❌ 错误 */
background-color: #EAF4EF;
color: #1A1814;
font-family: 'Fraunces', Georgia, serif;

2.3 页面路由与跳转

完整路由表见 user_interface_structure.md §4

// pages.json(UniApp 路由配置)
{
"pages": [
{ "path": "pages/auth/login/index" },
{ "path": "pages/auth/register/index" },
{ "path": "pages/home/index" },
{ "path": "pages/devices/index" },
{ "path": "pages/messages/index" },
{ "path": "pages/profile/index" }
],
"subPackages": [
{ "path": "pages-reminder", "pages": [...] },
{ "path": "pages-memory", "pages": [...] },
{ "path": "pages-privacy", "pages": [...] }
]
}

首页状态路由参数(六状态联动):

全局状态路由参数首页 Hero 卡片样式
CALM?state=calm--green-light 绿色背景
ALERT?state=alert--red-light 红色背景 + 脉冲动画
HELP?state=help--red 深红背景 + 紧急横幅
REMINDER?state=reminder--amber-light 琥珀色背景
FAMILY?state=family--blue-light 蓝色背景
OFFLINE?state=offline--paper3 灰色背景

2.4 Mock 数据规范(MSW)

Family App 前端开发阶段使用 MSW(Mock Service Worker) 拦截所有 API 请求,无需后端即可完成开发和验收。

2.4.1 Mock 初始化

// mocks/browser.ts
import { setupWorker } from 'msw'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)

// main.ts 中
if (import.meta.env.DEV) {
worker.start({
onUnhandledRequest: 'bypass',
quiet: true,
})
}

2.4.2 Mock Handlers(示例)

完整接口列表见 api_specification.yaml

// mocks/handlers.ts
import { http, HttpResponse } from 'msw'
import type { FamilyStatus, Alert, Device } from '@/types'

// 响应数据结构(来自 api_specification.yaml)
type ApiResponse<T> = {
code: number
data: T
message: string
}

export const handlers = [
// GET /family/status — 首页六状态
http.get('/api/v1/family/status', (): ApiResponse<FamilyStatus> => ({
code: 0,
data: {
elderName: 'Mary',
elderAvatar: null,
state: 'CALM', // CALM | REMINDER | FAMILY | ALERT | HELP | OFFLINE
lastHeartbeat: '2026-04-22T08:30:00Z',
}
})),

// GET /alerts — 告警列表
http.get('/api/v1/alerts', (): ApiResponse<{ total: number; list: Alert[] }> => ({
code: 0,
data: {
total: 1,
list: [{
id: 'ALT_001',
elderId: 'ELDER_001',
level: 'red', // red | amber | normal
status: 'firing', // firing | acknowledged | resolved | false_alarm
firedAt: new Date().toISOString(),
evidence: { heartRate: 58, fallConfidence: 0.92 },
}]
}
})),

// GET /devices — 设备列表
http.get('/api/v1/devices', (): ApiResponse<Device[]> => ({
code: 0,
data: [
{
id: 'DEV_LUMA_001',
deviceType: 'luma',
name: "Mary's Luma",
serialNumber: 'LMA-XXXX-XXXX',
status: 'online', // online | offline
lastHeartbeat: new Date().toISOString(),
},
{
id: 'DEV_RADAR_001',
deviceType: 'radar',
name: 'Bedroom Radar',
serialNumber: 'RDR-XXXX-XXXX',
status: 'online',
lastHeartbeat: new Date().toISOString(),
}
]
})),

// POST /auth/login — 登录
http.post('/api/v1/auth/login', async ({ request }): ApiResponse<{ token: string; userId: string }> => {
const body = await request.json() as { phone: string; password: string }
if (body.phone === '13800000000' && body.password === 'password') {
return {
code: 0,
data: { token: 'mock-jwt-token-' + Date.now(), userId: 'USR_001' }
}
}
return { code: 401, data: null, message: 'Invalid credentials' }
}),

// POST /alerts/{id}/ack — 告警确认(中断升级链路)
http.post('/api/v1/alerts/:id/ack', ({ params }): ApiResponse<{ id: string }> => ({
code: 0,
data: { id: params.id }
})),

// POST /device/bind — 设备绑定
http.post('/api/v1/device/bind', async (): ApiResponse<Device> => ({
code: 0,
data: {
id: 'DEV_NEW_' + Date.now(),
deviceType: 'luma',
status: 'online',
createdAt: new Date().toISOString(),
}
})),

// GET /family/members — 家庭成员
http.get('/api/v1/family/members', (): ApiResponse<FamilyMember[]> => ({
code: 0,
data: [
{ id: 'USR_001', name: 'John', role: 'admin', priority: 1, phone: '13800000001' },
{ id: 'USR_002', name: 'Sarah', role: 'member', priority: 2, phone: '13800000002' },
]
})),
]

2.5 API 联调规范

2.5.1 请求封装与 Token 管理

// api/index.ts(统一请求封装)
import { getToken, clearToken } from '@/utils/auth'

type RequestOptions = {
path: string
method: 'GET' | 'POST' | 'PUT' | 'DELETE'
data?: Record<string, unknown>
}

type ApiResponse<T> = {
code: number
data: T
message: string
}

export function request<T>(options: RequestOptions): Promise<T> {
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}${options.path}`,
method: options.method as any,
header: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${getToken()}`,
},
data: options.data,
success: (res) => {
const response = res.data as ApiResponse<T>

if (res.statusCode === 401 || response.code === 401) {
clearToken()
uni.reLaunch({ url: '/pages/auth/login/index' })
reject(new Error('Unauthorized'))
return
}

if (response.code !== 0) {
uni.showToast({ title: response.message, icon: 'none' })
reject(new Error(response.message))
return
}

resolve(response.data)
},
fail: () => {
uni.showToast({ title: 'Network error', icon: 'error' })
reject(new Error('Network error'))
}
})
})
}

// 使用示例
export const api = {
getFamilyStatus: () => request<FamilyStatus>({ path: '/family/status', method: 'GET' }),
getAlerts: (params?: { status?: string }) => request<Alert[]>({ path: '/alerts', method: 'GET', data: params }),
ackAlert: (id: string) => request({ path: `/alerts/${id}/ack`, method: 'POST' }),
bindDevice: (data: BindDeviceDto) => request<Device>({ path: '/device/bind', method: 'POST', data }),
}

2.5.2 响应数据结构规范

所有后端 API 遵循统一响应格式(见 api_specification.yaml):

// 成功
interface SuccessResponse<T> {
code: 0
data: T
message: ''
}

// 失败
interface ErrorResponse {
code: number // 401/403/404/500
data: null
message: string
}
code说明前端处理
0成功读取 data 字段
401未认证 / Token 过期跳转登录页
403无权限(跨家庭访问)提示"无权访问"
404资源不存在提示"内容不存在"
500服务端错误提示"服务异常,请稍后重试"

2.6 核心组件实现要点

2.6.1 六状态首页

详见 user_interface_structure.md §1.3ux_design_specification.md §3

<!-- pages/home/index.vue — 首页多状态容器 -->
<template>
<div class="app-container fadeIn">
<header class="header">...</header>

<main class="content slideUp">
<!-- 动态渲染对应状态的内容 -->
<component :is="currentStateComponent" />
</main>

<BottomNav :active="0" />
</div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import HomeCalm from './states/HomeCalm.vue'
import HomeAlert from './states/HomeAlert.vue'
import HomeOffline from './states/HomeOffline.vue'

const props = defineProps<{ state?: string }>()

const currentStateComponent = computed(() => {
const stateMap = {
CALM: HomeCalm,
ALERT: HomeAlert,
OFFLINE: HomeOffline,
REMINDER: HomeCalm, // 共用模板
FAMILY: HomeCalm,
HELP: HomeAlert,
}
return stateMap[props.state || 'CALM'] || HomeCalm
})
</script>

2.6.2 Quick Send(ALERT/HELP 态禁用)

<template>
<div class="send-grid">
<div
v-for="item in sendOptions"
:key="item.id"
class="send-card"
:class="{ disabled: isUrgent && item.id !== 'call' }"
>
...
</div>
</div>
</template>

<script setup lang="ts">
const isUrgent = computed(() =>
['ALERT', 'HELP'].includes(globalState.value)
)
</script>

2.6.3 老人头像(状态环动画)

CSS 动画定义见 ui_design_specification.md §1.8

/* 状态环脉冲动画 */
@keyframes ringPulse {
0%, 100% { transform: scale(1); opacity: 0.35; }
50% { transform: scale(1.06); opacity: 0.15; }
}
/* CALM: 3.5s / ALERT: 1.5s */
.status-ring { animation: ringPulse var(--ring-duration, 3.5s) ease-in-out infinite; }

3. Luma App 实现规范

3.1 技术栈与设备约束

层级技术选型说明
系统Android 10(定制固件)小黄蜂定制 Luma 音箱
应用Kotlin + WebView(HTML/CSS/JS)屏幕界面基于 Web,语音 Native
屏幕1280×800px 触摸屏固定尺寸,CSS 缩放适配
语音唤醒OpenAI Whisper(本地离线)唤醒词检测
语音合成OpenAI TTS(云端)跌倒询问、提醒播报、对话回复
语音对话OpenAI GPT-4o(云端)AI 对话生成
通信HTTP + WebSocket状态上报、指令下发、告警推送
固件构建Gradle + Android SDK编译为 .img 刷入设备

分辨率硬约束1280×800px,所有屏幕必须基于此尺寸设计。

3.2 页面清单与触发条件

完整清单见 user_interface_structure.md §2

屏幕触发条件核心 UI
home_calm设备激活后默认,状态平稳时间(52px+) + 问候语 + "I'm right here"
home_alert检测到异常活动"Mary, are you okay?" + 倾听动画
home_offline网络断连灰色调 + "I'm still here" + 颗粒纹理
home_help老人说"I need help"深红背景 + SOS 脉冲环
home_listening唤醒词触发Wave 动画(5 根声波条)
care_card收到家属语音消息家庭蓝渐变 + Voice Pulse 动画

3.3 屏幕结构规范

CSS 样式见 ui_design_specification.md §2.4-2.11

<!-- 屏幕固定分层结构(1280×800) -->
<div class="screen">
<div class="layer-time"> <!-- 时间层 -->
<div class="layer-card"> <!-- 内容层 -->
<div class="layer-presence"> <!-- 存在感层 -->
</div>
<div class="ambient-glow"></div> <!-- 氛围光(按状态可选) -->
<div class="grain-layer"></div> <!-- 颗粒纹理(OFFLINE/HELP) -->
<div class="safety-strip"></div> <!-- 安全提示条(OFFLINE) -->
/* 屏幕固定尺寸 */
.screen {
width: 1280px;
height: 800px;
max-width: 100vw;
max-height: 100vh;
}

/* 响应式缩放 */
@media (max-width: 1280px) {
.screen { width: 100vw; height: 56.25vw; }
}
@media (max-width: 900px) {
.time { font-size: 40px !important; }
.greeting { font-size: 38px !important; }
}

3.4 六状态屏幕样式速查

完整 CSS 变量见 ui_design_specification.md §2.1-2.7

状态背景色强调色氛围光动画
CALM#FAFAF7 暖白#8A6A00 琥珀琥珀径向渐变状态环慢速脉冲
ALERT#FAFAF7 暖白#B91C1C 深红琥珀/红渐变琥珀脉冲点
HELP#0D1117 深黑#8A3030 深红深红呼吸光晕SOS 脉冲环
OFFLINE#0D1117 深黑#5A6060 灰色中心灰色光晕旋转环 + 颗粒纹理
FAMILY#0D1117 深黑#3D6A9A 家庭蓝家庭蓝渐变Voice Pulse 点动画
LISTENING继承当前状态Wave 动画(5 声波条)

3.5 WebSocket 联调

Luma App 通过 WebSocket 接收服务端推送,双向通信:

// WebSocketService.kt — Luma App Android Kotlin

sealed class ServerEvent {
data class Alert(val data: AlertData) : ServerEvent()
data class Reminder(val data: ReminderData) : ServerEvent()
data class FamilyMessage(val data: MessageData) : ServerEvent()
data class TTSPlay(val text: String) : ServerEvent()
data class StateChange(val state: DeviceState) : ServerEvent()
}

sealed class LocalEvent {
data class Heartbeat(val deviceId: String) : LocalEvent()
data class UserResponse(val sessionId: String, val text: String) : LocalEvent()
data class SOSActivated(val elderId: String) : LocalEvent()
data class ReminderConfirmed(val reminderId: String) : LocalEvent()
}

class WebSocketService(token: String) {
private var ws: WebSocket? = null
private val reconnectDelay = ExponentialBackoff(initial = 1000, max = 30000)

fun connect() {
ws = OkHttpClient().newWebSocket(
Request.Builder().url("wss://api.reflekt.health/ws?token=$token").build(),
object : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
when (val event = parse(text)) {
is ServerEvent.Alert -> showScreen("home_alert", event.data)
is ServerEvent.Reminder -> showScreen("custom_reminder", event.data)
is ServerEvent.FamilyMessage -> showScreen("care_card", event.data)
is ServerEvent.TTSPlay -> ttsService.speak(event.text)
is ServerEvent.StateChange -> transitionTo(event.state)
}
}
override fun onFailure(...) { reconnect() }
}
)
}

fun send(event: LocalEvent) {
ws?.send(jsonEncode(event))
}
}

服务端推送事件类型

事件来源服务Luma App 处理
ALERTD4 AI 大脑显示预警询问屏,播放 TTS "Are you okay?"
REMINDERD2 家属端显示提醒播报屏,播放提醒内容
FAMILY_MSGD2 家属端显示家属消息卡片,播放语音
TTS_PLAYD4 AI 大脑调用 TTS 播报文本
STATE_CHANGED1 设备接入切换屏幕状态(如断网 → OFFLINE)

4. Admin 管理后台实现规范

4.1 技术栈

层级技术选型说明
前端框架Vue 3 + TypeScript组合式 API(Composition API)
UI 组件库ElementPlusVue 3 官方推荐
状态管理PiniaVue 3 官方推荐
HTTP 客户端Axios请求拦截、统一错误处理
路由Vue Router 4路由守卫鉴权
构建工具Vite快速热更新
Mockvite-plugin-mock + Mock.js开发阶段 Mock
CSSScoped CSS + CSS Variables不引入 Tailwind
目标平台PC Web(Chrome 90+)最小宽度 1024px

4.2 关键页面

完整清单见 user_interface_structure.md §1.10functional_requirements.md §三

模块页面核心功能
仪表盘dashboard试点运营看板(在线率/跌倒数/误报率)
设备管理device/list设备状态监控、绑定/解绑
告警管理alert/list告警列表、升级链路跟踪、处理标记
家庭管理family/list试点家庭档案、安装进度
审计日志audit/log12 个月日志查询(HIPAA 合规)
配置中心config/template关怀话术模板、提醒模板
用户权限system/user运营人员账号与 RBAC 权限

4.3 Mock Handlers(Admin)

// mocks/handlers.ts(Admin)
import { http, HttpResponse } from 'vitest/mockttp'
import { alertListData, deviceStatsData } from './data'

export const adminHandlers = [
http.get('/api/v1/admin/devices', () =>
HttpResponse.json({ code: 0, data: deviceStatsData })
),

http.get('/api/v1/admin/alerts', ({ request }) => {
const url = new URL(request.url)
const status = url.searchParams.get('status')
const filtered = status
? alertListData.filter(a => a.status === status)
: alertListData
return HttpResponse.json({ code: 0, data: filtered })
}),

http.post('/api/v1/admin/alerts/:id/handle', async ({ params }) =>
HttpResponse.json({ code: 0, data: { id: params.id, status: 'resolved' } })
),
]

4.4 启动与构建

# 安装依赖
pnpm install

# 开发模式(含 Mock)
pnpm dev

# 构建生产包
pnpm build

# 预览生产包
pnpm preview

5. 跨端共享规范

5.1 六状态颜色语义(Family App / Luma App / Admin 统一)

状态英文背景色强调色含义
平静CALM#EAF4EF#4A8A5A一切正常,无需行动
提醒REMINDER#FEF3C7#8A7040有提醒待确认
家人FAMILY#EFF6FF#3D6B9A老人给家属留了消息
关注ALERT#FEF2F2#9A5040可能发生跌倒,需确认
求助HELP#FEF2F2#8A3030老人已明确求助
离线OFFLINE#E8E4DE#5A6060连接已中断

5.2 文案红线(强制遵守)

来源:ux_design_specification.md §10.2raw_requirements_context.md §10.2

禁用表达替代表达
"已检测到跌倒""可能发生了什么,正在确认"
"Missed"、"detected"、"abnormal"中性温和描述
"emergency"(老人端)、"SOS"、"报警""need help" / "请说'帮我呼叫'"
"I'm monitoring you""我会陪你度过每一天"
"你昨晚没睡好""昨晚似乎有点辗转反侧"
原始数据值("步数:3245")温暖的人类语言,如"今天活动量正常"

5.3 字体规范

字体用途Family AppLuma AppAdmin
Fraunces / Libre Baskerville品牌标题、时间、问候语
DM Sans正文、界面文字、标签
Lora登录页品牌名
JetBrains Mono代码、等宽数据

5.4 四大设计铁律(跨端通用)

来源:ux_design_specification.md §9.1

铁律核心含义违规示例
Law 1: 冷静技术界面保持安静,不主动吸引注意力弹出通知、闪烁动画
Law 2: 解读,而非展示把数据翻译成温暖的人类语言展示原始步数图表
Law 3: 在场,而非评判永远不评判用户行为"你昨晚没睡好"、过度表扬
Law 4: 克制带来信任选择不展示什么比展示什么更重要展示摄像头画面、仪表盘

5.5 适老化硬指标

指标Family AppLuma App(强制)Admin
最小字号≥ 16pt≥ 18pt无要求
触控目标≥ 44dp × 44dp≥ 44dp无要求
按钮高度≥ 56dp(主 CTA)≥ 56dp无要求
对比度WCAG AA(4.5:1)WCAG AA(优先 7:1)无要求

6. 设计自查四问

来源:ux_design_specification.md §7raw_requirements_context.md 附录

完成每一屏实现后,自我检查:

  1. 这个设计感觉像监视吗?(答案必须是"否")
  2. 这个设计感觉像医疗产品吗?(答案必须是"否")
  3. 这个设计还能更简单吗?(答案必须是"是",并持续简化)
  4. 我的父母会对此感到舒适吗?(答案必须是"是")

If something feels impressive, remove it. If something feels quiet, keep it.


7. 参考文档索引

文档路径用途
用户界面结构设计./user_interface_structure.md页面字典、路由、跳转逻辑、组件复用
UX 交互设计规范./ux_design_specification.md四大铁律、六状态体系、动画规范、语音 UX
UI 视觉设计规范./ui_design_specification.md设计令牌、组件样式、字号规范
API 接口设计/_wiki_assets/api_specification.yamlOpenAPI 接口规格(权威来源)
软件端划分./software_endpoints.mdFamily App / Luma App / Admin 三端技术栈定义
功能清单明细./functional_requirements.md各端功能原子化清单(P0/P1)
原始需求上下文./raw_requirements_context.md文案红线、语音 UX 规范、升级链路参数
约束与依赖./constraints_and_dependencies.mdHIPAA 合规、第三方限制、设备约束

本文档由 Reflekt Health 研发团队维护,最后更新于 2026-04-22。