Remove the Go reference server; keep only Rust
CI / Rust (fmt / clippy / test / build) (push) Successful in 1m41s
CI / HTTP/JSON reference + SQLite persistence (push) Successful in 1m16s
CI / Rust (fmt / clippy / test / build) (pull_request) Successful in 47s
CI / HTTP/JSON reference + SQLite persistence (pull_request) Successful in 1m34s
CI / Rust (fmt / clippy / test / build) (push) Successful in 1m41s
CI / HTTP/JSON reference + SQLite persistence (push) Successful in 1m16s
CI / Rust (fmt / clippy / test / build) (pull_request) Successful in 47s
CI / HTTP/JSON reference + SQLite persistence (pull_request) Successful in 1m34s
The Go implementation is preserved in the v1.0.0 tag. Its observable behaviour stays the API reference: responses recorded from the Go server live in tools/compatibility_expected.txt, and tools/compatibility.py now compares the Rust server against them (--update re-records after an intentional change). The Go SQLite schema is frozen in tests/fixtures/go_schema_v1.sql for the existing-database test. Move the web client from internal/httpapi/web to web/, drop the Go CI job and Go version pin, and update README, AGENTS.md and docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
16dd2a3b3c
commit
10272f3851
33 files changed
+890
-1438
No files matched your search
@@ -23,16 +23,9 @@ Android ───────────┘
|
||||
|
||||
## Исходный код
|
||||
|
||||
Production runtime — один Rust-процесс: `src/main.rs`, `runtime.rs`, `config.rs`, `database.rs`, `auth.rs`, `sync.rs`, `server.rs`, `go_json.rs`. SQLite bundled через rusqlite; HTTP обслуживается axum/hyper. `runtime.rs` сохраняет socket deadlines Go (header 5s, read 15s, write 30s, idle 60s) и ограничивает graceful shutdown десятью секундами. `go_json.rs` сохраняет особенности encoding/json и исходные payload bytes. Статические файлы из `internal/httpapi/web` встроены при компиляции. Go-код сохранён как эталон совместимости и вариант rollback.
|
||||
Production runtime — один Rust-процесс: `src/main.rs`, `runtime.rs`, `config.rs`, `database.rs`, `auth.rs`, `sync.rs`, `server.rs`, `go_json.rs`. SQLite bundled через rusqlite; HTTP обслуживается axum/hyper. `runtime.rs` сохраняет socket deadlines Go (header 5s, read 15s, write 30s, idle 60s) и ограничивает graceful shutdown десятью секундами. `go_json.rs` сохраняет особенности encoding/json и исходные payload bytes. Статические файлы из `web/` встроены при компиляции.
|
||||
|
||||
Пути сохранённой Go-реализации:
|
||||
|
||||
```text
|
||||
- internal/auth
|
||||
- internal/config
|
||||
- internal/database
|
||||
- internal/httpapi
|
||||
```
|
||||
Исходная Go-реализация удалена после v1.0.0 (исходники остались в теге `v1.0.0`). Её наблюдаемое поведение зафиксировано в `tools/compatibility_expected.txt`, а SQLite-схема — в `tests/fixtures/go_schema_v1.sql`; Rust сверяется с обоими в CI.
|
||||
|
||||
Конкретные границы package/handler/service/repository нужно сохранять при рефакторинге: перенос кода между слоями не должен менять внешний API.
|
||||
|
||||
|
||||
+5
-20
@@ -2,27 +2,12 @@
|
||||
|
||||
Ниже описана серверная модель на основании исходного кода проекта. При изменении schema обновляйте этот документ.
|
||||
|
||||
## Найденные определения моделей/schema
|
||||
## Где определена schema
|
||||
|
||||
- internal/database/database.go
|
||||
- internal/database/database.go
|
||||
- internal/database/database.go
|
||||
- internal/config/config.go
|
||||
- internal/auth/tokens.go
|
||||
- internal/auth/tokens.go
|
||||
- internal/httpapi/auth_handlers.go
|
||||
- internal/httpapi/auth_handlers.go
|
||||
- internal/httpapi/auth_handlers.go
|
||||
- internal/httpapi/server.go
|
||||
- internal/httpapi/server.go
|
||||
- internal/httpapi/server.go
|
||||
- internal/httpapi/sync_handler.go
|
||||
- internal/httpapi/sync_handler.go
|
||||
- internal/httpapi/sync_handler.go
|
||||
- internal/httpapi/web.go
|
||||
- internal/httpapi/server_test.go
|
||||
- internal/httpapi/server_test.go
|
||||
- internal/httpapi/server_test.go
|
||||
- `src/database.rs` — создание и открытие схемы SQLite;
|
||||
- `tests/fixtures/go_schema_v1.sql` — исходная схема Go-сервера v1.0.0; Rust обязан открывать такие базы без изменений;
|
||||
- `src/sync.rs` — валидация и сериализация синхронизируемых записей;
|
||||
- `src/auth.rs` — пользователи, пароли и refresh-сессии.
|
||||
|
||||
## Общие сущности
|
||||
|
||||
|
||||
+11
-11
@@ -3,9 +3,9 @@
|
||||
## Runtime and configuration
|
||||
|
||||
The production executable is the Rust server, built with `cargo build --locked
|
||||
--release`. SQLite is bundled into the executable. The Go implementation remains
|
||||
in `cmd/balance-server` and `internal/` as a compatibility reference and rollback
|
||||
option; build it with `go build -o balance-server-go ./cmd/balance-server`.
|
||||
--release`. SQLite is bundled into the executable. The original Go implementation
|
||||
was removed after v1.0.0; the `v1.0.0` tag still contains its sources for the
|
||||
migration and rollback below (`go build -o balance-server-go ./cmd/balance-server`).
|
||||
|
||||
The Dockerfile uses a Rust 1.90 Debian Bookworm builder and a Debian Bookworm slim
|
||||
runtime, running as the unprivileged `balance` user. The image embeds the existing
|
||||
@@ -65,8 +65,9 @@ required. Do not start both implementations against the same database at once.
|
||||
Stop Rust first. Start the retained Go executable/image with the same current
|
||||
database directory and secret. Rust-written accounts, password hashes, refresh
|
||||
sessions, records, tombstones and cursors remain readable by Go. Check health,
|
||||
login, refresh and sync again. The compatibility suite exercises both directions,
|
||||
including a second takeover back to the original implementation.
|
||||
login, refresh and sync again. Before the Go sources were removed, the
|
||||
compatibility suite verified takeover and rollback in both directions; Rust still
|
||||
writes the same schema (`tests/fixtures/go_schema_v1.sql`).
|
||||
|
||||
For database corruption or an unrelated failed migration, stop all writers before
|
||||
restoring the complete backup directory. Restoring an older backup discards
|
||||
@@ -77,12 +78,11 @@ an active database or delete a Compose volume as part of an upgrade.
|
||||
## Validation and operations
|
||||
|
||||
Before release run `cargo test --locked`, `cargo build --locked --release`,
|
||||
`python3 tools/compatibility.py --rust-binary target/release/balance-server`, and
|
||||
the retained reference checks `go test ./...`, `go vet ./...`, `go build ./...`.
|
||||
The differential suite uses temporary databases and loopback listeners, compares
|
||||
API/errors/security headers/assets, tests browser cookies, pagination, LWW,
|
||||
tombstones, concurrent pushes, token expiration, refresh rotation, rate limiting,
|
||||
and shared-database takeover/rollback in both directions.
|
||||
and `python3 tools/compatibility.py --binary target/release/balance-server`.
|
||||
The suite uses temporary databases and loopback listeners, compares
|
||||
API/errors/security headers/assets with the recorded Go reference, tests browser
|
||||
cookies, pagination, LWW, tombstones, concurrent pushes, token expiration, refresh
|
||||
rotation, rate limiting, and SQLite persistence across restarts.
|
||||
|
||||
Keep regular encrypted backups with retention and restore drills. Monitor HTTP
|
||||
5xx, sync errors, authentication failures, latency, database/change-log growth
|
||||
|
||||
+8
-9
@@ -2,28 +2,26 @@
|
||||
|
||||
## Требования
|
||||
|
||||
Production-сервер использует Rust 1.90+ и bundled SQLite. Go 1.25+ нужен для сохранённой эталонной реализации; differential-проверки (`tools/compatibility.py`) требуют Go 1.27.3, как в CI: поведение `net/http` (например, код редиректа ServeMux 301/307) зависит от версии Go. Python 3 используется без сторонних пакетов.
|
||||
Сервер использует Rust 1.90+ и bundled SQLite. Python 3 нужен для `tools/compatibility.py` и используется без сторонних пакетов. Go больше не нужен.
|
||||
|
||||
Проверить локальную версию:
|
||||
|
||||
```bash
|
||||
rustc --version
|
||||
cargo --version
|
||||
go version
|
||||
python3 --version
|
||||
```
|
||||
|
||||
## Установка зависимостей
|
||||
|
||||
```bash
|
||||
cargo fetch --locked
|
||||
go mod download
|
||||
```
|
||||
|
||||
## Сборка
|
||||
|
||||
```bash
|
||||
cargo build --locked
|
||||
go build ./...
|
||||
```
|
||||
|
||||
## Тесты
|
||||
@@ -32,13 +30,15 @@ go build ./...
|
||||
cargo test --locked
|
||||
cargo build --locked
|
||||
python3 tools/compatibility.py
|
||||
go test ./...
|
||||
```
|
||||
|
||||
С race detector:
|
||||
`tools/compatibility.py` запускает сервер на временных портах и базах и сравнивает
|
||||
ответы API и статику с ответами исходного Go-сервера, записанными в
|
||||
`tools/compatibility_expected.txt`. Расхождение означает изменение, видимое
|
||||
клиентам. Если изменение намеренное, проверьте diff и перезапишите эталон:
|
||||
|
||||
```bash
|
||||
go test -race ./...
|
||||
python3 tools/compatibility.py --update
|
||||
```
|
||||
|
||||
## Static checks
|
||||
@@ -46,7 +46,6 @@ go test -race ./...
|
||||
```bash
|
||||
cargo fmt --check
|
||||
cargo clippy --locked --all-targets -- -D warnings
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
Если в проекте есть Makefile/CI, его команды имеют приоритет как canonical build pipeline.
|
||||
@@ -89,7 +88,7 @@ cargo clippy --locked --all-targets -- -D warnings
|
||||
↓
|
||||
cargo build --locked --release
|
||||
↓
|
||||
python3 tools/compatibility.py --rust-binary target/release/balance-server
|
||||
python3 tools/compatibility.py --binary target/release/balance-server
|
||||
↓
|
||||
container/package
|
||||
↓
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
|
||||
<rect width="512" height="512" fill="url(#bg)"/>
|
||||
|
||||
<!-- Wallet, scaled up from internal/httpapi/web/icon.svg -->
|
||||
<!-- Wallet, scaled up from web/icon.svg -->
|
||||
<g transform="translate(-34 -46) scale(1.12)">
|
||||
<path d="M141 173c0-25 20-45 45-45h140c25 0 45 20 45 45v18H186c-25 0-45 20-45 45v-63Z" fill="#fff" opacity=".5"/>
|
||||
<path d="M116 222c0-28 23-51 51-51h179c28 0 51 23 51 51v126c0 28-23 51-51 51H167c-28 0-51-23-51-51V222Z" fill="url(#shine)"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -45,7 +45,7 @@
|
||||
<g transform="translate(297 400)"><rect x="-48" y="-19" width="96" height="38" rx="19" fill="#1f1f2b" stroke="#3b3b55"/><text y="6">Web</text></g>
|
||||
</g>
|
||||
|
||||
<!-- App icon (internal/httpapi/web/icon.svg) -->
|
||||
<!-- App icon (web/icon.svg) -->
|
||||
<g transform="translate(384 272) scale(.5)" filter="url(#shadow)">
|
||||
<rect x="28" y="28" width="456" height="456" rx="128" fill="url(#iconbg)"/>
|
||||
<path d="M141 173c0-25 20-45 45-45h140c25 0 45 20 45 45v18H186c-25 0-45 20-45 45v-63Z" fill="#fff" opacity=".5"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
+1
-1
@@ -45,7 +45,7 @@
|
||||
<g transform="translate(114 320)"><rect x="-44" y="-17" width="88" height="34" rx="17" fill="#1f1f2b" stroke="#3b3b55"/><text y="5">Web</text></g>
|
||||
</g>
|
||||
|
||||
<!-- App icon (internal/httpapi/web/icon.svg) -->
|
||||
<!-- App icon (web/icon.svg) -->
|
||||
<g transform="translate(180 200) scale(.46875)" filter="url(#shadow)">
|
||||
<rect x="28" y="28" width="456" height="456" rx="128" fill="url(#iconbg)"/>
|
||||
<path d="M141 173c0-25 20-45 45-45h140c25 0 45 20 45 45v18H186c-25 0-45 20-45 45v-63Z" fill="#fff" opacity=".5"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Reference in new issue
Block a user