feat: v2 refactor - migrate to Hertz backend and Vue 3 frontend#22
feat: v2 refactor - migrate to Hertz backend and Vue 3 frontend#22zy84338719 merged 7 commits intomainfrom
Conversation
BREAKING CHANGE: Complete project restructure ## What's Changed ### Backend (Go + Hertz) - Migrate from Gin to CloudWeGo Hertz framework - Use Protocol Buffers (proto3) for API definition - Implement all core APIs: - Admin: login, stats, files, users, config, storage, maintenance - User: register, login, files, api-keys, profile - Share: text/file share, download, preview - Chunk: init/upload/complete/cancel with resume support - QR Code generation and retrieval - Health checks and setup initialization ### Frontend (Vue 3 + TypeScript) - Migrate to Vue 3 with Composition API - Use TypeScript for type safety - Vite for fast development and building - Element Plus UI components - All pages: home, share, admin, user ### Security - JWT authentication (HS256, 24h expiry) - API Key support (fcb_sk_xxx format, SHA256 hash storage) - Rate limiting middleware - CORS configuration ### Infrastructure - Docker multi-stage build - docker-compose configuration - Updated Makefile for build automation - SQLite/MySQL/PostgreSQL support (default SQLite) ## Deleted - Old Gin-based monolithic code (main.go, internal/, cmd/, tests/) - Old configuration system - Old Docker configuration ## Migration Guide 1. Build: make build 2. Run: ./backend/bin/server 3. Default port: 12346 4. First run will create admin user (admin/admin123) Co-authored-by: Wednesday AI Assistant <wednesday@openclaw.ai>
There was a problem hiding this comment.
Pull request overview
This PR is a v2 breaking refactor that restructures the project and migrates the backend to CloudWeGo Hertz (IDL/proto-driven) and the frontend to Vue 3 + TypeScript, with Docker/Makefile updates for the new build/deploy workflow.
Changes:
- Introduces proto-based IDL definitions and Hz/Kitex generation layout (
backend/idl,backend/biz,backend/gen) with new Hertz routers/handlers. - Adds configuration templates, bootstrap/server entrypoint, and multi-stage Docker builds for frontend+backend.
- Updates root docs and build tooling to match the new split
frontend/+backend/architecture.
Reviewed changes
Copilot reviewed 85 out of 428 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/idl/http/README.md | Documents HTTP IDL layout, examples, and generation commands. |
| backend/idl/common.proto | Adds common HTTP endpoints/services in proto. |
| backend/idl/api/api.proto | Defines Hz HTTP annotation extensions (proto2). |
| backend/idl/README.md | Documents IDL structure and code generation entry points. |
| backend/go.mod | Introduces backend Go module and dependencies for Hertz/GORM/etc. |
| backend/gen/rpc/README.md | Documents Kitex-generated RPC code layout and usage. |
| backend/gen/README.md | Documents generated-code directory rules and responsibilities. |
| backend/docs/README.md | Adds placeholder documentation structure for backend docs. |
| backend/configs/config.yaml | Adds default/dev YAML configuration template. |
| backend/configs/config.prod.yaml | Adds production configuration template and guidance. |
| backend/configs/README.md | Documents configuration conventions and env overrides. |
| backend/cmd/server/main.go | Adds Hertz server entry with graceful shutdown. |
| backend/cmd/server/bootstrap/bootstrap.go | Adds bootstrap: config/log/db/migrate/default admin/preview init and route registration. |
| backend/cmd/server/bootstrap/README.md | Documents bootstrap responsibilities and init order. |
| backend/cmd/server/README.md | Documents server entrypoint usage and run modes. |
| backend/build.sh | Adds a simple build script for producing a binary. |
| backend/biz/router/user/user.go | Hz-generated user route registrations. |
| backend/biz/router/user/middleware.go | Adds auth middleware wiring for user endpoints. |
| backend/biz/router/storage/storage.go | Hz-generated storage admin route registrations. |
| backend/biz/router/storage/middleware.go | Placeholder middleware hooks for storage routes. |
| backend/biz/router/share/share.go | Hz-generated share route registrations. |
| backend/biz/router/share/middleware.go | Wires optional auth for share endpoints. |
| backend/biz/router/setup/setup.go | Hz-generated setup/init route registrations. |
| backend/biz/router/setup/middleware.go | Placeholder middleware hooks for setup routes. |
| backend/biz/router/register.go | Central generated router registration aggregator. |
| backend/biz/router/qrcode/qrcode.go | Hz-generated QR code route registrations. |
| backend/biz/router/qrcode/middleware.go | Placeholder middleware hooks for QR routes. |
| backend/biz/router/preview/preview.go | Registers preview endpoint routing. |
| backend/biz/router/health/middleware.go | Placeholder middleware hooks for health routes. |
| backend/biz/router/health/health.go | Hz-generated health route registrations. |
| backend/biz/router/chunk/middleware.go | Placeholder middleware hooks for chunk routes. |
| backend/biz/router/chunk/chunk.go | Hz-generated chunk upload route registrations. |
| backend/biz/router/admin/middleware.go | Wires admin auth middleware for admin routes. |
| backend/biz/router/admin/maintenance.go | Hz-generated maintenance route registrations. |
| backend/biz/router/admin/admin.go | Hz-generated admin route registrations. |
| backend/biz/model/setup/setup.pb.go | Generated protobuf models for setup endpoints. |
| backend/biz/model/qrcode/qrcode.pb.go | Generated protobuf models for QR code endpoints. |
| backend/biz/model/api/api.pb.go | Generated protobuf code for Hz annotation extensions. |
| backend/biz/handler/user/user_service.go | Implements user handlers (register/login/info/files/api-keys). |
| backend/biz/handler/storage/storage/storage_service.go | Implements storage admin handlers and proto↔service conversions. |
| backend/biz/handler/setup/setup_service.go | Implements setup initialization/check endpoints. |
| backend/biz/handler/qrcode/qrcode/qrcode_service.go | Implements QR generation + retrieval using an in-memory store. |
| backend/biz/handler/preview/preview_service.go | Implements preview retrieval + on-demand generation and persistence. |
| backend/biz/handler/ping.go | Adds a simple ping handler. |
| backend/biz/handler/health/health_service.go | Implements health/readiness/liveness/version endpoints. |
| backend/biz/handler/admin/share/share_service.go | Adds admin share handler stubs (generated). |
| backend/biz/handler/admin/maintenance/setup/setup_service.go | Adds maintenance setup handler stubs (generated). |
| backend/biz/handler/admin/maintenance/admin/maintenance_service.go | Implements maintenance endpoints via internal admin service. |
| backend/biz/handler/admin/admin_service.go | Implements admin login + includes multiple admin endpoint stubs and some maintenance endpoints. |
| backend/biz/handler/admin/admin/admin_service.go | Adds another set of admin handler stubs (generated). |
| backend/biz/handler.bak/user/user_service.go | Adds backup copy of user handlers (duplicate tree). |
| backend/biz/handler.bak/storage/storage/storage_service.go | Adds backup copy of storage handlers (duplicate tree). |
| backend/biz/handler.bak/setup/setup_service.go | Adds backup copy of setup handlers (duplicate tree). |
| backend/biz/handler.bak/qrcode/qrcode/qrcode_service.go | Adds backup copy of QR handlers (duplicate tree). |
| backend/biz/handler.bak/preview/preview_service.go | Adds backup copy of preview handlers (duplicate tree). |
| backend/biz/handler.bak/ping.go | Adds backup copy of ping handler. |
| backend/biz/handler.bak/admin/share/share_service.go | Adds backup copy of admin share handler stubs. |
| backend/biz/handler.bak/admin/maintenance/setup/setup_service.go | Adds backup copy of maintenance setup stubs. |
| backend/biz/handler.bak/admin/maintenance/admin/maintenance_service.go | Adds backup copy of maintenance implementation. |
| backend/biz/handler.bak/admin/admin_service.go | Adds backup copy of admin handler implementation/stubs. |
| backend/biz/handler.bak/admin/admin/admin_service.go | Adds backup copy of nested admin stubs. |
| backend/README.md | Adds backend-specific README focused on codegen scaffolding. |
| backend/Makefile | Adds backend Makefile for build/run/codegen/tool install. |
| backend/Dockerfile | Adds backend Dockerfile building frontend+backend and running server with config mount. |
| backend/.hz.qrcode | Hz generator config for qrcode service. |
| backend/.hz | Hz generator config (currently pointing at qrcode dirs). |
| backend/.gitignore | Adds backend gitignore patterns. |
| admin-test.html | Removes a standalone admin API test HTML page. |
| TODO-REFACTOR-20260311.md | Adds refactor task tracking doc with status matrix. |
| README.md | Updates root README to v2 architecture and new commands/endpoints. |
| Makefile | Updates root build to include frontend+backend build steps and Docker packaging. |
| Dockerfile | Updates root Dockerfile to multi-stage build frontend+backend and run port 12346. |
| API-COMPARISON.md | Adds API completeness comparison report vs the old project. |
| // Bootstrap 应用程序启动入口 | ||
| func Bootstrap() (*server.Hertz, error) { | ||
| // 1. 初始化配置 | ||
| var err error | ||
| config, err = InitConfig("./conf/config.yaml") | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to init config: %w", err) | ||
| } | ||
|
|
||
| // 设置全局配置(供其他包访问) | ||
| conf.SetGlobalConfig(config) |
There was a problem hiding this comment.
Bootstrap hardcodes ./conf/config.yaml, but this repo introduces config files under backend/configs/ and both Dockerfiles/READMEs suggest passing a config path at runtime. This will cause the server to ignore the provided config and often fail to find the file. Read config path from a flag (e.g. --config) and/or env var (e.g. CONFIG_PATH), and keep the default path consistent with backend/configs/config.yaml.
| ENV TZ=Asia/Shanghai | ||
|
|
||
| # Run the server | ||
| CMD ["./server", "--config", "./config/config.yaml"] |
There was a problem hiding this comment.
The container runs ./server --config ..., but cmd/server/main.go + bootstrap.Bootstrap() don’t parse CLI args, and bootstrap currently uses a hardcoded path. Either add flag parsing in main.go and pass the path into bootstrap.InitConfig, or remove the unused --config args and ensure the hardcoded path matches the image layout.
| CMD ["./server", "--config", "./config/config.yaml"] | |
| CMD ["./server"] |
| updateReq.Config.StoragePath = req.Config.StoragePath | ||
| updateReq.Config.WebDAV = convertFromProtoWebDAVConfig(req.Config.Webdav) | ||
| updateReq.Config.S3 = convertFromProtoS3Config(req.Config.S3) | ||
| updateReq.Config.NFS = convertFromProtoNFSConfig(req.Config.Nfs) |
There was a problem hiding this comment.
updateReq.Config is dereferenced without being initialized, which will panic whenever req.Config != nil. Initialize updateReq.Config (or make it a non-nil value in UpdateConfigRequest) before assigning its fields.
| updateReq.Config.StoragePath = req.Config.StoragePath | |
| updateReq.Config.WebDAV = convertFromProtoWebDAVConfig(req.Config.Webdav) | |
| updateReq.Config.S3 = convertFromProtoS3Config(req.Config.S3) | |
| updateReq.Config.NFS = convertFromProtoNFSConfig(req.Config.Nfs) | |
| // 初始化 Config 以避免空指针 | |
| updateReq.Config = &storagesvc.StorageConfig{ | |
| StoragePath: req.Config.StoragePath, | |
| WebDAV: convertFromProtoWebDAVConfig(req.Config.Webdav), | |
| S3: convertFromProtoS3Config(req.Config.S3), | |
| NFS: convertFromProtoNFSConfig(req.Config.Nfs), | |
| } |
| // QRCodeStore 存储生成的二维码(内存存储) | ||
| var QRCodeStore = make(map[string]*StoredQRCode) |
There was a problem hiding this comment.
Handlers run concurrently; reading/writing a plain Go map without synchronization can panic with concurrent map read and map write. Protect QRCodeStore with a sync.RWMutex (or use sync.Map) and consider adding TTL/eviction to avoid unbounded memory growth.
| // 存储二维码数据 | ||
| QRCodeStore[id] = &StoredQRCode{ | ||
| ID: id, | ||
| Data: pngData, | ||
| DataStr: req.Data, | ||
| Size: size, | ||
| } |
There was a problem hiding this comment.
Handlers run concurrently; reading/writing a plain Go map without synchronization can panic with concurrent map read and map write. Protect QRCodeStore with a sync.RWMutex (or use sync.Map) and consider adding TTL/eviction to avoid unbounded memory growth.
| // 创建默认管理员 | ||
| admin := &model.User{ | ||
| Username: "admin", | ||
| Email: "admin@filecodebox.local", | ||
| PasswordHash: "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZRGdjGj/n3.rsQ5pPjZ5yVlWK5WAe", // password: admin123 | ||
| Nickname: "Administrator", | ||
| Role: "admin", | ||
| Status: "active", | ||
| } |
There was a problem hiding this comment.
Creating a well-known default admin (admin/admin123) on boot is a serious security risk if this code ever reaches a public environment. Prefer creating the admin only via the /setup initialization flow, or generate a one-time random password/token (printed once to logs) and require password change on first login.
| return fmt.Errorf("failed to create admin user: %w", err) | ||
| } | ||
|
|
||
| log.Println("Default admin user created (username: admin, password: admin123)") |
There was a problem hiding this comment.
Creating a well-known default admin (admin/admin123) on boot is a serious security risk if this code ever reaches a public environment. Prefer creating the admin only via the /setup initialization flow, or generate a one-time random password/token (printed once to logs) and require password change on first login.
| user_storage_quota: 1073741824 # 1GB | ||
| session_expiry_hours: 168 # 7天 | ||
| max_sessions_per_user: 5 | ||
| jwt_secret: "FileCodeBox2025JWT" |
There was a problem hiding this comment.
Shipping a fixed default jwt_secret encourages insecure deployments (many instances will share the same signing key). Consider leaving this empty in the default config (or using a placeholder), and require it be provided via env/secret management (or generate and persist a random secret on first run).
| jwt_secret: "FileCodeBox2025JWT" | |
| jwt_secret: "" # MUST be set via environment/secret management for production |
|
|
||
| package common; | ||
|
|
||
| option go_package = "common"; |
There was a problem hiding this comment.
option go_package = \"common\" is likely to cause generated code import/path issues (non-module-qualified package path, easy to collide, and may not match your module layout). Set go_package to the fully-qualified module path that matches where generated code should live (e.g., under github.com/zy84338719/fileCodeBox/...).
| option go_package = "common"; | |
| option go_package = "github.com/zy84338719/fileCodeBox/backend/idl/common"; |
| # 编译后端 | ||
| RUN CGO_ENABLED=1 go build \ | ||
| -ldflags="-w -s \ | ||
| -X 'github.com/zy84338719/fileCodeBox/internal/models/service.Version=${VERSION}' \ | ||
| -X 'github.com/zy84338719/fileCodeBox/internal/models/service.GitCommit=${COMMIT}' \ | ||
| -X 'github.com/zy84338719/fileCodeBox/internal/models/service.BuildTime=${BUILD_TIME}'" \ | ||
| -o bin/server ./cmd/server |
There was a problem hiding this comment.
This Dockerfile builds with CGO_ENABLED=1 but the runtime stage is a minimal Alpine image; if the binary ends up dynamically linked, it may fail at runtime due to missing libs. Unless CGO is required, prefer CGO_ENABLED=0 for a fully static binary (and keep consistent with backend/Dockerfile which already does that).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f3cc2ab29
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| func Bootstrap() (*server.Hertz, error) { | ||
| // 1. 初始化配置 | ||
| var err error | ||
| config, err = InitConfig("./conf/config.yaml") |
There was a problem hiding this comment.
Load server config from deployed config path
Bootstrap() hard-codes InitConfig("./conf/config.yaml") in backend/cmd/server/bootstrap/bootstrap.go:133, but this commit’s container wiring mounts config under /app/config (backend/Dockerfile:60,69 and docker-compose.yml:17). Because InitConfig only logs read failures and continues with defaults, deployments silently ignore operator config (including port), which makes the compose healthcheck on :8888 fail against the actual listener.
Useful? React with 👍 / 👎.
| const ( | ||
| defaultMaxUploadSize = 10485760 // 10MB | ||
| defaultStoragePath = "./data/uploads" | ||
| defaultBaseURL = "http://localhost:12345" |
There was a problem hiding this comment.
Build share URLs from runtime base_url config
The share handler bakes in defaultBaseURL = "http://localhost:12345" and uses it to generate response URLs, so users receive localhost links whenever the service runs behind another domain/port. Since this bypasses the loaded server configuration, share links are incorrect in non-default deployments and break client navigation outside local dev.
Useful? React with 👍 / 👎.
| func customizedRegister(r *server.Hertz) { | ||
| // 这里可以添加自定义路由,现在为空,所有的路由都通过 GeneratedRegister 注册 | ||
| } |
There was a problem hiding this comment.
Register static frontend routes in bootstrap server
The production entrypoint (cmd/server/main.go) depends on Bootstrap(), but customizedRegister is empty here, so only generated API routes are exposed; no handler serves / or SPA fallbacks. In this same commit the runtime image copies frontend assets into /app/static (backend/Dockerfile:57), so the bundled UI becomes unreachable when running the shipped server binary.
Useful? React with 👍 / 👎.
- 修复CI workflow中Go缓存路径指向backend/go.sum - 添加working-directory: backend到Go相关命令 - 修复golangci-lint使用install-mode: go解决Go版本兼容问题 - 修复coverage文件路径 - 统一所有服务端口为12345(Dockerfile、docker-compose、bootstrap.go、文档)
- 升级golangci-lint到v2.11.3以支持Go 1.25 - 移除biz/handler.bak目录避免编译错误
- 升级golangci-lint-action@v6到v7以支持golangci-lint v2 - 修复biz/handler/admin/maintenance中的类型引用从admin改为maintenance包 - 运行go fmt格式化代码
…_package - Remove legacy biz/ directory, migrate all generated code to gen/http/ - Split maintenance.proto into independent go_package=maintenance - Fix .hz routerDir config to point to gen/http/router - Add gen/http/handler/maintenance and gen/http/router/maintenance packages - Fix duplicate /health route registration in common router - Update register.go to include maintenance.Register - Fix admin_service.go duplicate function declarations
Summary
BREAKING CHANGE: Complete project restructure
Backend (Go + CloudWeGo Hertz)
Frontend (Vue 3 + TypeScript)
Security
Infrastructure
Deleted
Migration Guide
Test Plan