diff --git a/.cloud-dev/entrypoint.sh b/.cloud-dev/entrypoint.sh index a329809..e7b3bb6 100644 --- a/.cloud-dev/entrypoint.sh +++ b/.cloud-dev/entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/bash # ============================================ -# 文件持久化:通过符号链接将零碎文件持久化到命名卷 +# 文件持久化:启动时恢复 + 后台定期同步到命名卷 # ============================================ PERSIST_DIR="/root/.hair-keeper-persist" PERSIST_FILES=( @@ -12,22 +12,29 @@ PERSIST_FILES=( mkdir -p "$PERSIST_DIR" +# 启动时恢复:持久化目录中的文件优先覆盖到原路径 for filepath in "${PERSIST_FILES[@]}"; do filename=$(basename "$filepath") persist_path="$PERSIST_DIR/$filename" - - # 如果原路径是真实文件(非符号链接),迁移到持久化目录 - if [ -f "$filepath" ] && [ ! -L "$filepath" ]; then - mv "$filepath" "$persist_path" + if [ -f "$persist_path" ] && [ -s "$persist_path" ]; then + cp "$persist_path" "$filepath" fi - - # 确保持久化目录中存在该文件 - [ -f "$persist_path" ] || touch "$persist_path" - - # 创建符号链接 - ln -sf "$persist_path" "$filepath" done +# 后台定期同步:将原路径文件同步回持久化目录(每60秒) +( + while true; do + sleep 60 + for filepath in "${PERSIST_FILES[@]}"; do + filename=$(basename "$filepath") + persist_path="$PERSIST_DIR/$filename" + if [ -f "$filepath" ]; then + rsync -a "$filepath" "$persist_path" + fi + done + done +) & + # 设置默认密码 DEV_PASSWORD=${DEV_PASSWORD:-clouddev} @@ -70,5 +77,20 @@ echo "" echo "提示: 可通过环境变量 DEV_PASSWORD 自定义密码" echo "" +# 容器停止时执行最终同步 +cleanup() { + echo "Syncing persistent files before shutdown..." + for filepath in "${PERSIST_FILES[@]}"; do + filename=$(basename "$filepath") + persist_path="$PERSIST_DIR/$filename" + if [ -f "$filepath" ]; then + rsync -a "$filepath" "$persist_path" + fi + done + exit 0 +} +trap cleanup SIGTERM SIGINT + # 保持容器运行 -tail -f /dev/null \ No newline at end of file +tail -f /dev/null & +wait $! \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index cfd394f..3147c2d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,7 +3,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## 项目说明 -本项目模板(Hair Keeper v1.2.0)是一个高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑。 +本项目模板(Hair Keeper v1.3.0)是一个高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证(支持SSO单点登录)、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑。 Hair Keeper是个诙谐有趣的名称,和项目内容毫无关系。 @@ -77,6 +77,8 @@ Hair Keeper是个诙谐有趣的名称,和项目内容毫无关系。 - `src/server/queues/`:消息队列和worker,通过其中的index.ts统一导出,任务状态更新采用trpc SSE subscription,接口定义在`server/routers/jobs.ts`中 - `src/server/agents`:LLM的对接和使用 - `src/server/service/`:服务层模块集合,封装后端业务逻辑和系统服务 +- `src/server/service/session.ts`:会话管理服务,基于Redis实现权限变更后强制重新登录 +- `src/server/service/iaaa.ts`:北京大学统一认证(IAAA)对接服务,通过环境变量配置即可启用 - `src/server/service/dev/`:开发模式下的辅助功能需要的后台服务 - `src/server/utils/`:服务端专用工具函数库,为后端业务逻辑提供基础设施支持 - `src/api/dev/`:开发模式下的辅助功能需要的api diff --git a/README.md b/README.md index b8d25dd..3147c2d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + ## 项目说明 -本项目模板(Hair Keeper v1.2.0)是一个高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑。 +本项目模板(Hair Keeper v1.3.0)是一个高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证(支持SSO单点登录)、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑。 Hair Keeper是个诙谐有趣的名称,和项目内容毫无关系。 @@ -73,6 +77,8 @@ Hair Keeper是个诙谐有趣的名称,和项目内容毫无关系。 - `src/server/queues/`:消息队列和worker,通过其中的index.ts统一导出,任务状态更新采用trpc SSE subscription,接口定义在`server/routers/jobs.ts`中 - `src/server/agents`:LLM的对接和使用 - `src/server/service/`:服务层模块集合,封装后端业务逻辑和系统服务 +- `src/server/service/session.ts`:会话管理服务,基于Redis实现权限变更后强制重新登录 +- `src/server/service/iaaa.ts`:北京大学统一认证(IAAA)对接服务,通过环境变量配置即可启用 - `src/server/service/dev/`:开发模式下的辅助功能需要的后台服务 - `src/server/utils/`:服务端专用工具函数库,为后端业务逻辑提供基础设施支持 - `src/api/dev/`:开发模式下的辅助功能需要的api diff --git a/package.json b/package.json index 3ccde97..45a7de2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hair-keeper", - "version": "1.2.0", + "version": "1.3.0", "private": true, "scripts": { "dev": "next dev -p 3000 --turbo", diff --git a/src/constants/site.ts b/src/constants/site.ts index b175366..0d9c3e0 100644 --- a/src/constants/site.ts +++ b/src/constants/site.ts @@ -3,4 +3,4 @@ */ export const SITE_NAME = 'Hair Keeper' export const SITE_DESCRIPTION = '高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑' -export const SITE_VERSION = 'v1.2.0' \ No newline at end of file +export const SITE_VERSION = 'v1.3.0' \ No newline at end of file