Add admin console access and platform pages (trust, users, keys, workloads, settings)

This commit is contained in:
Emil
2026-08-03 00:11:47 +03:00
parent 7fb1059401
commit e923627ce0
36 changed files with 1562 additions and 86 deletions
@@ -54,6 +54,8 @@ func expectedMigrationName(version int) string {
return "0012_worker_trust.up.sql"
case 13:
return "0013_task_results.up.sql"
case 14:
return "0014_workload_settings.up.sql"
default:
return ""
}
@@ -0,0 +1,5 @@
BEGIN;
DROP TABLE IF EXISTS workload_settings;
COMMIT;
@@ -0,0 +1,11 @@
BEGIN;
-- Per-workload enable/disable. Absence of a row means "enabled" (the catalog
-- default); a row only exists once an admin flipped a workload off or back on.
CREATE TABLE workload_settings (
workload text NOT NULL PRIMARY KEY,
enabled boolean NOT NULL,
updated_at timestamptz NOT NULL DEFAULT now()
);
COMMIT;
@@ -91,6 +91,24 @@ func (r *WorkerRepo) MarkStaleOffline(ctx context.Context, cutoff time.Time) (in
return tag.RowsAffected(), nil
}
func (r *WorkerRepo) SetTrust(ctx context.Context, id uuid.UUID, trust domain.WorkerTrust) error {
sql, args, err := psql.Update("workers").
SetMap(map[string]any{"trust_level": string(trust), "updated_at": time.Now()}).
Where(sq.Eq{"id": id}).
ToSql()
if err != nil {
return err
}
tag, err := conn(ctx, r.pool).Exec(ctx, sql, args...)
if err != nil {
return fmt.Errorf("set worker trust: %w", err)
}
if tag.RowsAffected() == 0 {
return domain.ErrWorkerNotFound
}
return nil
}
func scanWorker(row pgx.Row) (*domain.Worker, error) {
var (
w domain.Worker
@@ -0,0 +1,67 @@
package postgres
import (
"context"
"fmt"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/emil28092005/SciMesh/coordinator/internal/usecase"
)
// WorkloadSettingsRepo persists the per-workload enable/disable overrides.
// Absence of a row means the workload is enabled (the catalog default).
type WorkloadSettingsRepo struct{ pool *pgxpool.Pool }
func NewWorkloadSettingsRepo(pool *pgxpool.Pool) *WorkloadSettingsRepo {
return &WorkloadSettingsRepo{pool: pool}
}
var _ usecase.WorkloadSettingsRepository = (*WorkloadSettingsRepo)(nil)
func (r *WorkloadSettingsRepo) GetEnabled(ctx context.Context, workload string) (bool, error) {
var enabled bool
err := conn(ctx, r.pool).QueryRow(ctx,
"SELECT enabled FROM workload_settings WHERE workload = $1", workload).Scan(&enabled)
if err != nil && err.Error() == "no rows in result set" {
return true, nil // no override: catalog default enabled
}
if err != nil {
return false, fmt.Errorf("get workload setting: %w", err)
}
return enabled, nil
}
func (r *WorkloadSettingsRepo) List(ctx context.Context) ([]usecase.WorkloadSetting, error) {
rows, err := conn(ctx, r.pool).Query(ctx,
"SELECT workload, enabled, updated_at FROM workload_settings ORDER BY workload ASC")
if err != nil {
return nil, fmt.Errorf("list workload settings: %w", err)
}
defer rows.Close()
var out []usecase.WorkloadSetting
for rows.Next() {
var s usecase.WorkloadSetting
if err := rows.Scan(&s.Workload, &s.Enabled, &s.UpdatedAt); err != nil {
return nil, err
}
out = append(out, s)
}
return out, rows.Err()
}
func (r *WorkloadSettingsRepo) SetEnabled(ctx context.Context, workload string, enabled bool, now time.Time) error {
sql, args, err := psql.Insert("workload_settings").
Columns("workload", "enabled", "updated_at").
Values(workload, enabled, now).
Suffix(`ON CONFLICT (workload) DO UPDATE SET enabled = EXCLUDED.enabled, updated_at = EXCLUDED.updated_at`).
ToSql()
if err != nil {
return err
}
if _, err := conn(ctx, r.pool).Exec(ctx, sql, args...); err != nil {
return fmt.Errorf("set workload setting: %w", err)
}
return nil
}
@@ -0,0 +1,89 @@
package sqlite
import (
"context"
"testing"
"time"
"github.com/google/uuid"
"github.com/emil28092005/SciMesh/coordinator/internal/domain"
)
func TestWorkloadSettingsRepoRoundTrip(t *testing.T) {
db := newTestDB(t)
ctx := context.Background()
repo := NewWorkloadSettingsRepo(db)
// No override: enabled by default.
enabled, err := repo.GetEnabled(ctx, "similarity-search")
if err != nil {
t.Fatal(err)
}
if !enabled {
t.Error("workload without an override must be enabled")
}
now := time.Date(2026, 8, 2, 12, 0, 0, 0, time.UTC)
if err := repo.SetEnabled(ctx, "similarity-search", false, now); err != nil {
t.Fatal(err)
}
enabled, err = repo.GetEnabled(ctx, "similarity-search")
if err != nil {
t.Fatal(err)
}
if enabled {
t.Error("workload must be disabled after the override")
}
// Upsert flips it back and updates the timestamp.
later := now.Add(time.Hour)
if err := repo.SetEnabled(ctx, "similarity-search", true, later); err != nil {
t.Fatal(err)
}
enabled, err = repo.GetEnabled(ctx, "similarity-search")
if err != nil {
t.Fatal(err)
}
if !enabled {
t.Error("workload must be re-enabled after the upsert")
}
list, err := repo.List(ctx)
if err != nil {
t.Fatal(err)
}
if len(list) != 1 || list[0].Workload != "similarity-search" || !list[0].Enabled {
t.Errorf("list = %+v, want the single re-enabled override", list)
}
}
func TestWorkerSetTrust(t *testing.T) {
db := newTestDB(t)
ctx := context.Background()
repo := NewWorkerRepo(db)
worker, err := domain.NewWorker("lab-node", []string{"similarity-search"}, fixedTime())
if err != nil {
t.Fatal(err)
}
if err := repo.Insert(ctx, worker); err != nil {
t.Fatal(err)
}
if err := repo.SetTrust(ctx, worker.ID, domain.WorkerUntrusted); err != nil {
t.Fatal(err)
}
got, err := repo.Get(ctx, worker.ID)
if err != nil {
t.Fatal(err)
}
if got.TrustLevel != domain.WorkerUntrusted {
t.Errorf("trust = %q, want untrusted", got.TrustLevel)
}
if err := repo.SetTrust(ctx, worker.ID, domain.WorkerTrusted); err != nil {
t.Fatal(err)
}
if err := repo.SetTrust(ctx, uuid.New(), domain.WorkerTrusted); err != domain.ErrWorkerNotFound {
t.Errorf("unknown worker trust err = %v, want ErrWorkerNotFound", err)
}
}
@@ -0,0 +1,8 @@
-- 0002: per-workload enable/disable. Absence of a row means "enabled" (the
-- catalog default); a row only exists once an admin flipped a workload off or
-- back on.
CREATE TABLE IF NOT EXISTS workload_settings (
workload TEXT NOT NULL PRIMARY KEY,
enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
updated_at INTEGER NOT NULL
);
@@ -69,8 +69,8 @@ func TestMigrateIsIdempotent(t *testing.T) {
if err := db.QueryRowContext(ctx, "PRAGMA user_version").Scan(&version); err != nil {
t.Fatal(err)
}
if version != 1 {
t.Errorf("user_version = %d, want 1", version)
if version != 2 {
t.Errorf("user_version = %d, want 2", version)
}
}
@@ -90,3 +90,20 @@ func (r *WorkerRepo) MarkStaleOffline(ctx context.Context, cutoff time.Time) (in
}
return res.RowsAffected()
}
func (r *WorkerRepo) SetTrust(ctx context.Context, id uuid.UUID, trust domain.WorkerTrust) error {
res, err := conn(ctx, r.db).ExecContext(ctx,
"UPDATE workers SET trust_level = ?, updated_at = ? WHERE id = ?",
string(trust), encodeTime(time.Now()), id.String())
if err != nil {
return err
}
affected, err := res.RowsAffected()
if err != nil {
return err
}
if affected == 0 {
return domain.ErrWorkerNotFound
}
return nil
}
@@ -0,0 +1,75 @@
package sqlite
import (
"context"
"database/sql"
"fmt"
"time"
"github.com/emil28092005/SciMesh/coordinator/internal/usecase"
)
// WorkloadSettingsRepo persists the per-workload enable/disable overrides.
// Absence of a row means the workload is enabled (the catalog default).
type WorkloadSettingsRepo struct{ db *sql.DB }
func NewWorkloadSettingsRepo(db *sql.DB) *WorkloadSettingsRepo { return &WorkloadSettingsRepo{db: db} }
var _ usecase.WorkloadSettingsRepository = (*WorkloadSettingsRepo)(nil)
func (r *WorkloadSettingsRepo) GetEnabled(ctx context.Context, workload string) (bool, error) {
var enabled int
err := conn(ctx, r.db).QueryRowContext(ctx,
"SELECT enabled FROM workload_settings WHERE workload = ?", workload).Scan(&enabled)
if err == sql.ErrNoRows {
return true, nil // no override: catalog default enabled
}
if err != nil {
return false, fmt.Errorf("get workload setting: %w", err)
}
return enabled == 1, nil
}
func (r *WorkloadSettingsRepo) List(ctx context.Context) ([]usecase.WorkloadSetting, error) {
rows, err := conn(ctx, r.db).QueryContext(ctx,
"SELECT workload, enabled, updated_at FROM workload_settings ORDER BY workload ASC")
if err != nil {
return nil, fmt.Errorf("list workload settings: %w", err)
}
defer func() { _ = rows.Close() }()
var out []usecase.WorkloadSetting
for rows.Next() {
var (
name string
enabled int
updatedAt int64
)
if err := rows.Scan(&name, &enabled, &updatedAt); err != nil {
return nil, err
}
out = append(out, usecase.WorkloadSetting{
Workload: name,
Enabled: enabled == 1,
UpdatedAt: decodeTime(updatedAt),
})
}
return out, rows.Err()
}
func (r *WorkloadSettingsRepo) SetEnabled(ctx context.Context, workload string, enabled bool, now time.Time) error {
_, err := conn(ctx, r.db).ExecContext(ctx, `
INSERT INTO workload_settings (workload, enabled, updated_at) VALUES (?, ?, ?)
ON CONFLICT (workload) DO UPDATE SET enabled = excluded.enabled, updated_at = excluded.updated_at`,
workload, boolInt(enabled), now.UnixNano())
if err != nil {
return fmt.Errorf("set workload setting: %w", err)
}
return nil
}
func boolInt(b bool) int {
if b {
return 1
}
return 0
}