doc: update backend doc
This commit is contained in:
+38
-39
@@ -1,70 +1,69 @@
|
||||
# coconut-leaf 后端
|
||||
# coconut-leaf Backend
|
||||
|
||||
coconut-leaf 的后端服务,使用 [Go](https://go.dev/) + [Gin](https://gin-gonic.com/) 实现,由旧版 Python Flask 后端迁移而来。
|
||||
数据层直接执行 SQL(不使用 ORM),目前仅完整实现 SQLite,MySQL 接口为占位实现(全部接口返回 not implemented 错误)。
|
||||
The backend service of coconut-leaf,
|
||||
implemented with [Go](https://go.dev/) + [Gin](https://gin-gonic.com/),
|
||||
migrated from the old Python Flask backend.
|
||||
The data layer executes SQL directly (no ORM).
|
||||
|
||||
## 环境要求
|
||||
> [!NOTE]
|
||||
> Currently only SQLite is fully implemented.
|
||||
> MySQL interfaces are placeholders (all endpoints return "not implemented" errors).
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Go >= 1.26**
|
||||
- **C 编译器(cgo)**:SQLite 驱动 [`mattn/go-sqlite3`](https://github.com/mattn/go-sqlite3) 依赖 cgo。
|
||||
- Windows:推荐使用 MSYS2 的 gcc。
|
||||
- Linux / macOS:系统自带的 gcc / clang 即可。
|
||||
- 构建前确保 `CGO_ENABLED=1`(有可用 C 编译器时通常默认开启)。
|
||||
- **C compiler (cgo)**: The SQLite driver [`mattn/go-sqlite3`](https://github.com/mattn/go-sqlite3) requires CGO feature.
|
||||
- Windows: MSYS2's gcc is recommended.
|
||||
- Linux / macOS: System-provided gcc / clang works.
|
||||
- Ensure `CGO_ENABLED=1` before building (usually enabled by default when a C compiler is available).
|
||||
|
||||
## 构建
|
||||
## Build
|
||||
|
||||
在 `backend/` 目录下:
|
||||
In the `backend/` directory:
|
||||
|
||||
```sh
|
||||
go build -o coconut-leaf
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> 首次构建会编译 SQLite 的 C 源,耗时 1–3 分钟属正常。
|
||||
>
|
||||
> 在 Windows 下用 MSYS2 编译出的可执行文件在运行时依赖 MSYS2 相关运行库(我这里是MSYS2 UCRT64,所以可能包含 `libgcc_s_*`、`libwinpthread-1.dll` 等)。
|
||||
> 需让这些DLL所在文件夹处于 PATH 中,或将这些 DLL 拷贝到可执行文件旁。
|
||||
> The first build compiles SQLite C source code; 1–3 minutes is normal.
|
||||
>
|
||||
> On Windows, executables built with MSYS2 depend on MSYS2 runtime libraries
|
||||
> (I use MSYS2 UCRT64, so it may include `libgcc_s_*`, `libwinpthread-1.dll`, etc.).
|
||||
> Either add the DLL directory to PATH or copy those DLLs next to the executable.
|
||||
|
||||
## 配置文件
|
||||
## Configuration
|
||||
|
||||
采用 TOML 格式,通过 `--config` 指定路径。完整模板见 `assets` 文件夹下的 [coconut-leaf.template.toml](../assets/coconut-leaf.template.toml)。
|
||||
Uses TOML format, specified via `-config` parameter.
|
||||
See the full template at [coconut-leaf.template.toml](../assets/coconut-leaf.template.toml) in the `assets` directory.
|
||||
|
||||
字段说明:
|
||||
## Command-line Arguments
|
||||
|
||||
| 字段 | 含义 |
|
||||
| Argument | Description |
|
||||
| --- | --- |
|
||||
| `database.driver` | `"sqlite"` 或 `"mysql"` |
|
||||
| `database.config.path` | SQLite 数据库文件路径 |
|
||||
| `database.config.{host,port,user,password,database}` | MySQL 连接参数(未实现) |
|
||||
| `web.port` | HTTP 监听端口 |
|
||||
| `others.debug` | 调试模式(生产环境请务必设置为false) |
|
||||
| `others.auto-token-clean-duration` | 过期 token 自动清理间隔(秒) |
|
||||
| `-config <PATH>` | **Required**, path to the TOML configuration file |
|
||||
| `-init` | Initialize the system: create tables and the first admin user |
|
||||
| `-username <NAME>` | Used with `-init`, the initial admin username |
|
||||
| `-password <PASS>` | Used with `-init`, the initial admin password |
|
||||
|
||||
## 命令行参数
|
||||
`-username` / `-password` are required only when `-init` is specified and are validated
|
||||
(username: `[0-9A-Za-z]+`, password: all visible ASCII characters, i.e., `[!-~]+`).
|
||||
|
||||
| 参数 | 说明 |
|
||||
| --- | --- |
|
||||
| `--config <PATH>` | **必填**,配置文件(TOML)路径 |
|
||||
| `--init` | 初始化系统:建表并创建首个管理员用户 |
|
||||
| `--username <NAME>` | 与 `--init` 配合,初始管理员的用户名 |
|
||||
| `--password <PASS>` | 与 `--init` 配合,初始管理员的密码 |
|
||||
## Initialization and Runtime
|
||||
|
||||
`--username` / `--password` 仅在 `--init` 时必填,并会做格式校验(用户名为 `[0-9A-Za-z]+`,密码为所有可见 ASCII 字符,即 `[!-~]+`)。
|
||||
### First Deployment
|
||||
|
||||
## 初始化与运行
|
||||
|
||||
### 首次部署
|
||||
|
||||
首次部署包括:建表 + 创建管理员,随后如日常运行一般:
|
||||
First deployment includes creating tables and the admin user, then running as usual:
|
||||
|
||||
```sh
|
||||
./coconut-leaf --config coconut-leaf.toml --init --username admin --password "your-password"
|
||||
```
|
||||
|
||||
### 日常运行
|
||||
### Normal Runtime
|
||||
|
||||
```sh
|
||||
./coconut-leaf --config coconut-leaf.toml
|
||||
```
|
||||
|
||||
启动后会在 `web.port` 监听。调试日志会输出到 stderr,格式为 `[<时间>] [<级别>] <消息> [key=value ...]`。
|
||||
After starting, it listens on `web.port`.
|
||||
Debug logs are written to stderr in the format `[<time>] [<level>] <message> [key=value ...]`.
|
||||
|
||||
+8
-8
@@ -13,14 +13,14 @@ type CLIArgs struct {
|
||||
Config string
|
||||
// Init indicates whether to initialize the calendar system before running.
|
||||
Init bool
|
||||
// Username is the first admin user's name; required together with --init.
|
||||
// Username is the first admin user's name; required together with -init.
|
||||
Username string
|
||||
// Password is the first admin user's password; required together with --init.
|
||||
// Password is the first admin user's password; required together with -init.
|
||||
Password string
|
||||
}
|
||||
|
||||
// Parse parses the command-line arguments via the standard flag package and
|
||||
// returns a *CLIArgs. When the required --config flag is missing, it prints the
|
||||
// returns a *CLIArgs. When the required -config flag is missing, it prints the
|
||||
// usage and exits with status 2 (matching argparse's exit code).
|
||||
func Parse() *CLIArgs {
|
||||
args := &CLIArgs{}
|
||||
@@ -34,19 +34,19 @@ func Parse() *CLIArgs {
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
// --config maps to the legacy -c/--config (required), --init to -i/--init.
|
||||
// --username/--password replace the legacy interactive GetUsernamePassword
|
||||
// -config maps to the legacy -c/--config (required), -init to -i/--init.
|
||||
// -username/-password replace the legacy interactive GetUsernamePassword
|
||||
// prompt and are required together with --init.
|
||||
flag.StringVar(&args.Config, "config", "", "The configuration file `CONFIG_TOML` for coconut-leaf")
|
||||
flag.BoolVar(&args.Init, "init", false, "Set for initialize the calendar system")
|
||||
flag.StringVar(&args.Username, "username", "", "The first admin user's name (required with --init)")
|
||||
flag.StringVar(&args.Password, "password", "", "The first admin user's password (required with --init)")
|
||||
flag.StringVar(&args.Username, "username", "", "The first admin user's name (required with -init)")
|
||||
flag.StringVar(&args.Password, "password", "", "The first admin user's password (required with -init)")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
// The standard flag package has no built-in "required", so validate manually.
|
||||
if args.Config == "" {
|
||||
fmt.Fprintln(os.Stderr, "error: the required flag --config is not provided")
|
||||
fmt.Fprintln(os.Stderr, "error: the required flag -config is not provided")
|
||||
flag.Usage()
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user