6e94db0c2b
feat(admin): add backup/restore tab (dual-mode + task progress polling)
...
新增 dashmap 依赖。create_backup 探测 pg_dump 优先(含 schema,签名头前置)、
不可用回退纯 SQL(COPY TO STDOUT 逐表,按表精确进度)。restore_backup 校验
签名头(仅本系统备份)+ 路径穿越防护 + 二次确认,探测 psql 执行。
list_backups/delete_backup 管理备份,GET /api/database/backups/{name} 下载
(admin 鉴权 + 白名单)。tasks.rs DashMap 进度表(1h 惰性 GC),前端每 1.5s
轮询 get_task_progress 显示进度条/stage,完成后刷新列表。
backups/ gitignored 不直接暴露。AGENTS.md 同步新增 CodeMirror 子项目与
数据库管理章节。
2026-06-29 19:16:11 +08:00
5c4b2a53d1
feat(admin): add data export tab (Axum streaming, SQL/CSV)
...
新增 GET /api/database/export Axum 流式路由(镜像 upload.rs 的 cookie→admin
鉴权),支持按表/按查询导出。CSV 用 COPY ... TO STDOUT WITH CSV 流式
(大表不 OOM),SQL 逐行拼 INSERT(含类型化转义)。表名白名单 + 查询
AST 只读强制。前端 ExportTab 触发 window.open 下载。
2026-06-29 19:01:16 +08:00
a49f47c8a6
feat(admin): add SQL console tab (read-write + 4 guards + sqlparser)
...
新增 sqlparser 依赖(optional+server),AppError 加 BadRequest 变体(护栏
返回动态用户可见消息)。execute_sql server function 全读写执行,4 道护栏:
(1) sqlparser AST 高危语句闸门——DROP DATABASE/SCHEMA 字符串预检绝禁、
DROP/TRUNCATE/ALTER 需勾选「我了解后果」;(2) 无 WHERE 的 UPDATE/DELETE 拒绝;
(3) 复用 STATEMENT_TIMEOUT_SECS 超时上限;(4) 前端写操作二次确认。
默认禁多语句,结果 500 行截断。get_db_schema 拉表/列供 CodeMirror 补全。
前端 SqlConsoleTab:CodeMirror 编辑器(Vim + Catppuccin 主题跟随站点 +
实时 schema 补全)+ 选项 toggles + 结果表格 + EXPLAIN 输出。
2026-06-29 18:56:15 +08:00
c4c490b881
feat(admin): add server status tab (sysinfo host metrics + cache hit rate)
...
新增 sysinfo 依赖(optional+server),sysinfo_sampler 后台采样任务
(SYSINFO_SAMPLE_SECS 可配,默认 0.5s)周期刷新 CPU/内存/磁盘/load 到 RwLock
快照,get_server_status 只读快照零成本。cache.rs 给 9 个缓存加 AtomicU64
hit/miss 计数 + cache_stats() 聚合命中率。
前端 ServerStatusTab:应用内指标(运行时间/连接池/会话/CPU/内存/磁盘/load)+
缓存命中率表 + 刷新按钮 + 自动刷新开关(500ms/1s/2s/5s/手动,默认手动)。
2026-06-29 18:45:02 +08:00
7553dcf405
feat(admin): add database status tab (tables/connections/migration version)
...
get_db_status server function 查 pg_catalog 聚合:数据库总大小/连接数/
表清单(行数估算+大小+死元组)/索引占用 Top10/活跃连接(过滤自身)/迁移版本。
前端 DbStatusTab:概览卡片 + 表/索引/连接表格 + 刷新按钮 + 自动刷新开关
(1s/2s/5s/30s/手动,默认手动;wasm 端用 web_sys setTimeout 轮询,无新依赖)。
2026-06-29 18:36:08 +08:00
81a4196e43
feat(admin): add /admin/system route shell with 5 tabs
...
新增系统管理入口页(数据库状态/服务器状态/SQL 控制台/导出/备份恢复),
顶部 tab 切换(用 use_signal 不深链)。路由注册 + 导航加「系统」项。
tab 内容待后续 task 填充。
2026-06-29 18:26:24 +08:00
c74e59485d
feat(editor): add codemirror-editor subproject + Rust bridge
...
新建 libs/codemirror-editor(pnpm/Vite IIFE/@catppuccin/codemirror Catppuccin
Latte+Mocha 主题/@codemirror/lang-sql schema 补全/@replit/codemirror-vim),
输出 public/codemirror/。Rust 桥接 codemirror_bridge.rs 镜像 tiptap_bridge.rs
(Reflect::get 取对象字面量 + EditorHandle 持有闭包 + Drop→destroy)。
接入 Makefile/Dioxus.toml/.gitignore。
注意:thememirror 不含 catppuccin 主题,改用官方 @catppuccin/codemirror@1.0.3
(导出 catppuccinLatte/catppuccinMocha)。
2026-06-29 18:24:38 +08:00
2776d39ac1
chore: remove unused docs/superpowers directory
CI / check (push) Failing after 4m37s
CI / build (push) Has been skipped
2026-06-29 16:19:17 +08:00
b309f2dbc1
chore: release v0.3.0
...
CI / check (push) Failing after 4m42s
CI / build (push) Has been skipped
Comment system, post trash, View Transitions theme animation, Tiptap image
upload coordinator, blur-up progressive images, lightbox & yggdrasil-core
subprojects, session/CSRF hardening, image Cache-Control/ETag, Dockerfile,
Gitea Actions CI, plus numerous performance and security improvements.
v0.3.0
2026-06-29 16:12:18 +08:00
74992d272f
docs(deployment): uncomment XFF in nginx example
...
Keep X-Forwarded-For as an active default so the snippet is
copy-paste safe; TRUSTED_PROXY_COUNT=1 relies on the proxy
rewriting XFF, and a commented-out line is easy to miss.
2026-06-29 15:59:54 +08:00
5e4f32f2ab
docs(main): fix misleading APP_BASE_URL comment
...
warn_if_app_base_url_unset() is unconditional—localhost dev also
emits a WARN (per csrf.rs doc). The main.rs side note claimed
localhost stays silent, contradicting the implementation.
2026-06-29 15:59:54 +08:00
62fe87961f
chore(build): add clippy and fix targets to Makefile
CI / check (push) Failing after 5m19s
CI / build (push) Has been skipped
2026-06-29 15:55:51 +08:00
431e6e1db4
fix(lint): resolve clippy warnings in comment_storage tests and trash.rs
...
- comment_storage.rs: group digits consistently (3600_000 → 3_600_000)
- trash.rs: remove unused `use super::*` in test module
2026-06-29 15:54:49 +08:00
48a328f553
feat(admin): add decorative image to tiptap editor with focus-within fade effect
2026-06-29 15:45:24 +08:00
962bef2276
fix(ssr-cache): log generation bump and effective SSR_CACHE_SECS
...
Dioxus 0.7 的增量渲染器把 IncrementalRenderer 封装在 FullstackState 内部
(pub(crate)),应用侧无法拿到句柄调用 invalidate(),世代号机制只是"未来就绪"
状态。实际失效仍依赖 SSR_CACHE_SECS 兜底 TTL,但此前写入路径完全静默,部署者
无法从日志判断"文章已写入、只是 SSR 缓存未失效",易误判成 DB/发布问题。
- bump_global_generation() 增加 info 日志(带 new_generation),诚实说明 Dioxus
0.7 不读取此值、需等 TTL 过期。
- main.rs 启动时打印生效的 SSR_CACHE_SECS(滞后上界),提示可调小缩短滞后。
2026-06-29 15:42:40 +08:00
45811df96e
fix(comments): add md-content class to comment item to fix syntax highlighting and blank line issues
2026-06-29 15:42:08 +08:00
408b29dd9d
feat(assets): add xiantiaoxiaogou decorative image
2026-06-29 15:34:47 +08:00
8855cdd49d
fix(styles): add @source to input.css to ensure tailwind scans rust files
2026-06-29 15:31:37 +08:00
656e35c79f
fix(comments): move decorative image properly inside textarea background layer
2026-06-29 15:20:48 +08:00
0b53e968c1
feat(comments): add decorative image to comment input with focus fade effect
2026-06-29 14:42:03 +08:00
fbd706b198
style: format files and update about page content
...
- Update about page content
- Format code in admin pages, tags, and theme modules
2026-06-29 14:31:04 +08:00
d1b5b8ee4e
fix(ui): suppress unused variable warning for active param in server build
2026-06-29 14:29:45 +08:00
369b4838a3
style: add brightness filter to images in dark mode
CI / check (push) Failing after 5m7s
CI / build (push) Has been skipped
2026-06-29 14:16:44 +08:00
ae770cae3a
feat(ui): use EmptyState component for search no results
2026-06-29 14:14:03 +08:00
23f0cc6222
fix(ui): adjust search placeholder size and position
2026-06-29 14:10:21 +08:00
b366c00e74
fix(ui): enlarge and better center search placeholder image
2026-06-29 14:07:35 +08:00
b666472193
fix(ui): add margin between post count and list in tag detail page
2026-06-29 14:05:47 +08:00
3ade2569df
chore(assets): add new empty state image for search page
2026-06-29 14:03:10 +08:00
40114b603c
fix(css): remove redundant .dark .blur-img causing grey background on loaded images
2026-06-29 14:00:08 +08:00
3f7d112898
feat(pages): add empty placeholder image to search page
2026-06-29 13:55:08 +08:00
528a79fb83
feat(pages): add empty state to tags and tag detail pages
2026-06-29 13:50:05 +08:00
373498870a
style: apply cargo fmt to workspace
CI / check (push) Failing after 5m35s
CI / build (push) Has been skipped
2026-06-29 13:47:40 +08:00
5e1becf116
fix(admin): explicitly set pointer-events auto for trash settings panel to resolve click bug
2026-06-29 13:46:05 +08:00
ef8af77a08
style(admin): format trash.rs
2026-06-29 13:42:29 +08:00
fdaefae027
test: fix test_auto_purge_settings_has_transition_class false positive
2026-06-29 13:37:59 +08:00
768dbc9510
feat(admin): add smooth slide-down animation to trash auto-purge settings panel
2026-06-29 13:34:43 +08:00
a47a5a6ac9
feat(admin): update empty state for trash page
2026-06-29 13:26:45 +08:00
c69a632e75
fix(ui): trigger FilterTabs indicator animation on click
2026-06-29 13:24:52 +08:00
3daa09efc2
fix(ui): fix WASM compilation error in FilterTabs indicator animation
2026-06-29 13:22:22 +08:00
ec5f933191
feat(ui): add smooth sliding animation to FilterTabs active indicator
2026-06-29 13:20:39 +08:00
d91a56f8b2
refactor(admin): extract comments filter tabs into FilterTabs component
2026-06-29 13:15:50 +08:00
79af7d345e
fix(admin): 修复重建内容后标题行纵向错位
...
点击「重建内容 / 重建全部」后,结果消息撑高了 RebuildCacheBar,外层
header 的 items-center 据此重新居中,把「文章管理」标题与「+ 写文章」按钮
整体下移,而重建按钮停在容器顶部,造成三者不再同处一行。
根因:c024de1 抽取 RebuildCacheBar 时把结果消息纳入子组件的 flex-col 文档流
(重构前消息是页面级兄弟节点,不参与 header 居中计算)。
修复:根容器改 relative,结果消息用 absolute 悬挂于按钮行下方、脱离文档流,
组件盒高恒等于按钮行高度,无论消息是否出现都不影响 header 的垂直居中。
验证:dx check + cargo clippy 全绿。
2026-06-29 11:49:28 +08:00
a1aef5bda9
fix(admin): add cursor-pointer to comment status filter buttons
2026-06-29 11:41:52 +08:00
dbe95f1173
feat(admin): use global EmptyState component in comments management page
2026-06-29 11:39:32 +08:00
72d21c6670
feat(admin): use global EmptyState component in posts management page
2026-06-29 11:38:50 +08:00
46e9a29f1e
fix(theme): 消除 ThemeToggle 在 wasm/server 构建的 unused_mut 警告
...
CI / check (push) Failing after 6m25s
CI / build (push) Has been skipped
dx build 的 wasm target 报两条 unused_mut:
- theme (160行): wasm 端的 theme.set 被非 wasm cfg 分支剥离,写操作转移
到副本 theme_clone,theme 本身在 wasm 下只被读取/Copy。加
#[cfg_attr(target_arch = "wasm32", allow(unused_mut))]——仅 wasm 端压住,
server 端仍需 mut(theme.set(next) 实际存在)。
- gen_clone (191行): 闭包内只读 gen_clone(),从未 set,两端都不需 mut,
直接删除。
顺带把原来无条件挂在 click_gen 上的 #[allow(unused_mut)] 改成
#[cfg_attr(not(target_arch = "wasm32"), ...)]——click_gen 只在 wasm 分支被
set(189行),server 端该分支被剥离。改为按 cfg 方向标注,与 theme 对称,
语义更精确(不再无差别压住 wasm 端的检查)。
匹配项目既定模式(post_cover.rs:20 的 cfg_attr allow)。零行为变更,
dx check / cargo check(双 target) / clippy / theme 测试均通过。
2026-06-29 11:31:57 +08:00
b923851284
docs(main): 注明 CompressionLayer 默认跳过 image/*
...
CI / check (push) Failing after 5m37s
CI / build (push) Has been skipped
避免后续误以为压缩层会对 WebP/PNG/JPEG 等已是压缩格式的图片再次
压缩而浪费 CPU。tower-http 的 DefaultPredicate 开箱即跳过 image/*
(例外 image/svg+xml)、gRPC、SSE 及 <32 字节响应,无需额外配置。
纯文档性注释,无行为变更。
2026-06-29 11:16:30 +08:00
74f8c212f6
feat(csrf): warn at startup when APP_BASE_URL is unset
...
APP_BASE_URL 未设置时 trusted_origin 回退到请求 Host 头推导本站 origin,
反向代理后若 Host 头可被客户端影响存在 CSRF 绕过风险。.env.example 虽然
警告了,但默认值就是空——'cp .env.example .env 后忘改' 是最常见的部署失误。
加启动时一次性 WARN(与 image.rs 的启动告警同范式):
- warn_if_app_base_url_unset() 在 main.rs 启动序列调用,与 validate_database_url
等配置告警归在一处
- 抽出纯函数 app_base_url_is_set() 承载判断逻辑,便于测试,打日志副作用与之解耦
- 5 个单测覆盖 unset/empty/whitespace/set/trim 边界
每请求路径的 trusted_origin 保持纯函数不变,不引入 dedup 状态或刷屏风险。
2026-06-29 11:02:58 +08:00
c237007111
docs: add production deployment guide
...
服务端的安全逻辑(会话 Cookie Secure 标志、限流按真实客户端 IP 聚合、
CSRF origin 校验)都默认前置反向代理并终结 TLS,但缺少一份成体系的部署
文档说明这一点。不知情的部署者直接把 3000 端口暴露到公网 HTTP 会同时踩中
cookie 无 Secure、限流退化/可伪造、CSRF Host 回退可绕过三个坑。
新增 docs/DEPLOYMENT.md:
- 醒目的前置警告,禁止裸暴露 3000 端口到公网 HTTP
- nginx + Caddy 最小配置示例(含 XFF 覆写、body 上限对齐应用侧 10 MiB、
代理超时对齐应用侧 300s)
- 生产环境必设变量三件套及 TRUSTED_PROXY_COUNT 设错的两种后果
- Docker 部署示例(绑定回环地址,反代作为唯一公网入口)
- 部署后验证清单
README 加「生产部署」节链接到该文档。代码无需修改——三个环境变量的保守
默认值与 .env.example 的警告注释设计上是正确的,缺口纯粹是文档。
2026-06-29 10:55:24 +08:00
8ec4ecd310
chore: migrate JS subprojects from npm to pnpm
...
CI / check (push) Failing after 4m41s
CI / build (push) Has been skipped
Switch tiptap-editor, lightbox, and yggdrasil-core from npm to pnpm.
Replace package-lock.json with pnpm-lock.yaml and update Makefile accordingly.
2026-06-29 10:35:04 +08:00