feat: unify account environments and work collection

This commit is contained in:
2026-10-06 13:00:29 +08:00
parent b72727451d
commit 950b23da32
22 changed files with 935 additions and 93 deletions
+2 -2
View File
@@ -462,7 +462,7 @@ func (s *Store) GetEnvironmentContext(ctx context.Context, alias string) (Enviro
var runtimeID, runtimeNetworkID, runtimeNodeID, cleanupRuntimeID, cleanupNetworkID sql.NullString
var cleanupBindingVersion sql.NullInt64
err = tx.QueryRowContext(ctx, `
SELECT environment.alias, environment.name, gateway.name,
SELECT environment.id, environment.alias, environment.name, gateway.name,
environment.fingerprint, environment.created_at, COALESCE(account.account_id, ''), COALESCE(account.status, ''), environment.profile_id,
environment.version,
environment.runtime_cleanup_pending, environment.runtime_cleanup_binding_version,
@@ -479,7 +479,7 @@ func (s *Store) GetEnvironmentContext(ctx context.Context, alias string) (Enviro
JOIN gateway ON gateway.id = environment.gateway_id
LEFT JOIN network_exit network ON network.id = environment.exit_id
WHERE environment.alias = $1`, alias).
Scan(&result.Alias, &result.Name, &result.Gateway, &encoded, &result.CreatedAt,
Scan(&result.ID, &result.Alias, &result.Name, &result.Gateway, &encoded, &result.CreatedAt,
&result.AccountID, &result.AccountStatus, &result.ProfileID,
&result.BindingVersion, &result.RuntimeCleanupPending, &cleanupBindingVersion,
&cleanupRuntimeID, &cleanupNetworkID,
+1 -1
View File
@@ -24,7 +24,7 @@ func (s *Store) CreateStandaloneEnv(ctx context.Context, gateway string, fingerp
}
func (s *Store) ListPendingEnvironments(ctx context.Context) ([]EnvironmentContext, error) {
rows, err := s.db.QueryContext(ctx, `SELECT alias FROM browser_env WHERE account_id IS NULL ORDER BY created_at,id`)
rows, err := s.db.QueryContext(ctx, `SELECT alias FROM browser_env WHERE account_id IS NULL ORDER BY id DESC`)
if err != nil {
return nil, fmt.Errorf("list pending browser environments: %w", err)
}
@@ -0,0 +1,46 @@
package environment
import (
"context"
"encoding/json"
"os"
"testing"
)
func TestPendingEnvironmentDatabaseIDOrder(t *testing.T) {
databaseURL := os.Getenv("CREATORHUB_POSTGRES_TEST_URL")
if databaseURL == "" {
t.Skip("set CREATORHUB_POSTGRES_TEST_URL to run PostgreSQL integration coverage")
}
ctx := context.Background()
store := openFullyMigratedHub(t, ctx, isolatedDatabaseURL(t, databaseURL))
t.Cleanup(func() { _ = store.Close() })
if _, err := store.CreateGateway(ctx, "order-gateway", "http://127.0.0.1:8090", "order-gateway-test-token"); err != nil {
t.Fatal(err)
}
first, err := store.CreateStandaloneEnv(ctx, "order-gateway", Fingerprint{})
if err != nil {
t.Fatal(err)
}
second, err := store.CreateStandaloneEnv(ctx, "order-gateway", Fingerprint{})
if err != nil {
t.Fatal(err)
}
if first.ID < 1 || second.ID <= first.ID {
t.Fatalf("environment IDs must increase: first=%d second=%d", first.ID, second.ID)
}
pending, err := store.ListPendingEnvironments(ctx)
if err != nil || len(pending) != 2 || pending[0].ID != second.ID || pending[1].ID != first.ID {
t.Fatalf("pending environments must be newest first: %#v err=%v", pending, err)
}
data, err := json.Marshal(second)
if err != nil {
t.Fatal(err)
}
var response struct {
ID int64 `json:"id"`
}
if err := json.Unmarshal(data, &response); err != nil || response.ID != second.ID {
t.Fatalf("database ID missing from environment JSON: %s err=%v", data, err)
}
}
+4 -3
View File
@@ -223,6 +223,7 @@ type Gateway struct {
// Env 是一个浏览器环境;浏览器安装和默认运行时由 gateway 宿主机配置。
type Env struct {
ID int64 `json:"id"`
Alias string `json:"alias"`
Name string `json:"name"`
Gateway string `json:"gateway"`
@@ -452,7 +453,7 @@ func (s *Store) DeleteGateway(ctx context.Context, name string) error {
func (s *Store) ListEnvs(ctx context.Context) ([]Env, error) {
rows, err := s.db.QueryContext(ctx, `
SELECT environment.alias, environment.name, gateway.name, environment.fingerprint, environment.created_at
SELECT environment.id, environment.alias, environment.name, gateway.name, environment.fingerprint, environment.created_at
FROM browser_env environment
JOIN gateway ON gateway.id = environment.gateway_id
ORDER BY environment.created_at, environment.alias`)
@@ -476,7 +477,7 @@ func (s *Store) GetEnv(ctx context.Context, alias string) (Env, error) {
return Env{}, ErrInvalid
}
rows, err := s.db.QueryContext(ctx, `
SELECT environment.alias, environment.name, gateway.name, environment.fingerprint, environment.created_at
SELECT environment.id, environment.alias, environment.name, gateway.name, environment.fingerprint, environment.created_at
FROM browser_env environment
JOIN gateway ON gateway.id = environment.gateway_id
WHERE environment.alias = $1`, alias)
@@ -536,7 +537,7 @@ func (s *Store) DeleteAccountEnvironment(ctx context.Context, accountID string)
func scanEnv(rows *sql.Rows) (Env, error) {
var env Env
var encoded []byte
if err := rows.Scan(&env.Alias, &env.Name, &env.Gateway, &encoded, &env.CreatedAt); err != nil {
if err := rows.Scan(&env.ID, &env.Alias, &env.Name, &env.Gateway, &encoded, &env.CreatedAt); err != nil {
return Env{}, errors.New("decode browser env")
}
if len(encoded) > 0 {