外观
数据模型说明 — CodeNote
字段定义详见对应 Entity .kt 文件,已包含完整注释。
后端(MySQL)— src/main/kotlin/com/codenote/entity/*.kt
users ──┬── user_sessions / login_records / account_links ← 认证
├── qr_codes / categories / scan_records / public_links ← 二维码
├── activities ── check_in_configs / check_in_records
│ └── pass_configs / passes / pass_usage_records
├── assets ── asset_categories / asset_transfers
│ │ └── asset_inventories / asset_inventory_items
│ └── 通用动态数据模型:meta_objects / meta_fields / meta_templates
│ └── meta_template_fields / meta_object_bindings / meta_values
├── organizations ── org_members / org_shares / org_invitations / org_locations
├── album_photos / files
└── sync_mapping / unsynced_records
admin_logs / system_settings / token_blacklist / app_updates / agreements模块 → 实体文件:
| 模块 | 实体文件 |
|---|---|
| 认证 | User UserSession LoginRecord AccountLink TokenBlacklist |
| 二维码 | QrCode Category ScanRecord PublicLink |
| 活动/签到/通行 | Activity CheckInConfig CheckInRecord PassConfig Pass PassTemplate PassUsageRecord |
| 固定资产 | Asset AssetCategory AssetTransfer AssetInventory AssetInventoryItem(高频字段升列:brand/model/serial_no/purchase_date/purchase_price/supplier/warranty_expiry/remark) |
| 动态元数据 | MetaObject MetaField MetaTemplate MetaTemplateField MetaObjectBinding MetaValue |
| 组织 | Organization OrgMember OrgShare OrgInvitation OrgLocation |
| 相册/文件 | AlbumPhoto File |
| 系统 | Notification SystemSetting AdminLog AppUpdate |
| 协议 | Agreement(agreements,Markdown 原文 + 版本化) |
| 离线同步 | SyncMapping UnsyncedRecord |
| 联系人聊天 | ContactRequest Contact ContactBlock UserChatSetting Conversation ConversationMember Message(7 表,详见 /designs/messaging/contacts-chat.md) |
| RBAC 权限 | RbacPermission RbacRole RbacRolePermission RbacUserRole RbacUserPermission |
可见性架构(§,可扩展设计)
归属容器抽象:活动等资源归属为 owner_type + owner_id(PERSONAL=个人 / ORGANIZATION=组织 / DEPARTMENT=部门[未来]),替代硬编码个人/组织。
activities.creator_id(创建人,永远是人)+owner_type/owner_id(归属容器)activities.visibility:PUBLIC(公开,发现页展示)/ RESTRICTED(restricted_scope_type/id 指向容器成员)/ INVITE_ONLY(仅邀请,invite_code 凭证)activities.invite_code:INVITE_ONLY 生成,二维码activity:{id}:{inviteCode}携带即凭证;重置后旧码作废organizations.visibility:PUBLIC(发现页可见,可申请加入)/ INTERNAL(仅组织码/邀请,joinPolicy 强制 INVITE)
统一校验入口:ActivityVisibility.isVisible()(详情/签到/通行证/H5 落地页共用);成员关系走 MembershipService.isMember()(未来 DEPARTMENT 加分支)。
发现页:/api/discover/orgs、/api/discover/activities 只返回 PUBLIC + ACTIVE 资源。
agreements 用户协议/隐私政策表
版本化策略:只增不改(内容一经发布不可编辑删除,历史永久保留);同类型
type + version唯一;is_current标记当前生效版本(同类型互斥,发布/切换时事务内置位)。
sql
CREATE TABLE agreements (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(30) NOT NULL COMMENT '类型:SERVICE=服务协议 PRIVACY=隐私政策',
version INT NOT NULL COMMENT '版本号(同类型内递增)',
title VARCHAR(100) NOT NULL COMMENT '标题',
content TEXT NOT NULL COMMENT 'Markdown 原文',
is_current TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1=当前生效版本',
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL,
UNIQUE KEY uk_agreement_type_version (type, version)
) COMMENT='用户协议/隐私政策版本表';- 发布:版本号自动
max(version)+1,发布即生效(旧版本自动失效) - 回滚:历史版本可激活为当前生效版(
POST /api/admin/agreements/{id}/activate) - 展示:内容存 Markdown 原文,App 端经后端
MarkdownRenderer渲染为contentHtml展示 - 权限点(PLATFORM 域):
agreement:read/create/activate(BUSINESS_ADMIN 已授权)+content:render(BUSINESS_ADMIN/OPERATION_ADMIN) - 扩展(未来):用户签署记录表
agreement_acceptances(user_id, type, version, accepted_at);公告/帮助文档可复用渲染链路另行设计
通用动态数据模型(meta_*,实施)
取代原
asset_field_definitions/asset_category_field_bindings/asset_field_values(3 表已删)。 元数据驱动四层:业务对象 → 字段 → 模板 → 值;新业务只注册meta_objects即获得全套能力,零新增表结构。
6 张表:
| 表 | 说明 |
|---|---|
meta_objects | 业务对象注册表(object_name 唯一;main_entity_table 指向主实体表,asset→assets) |
meta_fields | 字段定义(scope: GLOBAL/ORG/USER;entity_column 非空=映射主实体固定列;软删 is_deleted,field_key 追加 '#id' 释放唯一键) |
meta_templates | 模板(可复用字段组合;is_default 每对象+scope 唯一;is_system 系统预置不可删;软删) |
meta_template_fields | 模板-字段明细(分组/排序/必填/布局 JSON) |
meta_object_bindings | 实体↔模板绑定(多态 object_name+entity_id,无外键,服务层级联删除) |
meta_values | 通用字段值(EAV + 冗余列 value_num/value_date + 类型索引,支持按类型筛选排序) |
混合存储(单一写路径):assets 保留高频固定列(8 个升列字段 + 原定位/照片/负责人等), 扩展字段全走 meta_values;固定列字段(meta_fields.entity_column 非空)的值读写统一走 PUT /api/meta/.../values,由 MetaValueService 按 entity_column 转写 assets 列,App/Admin 不感知差异。
字段类型注册表(统一 UPPER_SNAKE_CASE,15 种):TEXT / TEXTAREA / NUMBER / DATE / DATETIME / BOOLEAN / SELECT / MULTI_SELECT / RADIO / CHECKBOX / ATTACHMENT / PHOTO / GEO / REF / COMPUTED。 新增类型只注册一个 Validator(FieldValidatorRegistry),三端渲染自动生效。
预置数据(V1,优化):业务对象 资产(asset) + 资产分类(asset_category);asset 配 9 个 GLOBAL 字段(8 个升列映射 + source_type 走 meta_values)+ 三种系统模板:
默认资产模板(is_default):通用 8 字段(brand/model/serial_no/purchase_date/purchase_price/supplier/source_type/remark,无保修)电子设备模板:全部 9 字段,serial_no 必填,含 warranty_expiry办公用品模板:轻量 5 字段(model/purchase_date/purchase_price/supplier/remark)
RBAC 权限系统(通用三域)
通用三域 RBAC 权限系统(方案 v3.3 定稿,实施完成;权限点/矩阵详见 PermissionRegistry 与
后台端点权限核对表.md)
5 张表:
| 表 | 说明 |
|---|---|
rbac_permissions | 权限点定义(domain/resource/action 唯一;enabled 停用代替删除) |
rbac_roles | 角色定义(domain+scope_id+role_code 唯一;scope_id:ORG 域=orgId,PLATFORM/APP 域=0 全局,不用 NULL) |
rbac_role_permissions | 角色-权限关联(级联删除) |
rbac_user_roles | 用户-角色关联(级联删除;组织角色绑定仅成员 ACTIVE 时生效) |
rbac_user_permissions | 用户-权限直接授权(例外授权;scope_id 使 ORG 域例外授权按组织生效) |
权限域:PLATFORM(管理后台,系统管理员管理)/ APP(App 用户,后台定义)/ ORG(组织,scope=orgId,拥有者管理)。
本次结构变更:
users.role/org_members.role列删除(不再双写,角色授权走rbac_user_roles)qr_codes/album_photos新增org_id(NULL=个人原件,非空=分享到组织的副本)org_shares重建:entity_id→source_id(原件)+copy_id(副本),唯一键(org_id, entity_type, copy_id)- 预置角色:PLATFORM
SYSTEM_ADMIN/USER_ADMIN/ORG_ADMIN,APPUSER(=全部 APP 权限,行为不变),ORGOWNER/ADMIN/MEMBER(scope_id=0 为模板,组织创建时复制);平台角色管理可管理 ORG 模板及组织实例角色(模板修改不回溯存量组织);模板自定义角色复制到组织时保留 isSystem(可删);OWNER 模板权限绑定无效(短路角色) - 权限点全量 212 个(PLATFORM 76 / APP 73 / ORG 63),PermissionRegistry 启动幂等同步(只增不删)
角色语义:OWNER 恒有该 scope 全部权限(短路放行);转让后旧 OWNER 降为 ADMIN(§1.2.2);初始 admin 的 SYSTEM_ADMIN 绑定不可撤销(§1.1#6)。
Android(Room)— Entities.kt
| Entity | 对应后端表 | 同步 |
|---|---|---|
CategoryEntity | categories | ✅ |
QrCodeEntity | qr_codes | ✅ |
ScanRecordEntity | scan_records | ✅ |
NotificationEntity | notifications | ❌ |
AssetEntity | assets | ✅ |
CheckInActivityEntity | check_in_activities | ❌ |
CheckInRecordEntity | check_in_records | ✅ |
PassEntity | passes | ❌ |
AlbumPhotoEntity | album_photos | ✅ |
OrgEntity | organizations | ❌ |
OrgMemberEntity | org_members | ❌ |
建表 SQL:
V1__init_schema.sql
附录:users / assets 补充字段与枚举
users 表补充字段:
nickname VARCHAR(50) NOT NULL DEFAULT ''— 昵称,全端显示默认用它;用户可经 updateProfile 修改(≤50 字符,null 不改,空串清空)signature VARCHAR(200) DEFAULT NULL— 个性签名(≤100 字符,新增)
assets 表补充列:assignee_name VARCHAR(50) — 当前使用人昵称快照(分配/转移时写入)
org_invitations 表补充列:expires_at BIGINT NOT NULL DEFAULT 0 — 邀请过期时间戳(毫秒),0 表示不限制;PENDING 超时后惰性置为 EXPIRED(新增,有效期 7 天)
新增表:
nickname_adjectives/nickname_nouns— 昵称词库(各预置 100 条,admin CRUD)
credential_codes.type 新增枚举:PASSWORD_RESET(忘记密码 + 登录态修改密码共用)
附录:user_identities 用户认证身份表
sql
CREATE TABLE user_identities (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
provider VARCHAR(32) NOT NULL COMMENT 'PHONE/EMAIL/DEVICE/WECHAT/APPLE...',
identifier VARCHAR(255) NOT NULL COMMENT '手机号/邮箱/设备ID/微信openid',
credential VARCHAR(255) DEFAULT NULL COMMENT '第三方unionid等',
verified BOOLEAN NOT NULL DEFAULT FALSE,
extra TEXT DEFAULT NULL COMMENT '设备名/第三方昵称/头像等',
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL,
UNIQUE KEY uk_provider_identifier (provider, identifier),
INDEX idx_user_id (user_id),
CONSTRAINT fk_identity_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) COMMENT '用户认证身份表';- 规则:PHONE/EMAIL/WECHAT 每用户一条(换绑=删旧插新);DEVICE 每用户多条但仅存在于「无其他登录方式」窗口期(:绑定手机/邮箱/密码或登出时自动删除,设备永不与账号绑定)
users.username/password保留(用户名密码登录凭据)account_links保留(多账号切换);user_sessions / login_records的 device_id 为会话/审计标识,不变- 设备管理 = 会话设备管理:
GET /api/auth/devices改查user_sessions(登录设备 + 最后活跃时间),移除 = 吊销会话 - 各业务表(categories/qr_codes/album_photos/scan_records 等)的 device_id 列保留(历史数据)
login_records.login_type 新增:password_reset、password_change、email_unbind、phone_unbind