test: end-to-end user journey in CI; fix ALS vectors for small libraries
ci / api / api (push) Successful in 30s
ci / recommender / recommender (push) Successful in 30s
ci / db / db (push) Failing after 1m8s

- newApp (extracted from main) is the exact production wiring; the
  `ci / db` job now also runs it on PostgreSQL, Redis and Meilisearch
  and walks the main user flows over HTTP: first admin sign-in and
  credential change, local source and scan, search, album / artist /
  top tracks, signed stream, events and history, likes, fallback wave,
  playback state, upload queue up to review.
- ALS on a small library produced fewer than 64 factors and the insert
  into vector(64) failed; vectors are now zero-padded to the column size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Opus 5.5 committed 2026-10-20 18:26:36 +03:00
1 parent f5c276092f
commit 2285107d04
5 files changed
+382 -11

No files matched your search

+18 -8
View File
@@ -72,12 +72,25 @@ func run() error {
rdb := redis.NewClient(redisOpts)
defer func() { _ = rdb.Close() }()
authSvc, err := newAuthService(cfg, pool, rdb, log)
handler, err := newApp(ctx, cfg, pool, rdb, log, library.FFprobe{Bin: cfg.FFprobePath, Timeout: time.Minute})
if err != nil {
return err
}
srv := httpx.NewServer(cfg.HTTPAddr, handler)
log.Info("starting", "version", buildinfo.Version)
return httpx.Serve(ctx, log, srv, cfg.ShutdownTimeout)
}
// newApp собирает сервис: хранилища, сканер, плеер, волну, очередь и HTTP-роутер. Фоновые задачи живут до отмены ctx.
// prober подменяется в сквозном тесте (там нет ffprobe).
func newApp(ctx context.Context, cfg config.API, pool *pgxpool.Pool, rdb *redis.Client, log *slog.Logger,
prober library.Prober) (http.Handler, error) {
authSvc, err := newAuthService(cfg, pool, rdb, log)
if err != nil {
return nil, err
}
if err := authSvc.Bootstrap(ctx); err != nil {
return err
return nil, err
}
sys := system.NewHandler(system.Info{
@@ -92,7 +105,6 @@ func run() error {
})
libStore := library.NewStore(pool)
prober := library.FFprobe{Bin: cfg.FFprobePath, Timeout: time.Minute}
board := library.NewProgressBoard()
scanner := library.NewScanner(libStore, prober, board, log)
agent := library.NewHTTPAgent(cfg.StorageAgentURL, cfg.InternalToken)
@@ -102,7 +114,7 @@ func run() error {
indexer := search.NewIndexer(pool, meili, log)
signer, err := sign.New(cfg.SigningKey)
if err != nil {
return err
return nil, err
}
if cfg.SigningKey == "" {
log.Warn("STREAM_SIGNING_KEY is not set: cover and stream links will break on restart")
@@ -152,7 +164,7 @@ func run() error {
uploads.Config{StagingDir: cfg.UploadsDir, FFmpeg: cfg.FFmpegPath}, log)
upSvc.Run(ctx)
srv := httpx.NewServer(cfg.HTTPAddr, server.NewRouter(server.Deps{
return server.NewRouter(server.Deps{
Log: log,
System: sys,
Auth: auth.NewHandler(authSvc, cfg.CookieSecure),
@@ -166,9 +178,7 @@ func run() error {
Dir: cfg.UpdatesDir, MinSupported: cfg.MinAndroidVersionCode}, log),
Uploads: uploads.NewHandler(upSvc),
TUS: uploads.NewTUS(uploads.NewStore(pool), cfg.UploadsDir, upSvc.Complete, log),
}))
log.Info("starting", "version", buildinfo.Version)
return httpx.Serve(ctx, log, srv, cfg.ShutdownTimeout)
}), nil
}
func newAuthService(cfg config.API, pool *pgxpool.Pool, rdb *redis.Client, log *slog.Logger) (*auth.Service, error) {