Files
pokopiawiki.tootaio.com/DESIGN.md
xiaomai ec3494ea28 docs: expand project design and agent guidelines
Rewrite DESIGN.md to detail product goals, data models, and API boundaries
Update AGENTS.md with existing UI patterns, i18n rules, and strict completion criteria
2026-05-01 14:50:05 +08:00

9.8 KiB
Raw Blame History

Pokopia Wiki

产品目标

  • Pokopia Wiki 是一个面向 Pokopia 游戏资料的社区 Wiki。
  • 所有人都可以浏览 Wiki 内容。
  • 已注册并完成邮箱验证的用户可以创建、编辑、删除 Wiki 内容。
  • 前台以 Pokemon、栖息地、物品、材料单、每日 CheckList 为主要浏览入口。
  • 管理入口用于维护全局配置、语言、列表排序和每日 CheckList。

技术栈

  • Monorepopnpm workspaceNode.js >= 22TypeScript。
  • 前端Vue、Vite、Vue Router、Vue I18n、Iconify。
  • 后端Node.js、Fastify、pg、PostgreSQL。
  • 运维Docker / docker compose。
  • 依赖版本遵循现有 package.json,新增依赖时优先使用当前主流稳定版本,并保持项目结构简单。

全局设计原则

  • DESIGN.md 是产品行为、数据结构和 API 暴露边界的单一事实来源。
  • API 只返回业务需要的字段不返回密码、token hash、验证 token、内部调试字段或不必要的元数据。
  • 用户界面只展示业务数据和设计内的文案,不展示提示词、计划、调试信息、字段内部名或修改说明。
  • 可编辑 Wiki 内容必须记录创建者、最后编辑者、创建时间、最后编辑时间和编辑历史。
  • 列表顺序由 sort_order 控制,默认按创建时间旧到新初始化,排序值按 10 递增以便后续插入和拖拽排序。

国际化

  • 前端使用 Vue I18n 管理界面文案,并通过 X-Locale 请求头告知后端当前语言。
  • 前端当前语言保存在 localStoragepokopia_locale
  • 后端默认语言为 en
  • 语言配置存储在 languages
    • code
    • name
    • enabled
    • is_default
    • sort_order
  • 语言 code 格式为 xxxx-YY,例如 enzh-CN
  • 系统必须且只能有一个默认语言。
  • 初始语言包含:
    • enEnglish默认语言
    • zh-CN:简体中文
  • 实体翻译存储在 entity_translations
    • entity_type
    • entity_id
    • locale
    • field_name
    • value
  • 支持翻译的实体:
    • Pokemon
    • 特长
    • 喜欢的环境
    • 喜欢的东西 / 标签
    • 物品分类
    • 物品用途
    • 入手方式
    • 物品
    • 地图
    • 栖息地
    • 每日 CheckList Task
  • 支持翻译的字段:
    • name
    • title
  • 实体仍保留基础 nametitle 字段,默认语言内容以基础字段为准。
  • API 返回展示名称时按当前语言解析,回退顺序为:请求语言翻译 -> 默认语言翻译 -> 基础字段。
  • 编辑表单必须避免本地化 UI 覆盖基础名称;翻译字段只展示当前需要编辑的语言。

用户与认证

  • 用户可注册:
    • 邮箱
    • 显示名
    • 密码
  • 邮箱保存为小写。
  • 密码只保存 hash。
  • 注册后必须通过邮箱验证。
  • 邮件发送使用 Resend
    • RESEND_API_KEY
    • EMAIL_FROM
    • APP_ORIGINFRONTEND_ORIGIN
  • 验证邮件包含一次性验证链接。
  • 验证 token 只保存 hash并带过期时间和使用状态。
  • 只有邮箱已验证的用户可以登录。
  • 登录成功后返回明文 session token 给前端;数据库只保存 session token hash。
  • 前端将登录 token 保存在 localStoragepokopia_auth_token
  • 用户可退出登录,退出时删除对应 session。
  • 对外用户字段只包含必要信息:
    • 当前用户:idemaildisplayNameemailVerified
    • 编辑署名:iddisplayName

Community 编辑与审计

  • 已验证用户可以通过前台或管理入口编辑 Wiki 内容。
  • 新增、修改、删除 Wiki 内容时必须写入审计信息。
  • 可编辑实体包含:
    • Pokemon
    • 栖息地
    • 物品
    • 材料单
    • 每日 CheckList Task
    • 全局配置项
  • 主要可编辑表包含:
    • created_by_user_id
    • updated_by_user_id
    • created_at
    • updated_at
    • sort_order
  • 详细编辑历史存储在 wiki_edit_logs
    • entity_type
    • entity_id
    • actioncreate / update / delete
    • user_id
    • changes
    • created_at
  • 详情页展示最后编辑者、最后编辑时间和编辑历史面板。
  • 编辑历史中的用户信息只展示必要署名不暴露邮箱、token、hash 或内部元数据。

全局配置数据

以下配置项都支持创建、编辑、删除、翻译和拖拽排序。

特长

  • 名称
  • 是否有掉落物:has_item_drop
  • 已移除 subcategory 字段。
  • 当特长允许掉落物时Pokemon 编辑中可为该 Pokemon + 特长配置一个掉落物品。

喜欢的环境

  • 名称

喜欢的东西 / 标签

  • 名称
  • 同时用于:
    • Pokemon 喜欢的东西
    • 物品标签

物品分类

  • 名称
  • 用于物品和材料单按结果物品分类展示。

物品用途

  • 名称
  • 物品用途可为空。

入手方式

  • 名称
  • 可关联到物品和材料单。

地图

  • 名称
  • 用于栖息地中 Pokemon 出现地点。

Pokemon

Pokemon 可配置:

  • ID
  • 名称
  • 喜欢的环境:单选
  • 特长:可多选,最多 2 个
  • 特长掉落物品:按 Pokemon + 特长配置,单选物品
  • 喜欢的东西:可多选,最多 6 个
  • 出现的栖息地:由栖息地出现配置反向展示
  • 翻译
  • 排序

Pokemon 列表功能:

  • 搜索
  • 按喜欢的环境筛选
  • 按特长筛选:
    • 满足任意条件
    • 满足全部条件
  • 按喜欢的东西筛选:
    • 满足任意条件
    • 满足全部条件
  • 按自定义排序展示

Pokemon 详情页展示:

  • 基本信息
  • 特长
  • 特长掉落物品
  • 喜欢的环境
  • 喜欢的东西
  • 关联喜欢的东西的物品
  • 出现的栖息地
  • 最后编辑信息
  • 编辑历史

物品

物品可配置:

  • 名称
  • 分类:必填
  • 用途:可为空
  • 入手方式:可多选
  • 客制化:
    • 可染色
    • 可双区染色
    • 可改花纹
  • 无材料单:no_recipe
  • 标签:使用喜欢的东西配置,可多选
  • 翻译
  • 排序

物品列表功能:

  • 搜索
  • 按分类展示为标签页
  • 按用途筛选
  • 按标签筛选
  • 按自定义排序展示

物品详情页展示:

  • 基本信息
  • 分类
  • 用途
  • 入手方式
  • 客制化
  • 标签
  • 关联材料单
  • 作为材料出现的材料单
  • 相关栖息地
  • 相关 Pokemon 掉落
  • 最后编辑信息
  • 编辑历史

材料单

材料单与物品是一对一关系:

  • 一个材料单必须关联一个结果物品。
  • 一个物品最多只能有一个材料单。
  • 标记为 no_recipe 的物品不能创建材料单。
  • 材料单没有独立名称,展示名称来自结果物品。

材料单可配置:

  • 结果物品
  • 入手方式:可多选
  • 需要材料:多项物品 + 数量
  • 排序

材料单列表功能:

  • 独立于物品列表展示
  • 按结果物品分类展示
  • 按自定义排序展示

材料单详情页展示:

  • 结果物品
  • 入手方式
  • 需要材料列表
  • 最后编辑信息
  • 编辑历史

栖息地

栖息地可配置:

  • 名称
  • 配方:多项物品 + 数量
  • 可出现的 Pokemon
  • 翻译
  • 排序

Pokemon 出现配置:

  • Pokemon
  • 地图:可多选
  • 时间:可多选
    • 早晨
    • 中午
    • 傍晚
    • 晚上
  • 天气:可多选
    • 晴天
    • 阴天
    • 雨天
  • 稀有度1 到 3 星

栖息地列表功能:

  • 按自定义排序展示
  • 展示配方摘要和可能出现的 Pokemon 摘要

栖息地详情页展示:

  • 配方列表
  • 可能出现的 Pokemon 列表
  • 出现时间
  • 出现天气
  • 稀有度
  • 出现的地图列表
  • 最后编辑信息
  • 编辑历史

每日 CheckList

每日 CheckList Task 可配置:

  • Task 标题
  • 翻译
  • Task 顺序

前台行为:

  • 展示每日要做的 Task。
  • 每个 Task 可勾选。
  • 勾选状态保存在浏览器本地。
  • 勾选状态按本地日期自动清空,不删除 Task。
  • 已删除 Task 的本地勾选状态会自动清理。

管理行为:

  • 已验证用户可新增、编辑、删除 Task。
  • 已验证用户可通过 Handle 拖拽排序。

前端交互与 UI

  • UI 风格以 DesignGuidelines.html 为准。
  • 页面结构以 AppShellPageHeader、列表、详情区和管理区为核心。
  • 导航和主要操作使用图标增强识别。
  • 数据加载状态使用 Skeleton避免裸文本 loading。
  • 分类切换使用 Tabs。
  • 布尔或模式选择使用 SwitchGroup、checkbox、segmented control 等合适控件。
  • 多选和单选复用 TagsSelect,支持搜索、键盘操作和必要时的内联创建。
  • 主要实体的新建和编辑使用路由驱动的 Modal
    • /pokemon/new
    • /pokemon/:id/edit
    • /habitats/new
    • /habitats/:id/edit
    • /items/new
    • /items/:id/edit
    • /recipes/new
    • /recipes/:id/edit
  • 进入或关闭编辑 Modal 时应保留底层页面上下文,不进行不必要的滚动跳转。
  • 用户界面不得展示内部字段名、调试数据、计划说明或“已修改某字段”一类实现说明。

API 概览

公开浏览 API

  • GET /api/languages
  • GET /api/options
  • GET /api/daily-checklist
  • GET /api/pokemon
  • GET /api/pokemon/:id
  • GET /api/habitats
  • GET /api/habitats/:id
  • GET /api/items
  • GET /api/items/:id
  • GET /api/recipes
  • GET /api/recipes/:id

认证 API

  • POST /api/auth/register
  • POST /api/auth/verify-email
  • POST /api/auth/login
  • GET /api/auth/me
  • POST /api/auth/logout

已验证用户编辑 API

  • Pokemon、栖息地、物品、材料单的创建、更新、删除。
  • 每日 CheckList 的创建、更新、删除、排序。
  • 全局配置项的创建、更新、删除、排序。
  • 语言的创建、更新、删除、排序。
  • Pokemon、物品、材料单、栖息地的列表排序。

开发与验证

  • 本项目在 WSL 中开发,运行验证主要通过 Docker。
  • 常规轻量验证:
    • pnpm lint
    • pnpm typecheck
  • 不在 WSL 中运行测试作为完成任务的前置条件。
  • Docker 运行问题以用户提供的 docker compose up --build 输出为准进行后续修复。