Commit Graph

22 Commits (2445da8630588267047c846cdedd995532bc7fb8)

Author SHA1 Message Date
zijiren 2445da8630
refactor(metrics): centralize registry and lifecycle tracking (#446)
## Summary

- split Prometheus definitions into domain-owned modules backed by one
registry
- eagerly initialize every metric family and fail startup on invalid or
duplicate definitions
- add reusable RAII guards for gauges and relay durations across
cancellation, panic, and retry paths
- centralize HTTP, WebSocket, gRPC, and relay recording behind
bounded-label helpers
- enforce the 65-metric bilingual catalog from registered descriptors
- persist completed explicit-message deletion and user-ban moderation
steps
- update the pinned Rust toolchain and CI jobs to `nightly-2026-08-25`
- make the CI Clippy job fail on every Rust warning with `-D warnings`
- keep Helm configuration-validation builds visible to avoid silent-run
termination
- separate Rust caches by artifact type and let Helm reuse codegen
artifacts from the Build job
- work around the nightly global next-solver memory regression and
remove obsolete rustc recursion-limit overrides
- preserve workspace Rust flags in Docker builds while applying linker
flags to the final binary

## Compatibility

- preserve all existing metric names, HELP text, label order, and
histogram buckets
- keep route-template and bounded status/error labels
- return HTTP 500 when Prometheus exposition encoding fails
- keep the latest nightly while restoring the previous coherence-only
trait-solver behavior

## Nightly memory regression

The failed CI jobs were terminated by the runner while compiling
`synctv-api-http` (SIGTERM, exit 143). Local peak-RSS measurements for
that crate were:

| Configuration | Peak RSS |
| --- | ---: |
| `nightly-2026-08-21` | 6.62 GB |
| `nightly-2026-08-25`, global next solver | 10.76 GB |
| `nightly-2026-08-25`, `-Znext-solver=coherence` | 6.64 GB |

Rust enabled `-Znext-solver=globally` by default on nightly in
[rust-lang/rust#160619](https://github.com/rust-lang/rust/pull/160619).
The same memory blow-up is tracked in
[rust-lang/rust#161748](https://github.com/rust-lang/rust/issues/161748),
and the official tracking issue documents `-Znext-solver=coherence` as
the temporary opt-out. The workspace now applies that option in
`.cargo/config.toml`.

The Dockerfile previously set `RUSTFLAGS` for linker options, which
overrode the workspace configuration and re-enabled the global solver
inside image builds. It now uses `cargo rustc` to pass linker flags only
to the final binary, preserving the workspace solver setting for every
crate.

All rustc `#![recursion_limit = "256"]` attributes were removed. The
default limit passes with the coherence-only solver, confirming that a
higher recursion limit was unrelated to the CI termination.

## Validation

- `make build-workspace`
- `make clippy-check` (`--workspace --all-targets -- -D warnings`)
- `cargo check --locked -p synctv-api-http`
- `cargo check --locked -p synctv-api-common -p synctv-api-grpc`
- `cargo test -p synctv-api-common --lib` (655 passed, 165 Docker tests
ignored)
- `cargo test -p synctv-core metrics --lib` (9 passed)
- `make fmt-check`
- `docker build --check .`
- `make validate-helm`
- `actionlint .github/workflows/ci.yml .github/workflows/helm-ci.yml`
- `npm run validate` in `docs` (124 pages, 353 links, Astro 0
errors/warnings)
4 weeks ago
zijiren 0633b83b4e
feat(emby): support passwordless accounts (#442)
## Summary
- Allow Emby users with an explicitly empty password to authenticate.
- Preserve password whitespace and keep missing credentials or empty API
keys invalid.
- Accept passwordless credentials through the remote provider API and
expose the CLI `--no-password` option.
- Update proto comments and CLI documentation.

## Validation
- Media provider test suite: 552 passed, 5 ignored.
- Focused Emby, gRPC, CLI, formatting, clippy, proto freshness, and
documentation checks passed.
1 month ago
zijiren c7aa2b0636
docs: add Nginx reverse proxy guide (#441)
## Summary

- add Chinese and English Nginx reverse proxy guides for the SyncTV HTTP
and WebSocket entrypoint
- disable Nginx proxy caching and upstream response buffering for all
API, Web UI, HLS, and media responses
- preserve SyncTV `Cache-Control` headers and explain why request
buffering remains independent
- link the guide from navigation, production checks, and media latency
troubleshooting

## Scope

The example covers the HTTP/WebSocket entrypoint only. It does not add
gRPC, RTMP, or Ingress configuration.

## Verification

- `npm run validate` in `docs`
- docs content validation: 124 pages, 353 internal links
- Astro diagnostics: 0 errors, 0 warnings, 0 hints
- static build and internal link validation
- `git diff --check`

`nginx -t` was not run because Nginx is not installed in the local
environment.
1 month ago
zijiren 9ebfef16e9
feat(web): support runtime UI assets (#440)
## Summary

- add a `web-ui-dynamic` feature that serves a mutable Web distribution
without compile-time embedding
- add `server.web_ui_directory` and `SYNCTV_SERVER_WEB_UI_DIRECTORY`,
with per-request disk reads, SPA fallback, security headers, and path
containment checks
- keep `web-ui` release builds embedded while allowing the same
production binary and Docker image to use a mounted runtime directory
- configure `make dev-serve` to use `synctv-web-ui/dist` and document
both modes

## Docker behavior

CI continues to build release images with `web-ui`, so embedded assets
remain the default. Mounting a distribution and setting
`SYNCTV_SERVER_WEB_UI_DIRECTORY` makes that directory authoritative at
runtime.

## Verification

- `cargo fmt --all -- --check`
- `git diff --check`
- `cargo test -p synctv-api-http --features web-ui-dynamic
http::web_ui::tests`
- `cargo test -p synctv-api-http --features web-ui http::web_ui::tests`
- `cargo check -p synctv --features web-ui-dynamic`
- `cargo check -p synctv --features web-ui`
1 month ago
zijiren 0778c2b23e
feat(rtmp): add advertised publish workflow (#439)
## Summary

- add the RTMP advertised address runtime setting and use it when
returning generated publish URLs
- generate reusable media-scoped publish sessions through the
provider-owned workflow
- preserve single-use publish keys while allowing creators to mint
replacements
- update runtime-setting documentation and generated protobuf contracts

## Verification

- cargo check -p synctv --features web-ui
- git diff --check
- end-to-end RTMP publish and playback against the embedded Web UI
1 month ago
zijiren 89b16ab21e
release: prepare v1.0.3 (#430)
## Summary

- bump the server, Helm chart, and documentation metadata to v1.0.3
- keep the Compose image fallback validation aligned with the
configurable image tag
- release the latest upstream main commit with personal user blocking

## Verification

- `make fmt-check`
- `make validate-helm`
- `cargo test -p synctv-api-common user_block --locked`
1 month ago
zijiren 61a837a424
docs: document TOTP support and limitations (#428)
## Summary

- document TOTP enrollment, verification, recovery codes, lifecycle, and
security controls in Chinese and English
- add HTTP and gRPC client flows, MFA request examples, and
recovery-code status fields
- describe clock synchronization, data retention, OAuth2 behavior, and
encryption-key rotation limitations

## Validation

- `npm run validate:content`
- `npx astro check`
- `npx astro build`
- `git diff --check`
1 month ago
zijiren 96d22abe99
fix(webrtc): use public STUN by default (#427)
## Summary

- disable the built-in SyncTV STUN server by default across application,
Compose, image, environment, and Helm configuration
- default `webrtc.externalIceServers` to Cloudflare and Google public
STUN endpoints while preserving persisted overrides and explicit `[]`
- update deployment validation, tests, examples, and English/Chinese
documentation

Tailscale is not included because it publishes STUN endpoints through
its dynamic DERP map and does not provide a stable general-purpose
hostname suitable for this default.

## Testing

- `cargo fmt --all -- --check`
- `cargo test -p synctv-core --test global_settings_registry_tests`
- `cargo test -p synctv-core
test_runtime_settings_default_to_public_stun_servers`
- `cargo test -p synctv default_webrtc_config_disables_builtin_stun`
- `cargo check --workspace --all-targets`
- `bash scripts/validate-helm.sh`
- Compose configuration rendering
- `npm run validate:content`
- `npm run check`
- `git diff --check`
1 month ago
zijiren 8711158d60
refactor: remove low-value thin wrappers (#426)
## Summary

- remove unused compatibility APIs and low-value forwarding wrappers
across the workspace
- inline service, repository, provider, cluster, proxy, and protocol
paths while preserving existing behavior
- remove stale dependencies, metrics, tests, and SQLx metadata generated
for deleted queries

## Validation

- `cargo check --workspace --all-targets`
- `cargo fmt --all -- --check`
- `git diff --check`
- relevant test suites: 1,408 passed, 184 ignored
- broader test run: 2,286 passed
1 month ago
zijiren 6b884e9964
fix(bilibili): restore subtitles and dynamic live danmaku (#415)
## Summary
- Propagate dynamic playlist identity into Bilibili playback generation
and expose room-scoped live danmaku SSE.
- Resolve each SSE connection against the current playlist target and
provider instance, retaining the playlist credential owner.
- Restore loopback-only PostgreSQL and Redis ports in the development
Compose profile so host-based `make dev-serve` can connect.

## Validation
- `cargo clippy -p synctv-core -p synctv-api-common -p synctv-api-http
--all-targets -- -D warnings`
- `cargo test -p synctv-core
dynamic_live_playback_has_a_live_danmaku_track`
- `cargo test -p synctv-api-common
dynamic_live_danmaku_provider_converts_to_room_scoped_endpoint`
- `cargo test -p synctv-api-http`
- `docker compose -p synctv-dev -f docker-compose.dev.yml config -q`
1 month ago
zijiren d560b8efce
fix: harden Bilibili playback reliability (#412)
## Summary

- Treat explicit null collection fields in Bilibili VOD playback
responses as empty collections.
- Cover DASH streams, backup URLs, Dolby audio, supported formats, DURL
responses, subtitles, video pages, UGC collections, and PGC episodes.
- Resolve Bilibili DASH resources from versioned playback metadata and
provide every equivalent CDN URL to the existing candidate executor.
- Prefer the URL selected by the player, then retry primary and backup
CDNs before committing the downstream response.

## Root cause

Bilibili occasionally emits explicit null for fields normally
represented as JSON arrays, which caused playback/start deserialization
errors. Proxy DASH resource requests also used a single CDN even though
the provider response included backup URLs.

## Validation

- cargo fmt --all -- --check
- cargo check for synctv-api-common, synctv-api-http, and
synctv-api-grpc
- synctv-media-providers Bilibili tests: 91 passed
- synctv-core Bilibili tests: 17 passed, 2 ignored
- candidate executor tests: 2 passed
- Real playback/start, proxy MPD, Range request, CDN fault injection,
dev build, and dev smoke checks
1 month ago
zijiren 2f61d0e8de
release: prepare v1.0.2 (#408)
## Summary

- bump the Cargo workspace to 1.0.2
- synchronize Helm chart and documentation versions

## Verification

- `make fmt-check`
- `make clippy-check`
- `make nextest-default` (5,186 passed)
- `make nextest-ignored` (1,585 passed)
- `make validate-helm`
1 month ago
zijiren 9bc010c568
fix: classify forced realtime disconnects (#395)
## Summary

- send a typed realtime termination message before server-initiated
WebSocket disconnects
- restore the view_playback_history permission bit across effective
permissions and runtime settings round trips
- remove the unused common ErrorCode enum and document the dedicated
termination codes

## Validation

- make nextest: 6715 passed
- make clippy
- git diff --check
2 months ago
zijiren da1abd1a68
feat: add recoverable resource deletion lifecycle (#394)
## Summary

- Add recoverable soft deletion for users, rooms, playlists, media, and
chat messages, with retention-based physical cleanup.
- Hide deleted users and owned resources from active API, room,
playback, messaging, and realtime paths while preserving restoration
metadata.
- Add user lifecycle administration across HTTP, gRPC, management
runtime, and SyncTV CLI, including deleted-user listing and restore
operations.
- Add lifecycle migration, cleanup orchestration, audit fields,
resource-change events, and refreshed SQLx offline metadata.

## Design

- Model account, administrator, system, room, and user deletion sources
explicitly so cascade ownership and audit history remain deterministic.
- Release email and OAuth identity occupancy during deletion;
restoration reclaims available identities and reports conflicts
according to restore options.
- Preserve recoverable aggregate rows during the retention window,
remove ephemeral membership and playback state immediately, and purge
expired data in dependency order.
- Wait for realtime observation acknowledgements before publishing
lifecycle changes to avoid subscription registration races.

## Verification

- `make nextest`: 6707 passed, 0 skipped
- `make clippy`: passed for the workspace and all targets
- `make clippy-check`: passed
- `cargo fmt --all -- --check`: passed
- `git diff --check`: passed
2 months ago
zijiren c0e3c2dae5
fix(docs): preserve TAR end-of-archive blocks (#389)
## Summary
- Allocate an explicit TAR output buffer sized to the written bytes plus
two 512-byte end blocks.
- Copy the archive payload into the buffer so TAR downloads always
include the required zero blocks.

## Testing
- `npm run validate` from `docs/`
- TAR end-block assertion with `tar-js`
2 months ago
zijiren e42aed8b9f
fix(docs): package Compose environment files as TAR (#388)
## Summary
- Fix Compose environment archive filenames for issue #385.
- Provide a lazy-loaded TAR download containing all three environment
files.
- Use Starlight code blocks for environment previews and built-in copy
controls.
- Document Linux hidden files and the `ls -a` command after extraction.

## Testing
- `npm run validate` (from `docs/)
2 months ago
zijiren233 6eeb974c9b
docs(apple): explain Developer ID browser authentication 2 months ago
zijiren 11f1e8effc
release: prepare v1.0.1
Merge the backend release version synchronization.
2 months ago
zijiren 1716af8321
feat(oauth2): add provider modes and native Apple flow
Merge reviewed OAuth provider mode and native Apple flow changes.
2 months ago
zijiren233 d81e731203
docs: add Compose environment generator 2 months ago
zijiren233 0dcc27feee
docs: fix client download links 2 months ago
zijiren233 5425eaf436 chore: replace synctv-org backend with SyncTV v1.0.0 2 months ago