feat: 完整游戏运维功能

This commit is contained in:
npc0-hue
2026-07-18 09:04:01 +08:00
parent f3b14b7945
commit 48b8ad8d6c
187 changed files with 16607 additions and 1140 deletions
+168 -8
View File
@@ -20,6 +20,20 @@ type UserRepository interface {
Update(domain.User) error
}
type AuthSessionRepository interface {
Create(domain.AuthSessionRecord) error
Get(id string) (domain.AuthSessionRecord, error)
List(domain.AuthSessionFilter) ([]domain.AuthSessionRecord, error)
Update(domain.AuthSessionRecord) error
}
type RunControlSessionRepository interface {
Create(domain.RunControlSession) error
Get(id string) (domain.RunControlSession, error)
List(struct{}) ([]domain.RunControlSession, error)
Update(domain.RunControlSession) error
}
type AIProviderRepository interface {
Create(domain.AIProvider) error
Get(id string) (domain.AIProvider, error)
@@ -91,6 +105,28 @@ type ClientManagerDistributionRepository interface {
Update(domain.ClientManagerDistribution) error
}
type ClientManagerInstallationRepository interface {
Create(domain.ClientManagerInstallation) error
Get(id string) (domain.ClientManagerInstallation, error)
List(domain.ClientManagerInstallationFilter) ([]domain.ClientManagerInstallation, error)
Update(domain.ClientManagerInstallation) error
}
type ClientManagerSessionRepository interface {
Create(domain.ClientManagerSession) error
Get(id string) (domain.ClientManagerSession, error)
List(domain.ClientManagerSessionFilter) ([]domain.ClientManagerSession, error)
Update(domain.ClientManagerSession) error
}
type ClientManagerNonceRepository interface {
Create(domain.ClientManagerRegistrationNonce) error
Get(id string) (domain.ClientManagerRegistrationNonce, error)
List(domain.ClientManagerNonceFilter) ([]domain.ClientManagerRegistrationNonce, error)
Update(domain.ClientManagerRegistrationNonce) error
Delete(id string) error
}
type DependencyStatusRepository interface {
Create(domain.DependencyStatus) error
Get(id string) (domain.DependencyStatus, error)
@@ -126,8 +162,26 @@ type AuditEventRepository interface {
Update(domain.AuditEvent) error
}
type MetricSampleRepository interface {
Create(domain.MetricSample) error
Get(id string) (domain.MetricSample, error)
List(domain.MetricSampleFilter) ([]domain.MetricSample, error)
Update(domain.MetricSample) error
Delete(id string) error
}
type BackupRepository interface {
Create(domain.BackupRecord) error
Get(id string) (domain.BackupRecord, error)
List(domain.BackupFilter) ([]domain.BackupRecord, error)
Update(domain.BackupRecord) error
Delete(id string) error
}
type Store interface {
Users() UserRepository
AuthSessions() AuthSessionRepository
RunControlSessions() RunControlSessionRepository
AIProviders() AIProviderRepository
GamePlugins() GamePluginRepository
ServerInstances() ServerInstanceRepository
@@ -138,15 +192,22 @@ type Store interface {
EncryptedComponentKeys() EncryptedComponentKeyRepository
RunDistributions() RunDistributionRepository
ClientManagerDistributions() ClientManagerDistributionRepository
ClientManagerInstallations() ClientManagerInstallationRepository
ClientManagerSessions() ClientManagerSessionRepository
ClientManagerNonces() ClientManagerNonceRepository
DependencyStatuses() DependencyStatusRepository
ClientManagerBuildJobs() ClientManagerBuildJobRepository
RunUpdateJobs() RunUpdateJobRepository
LogStreams() LogStreamRepository
AuditEvents() AuditEventRepository
MetricSamples() MetricSampleRepository
Backups() BackupRepository
}
type MemoryStore struct {
users *memoryRepository[domain.User, domain.UserFilter]
authSessions *memoryRepository[domain.AuthSessionRecord, domain.AuthSessionFilter]
runSessions *memoryRepository[domain.RunControlSession, struct{}]
aiProviders *memoryRepository[domain.AIProvider, domain.AIProviderFilter]
gamePlugins *memoryRepository[domain.GamePlugin, domain.GamePluginFilter]
serverInstances *memoryRepository[domain.ServerInstance, domain.ServerInstanceFilter]
@@ -157,11 +218,16 @@ type MemoryStore struct {
componentKeys *memoryRepository[domain.EncryptedComponentKey, domain.EncryptedComponentKeyFilter]
runDists *memoryRepository[domain.RunDistribution, domain.RunDistributionFilter]
clientDists *memoryRepository[domain.ClientManagerDistribution, domain.ClientManagerDistributionFilter]
clientInstalls *memoryRepository[domain.ClientManagerInstallation, domain.ClientManagerInstallationFilter]
clientSessions *memoryRepository[domain.ClientManagerSession, domain.ClientManagerSessionFilter]
clientNonces *memoryRepository[domain.ClientManagerRegistrationNonce, domain.ClientManagerNonceFilter]
dependencies *memoryRepository[domain.DependencyStatus, domain.DependencyStatusFilter]
buildJobs *memoryRepository[domain.ClientManagerBuildJob, domain.ClientManagerBuildJobFilter]
updateJobs *memoryRepository[domain.RunUpdateJob, domain.RunUpdateJobFilter]
logStreams *memoryRepository[domain.LogStream, domain.LogStreamFilter]
auditEvents *memoryRepository[domain.AuditEvent, domain.AuditEventFilter]
metricSamples *memoryRepository[domain.MetricSample, domain.MetricSampleFilter]
backups *memoryRepository[domain.BackupRecord, domain.BackupFilter]
}
func NewMemoryStore() *MemoryStore {
@@ -171,6 +237,16 @@ func NewMemoryStore() *MemoryStore {
domain.CopyUser,
matchUser,
),
authSessions: newMemoryRepository(
func(session domain.AuthSessionRecord) string { return session.ID },
domain.CopyAuthSessionRecord,
matchAuthSession,
),
runSessions: newMemoryRepository(
func(session domain.RunControlSession) string { return session.RunEndpointID },
domain.CopyRunControlSession,
func(domain.RunControlSession, struct{}) bool { return true },
),
aiProviders: newMemoryRepository(
func(provider domain.AIProvider) string { return provider.ID },
domain.CopyAIProvider,
@@ -217,6 +293,21 @@ func NewMemoryStore() *MemoryStore {
domain.CopyClientManagerDistribution,
matchClientManagerDistribution,
),
clientInstalls: newMemoryRepository(
func(installation domain.ClientManagerInstallation) string { return installation.ID },
domain.CopyClientManagerInstallation,
matchClientManagerInstallation,
),
clientSessions: newMemoryRepository(
func(session domain.ClientManagerSession) string { return session.ID },
domain.CopyClientManagerSession,
matchClientManagerSession,
),
clientNonces: newMemoryRepository(
func(nonce domain.ClientManagerRegistrationNonce) string { return nonce.ID },
domain.CopyClientManagerRegistrationNonce,
matchClientManagerNonce,
),
dependencies: newMemoryRepository(
func(status domain.DependencyStatus) string { return status.ID },
domain.CopyDependencyStatus,
@@ -242,17 +333,29 @@ func NewMemoryStore() *MemoryStore {
domain.CopyAuditEvent,
matchAuditEvent,
),
metricSamples: newMemoryRepository(
func(sample domain.MetricSample) string { return sample.ID },
domain.CopyMetricSample,
matchMetricSample,
),
backups: newMemoryRepository(
func(record domain.BackupRecord) string { return record.ID },
domain.CopyBackupRecord,
matchBackup,
),
}
}
func (store *MemoryStore) Users() UserRepository { return store.users }
func (store *MemoryStore) AIProviders() AIProviderRepository { return store.aiProviders }
func (store *MemoryStore) GamePlugins() GamePluginRepository { return store.gamePlugins }
func (store *MemoryStore) ServerInstances() ServerInstanceRepository { return store.serverInstances }
func (store *MemoryStore) RunEndpoints() RunEndpointRepository { return store.runEndpoints }
func (store *MemoryStore) Jobs() JobRepository { return store.jobs }
func (store *MemoryStore) Artifacts() ArtifactRepository { return store.artifacts }
func (store *MemoryStore) RuntimeBindings() RuntimeBindingRepository { return store.runtimeBindings }
func (store *MemoryStore) Users() UserRepository { return store.users }
func (store *MemoryStore) AuthSessions() AuthSessionRepository { return store.authSessions }
func (store *MemoryStore) RunControlSessions() RunControlSessionRepository { return store.runSessions }
func (store *MemoryStore) AIProviders() AIProviderRepository { return store.aiProviders }
func (store *MemoryStore) GamePlugins() GamePluginRepository { return store.gamePlugins }
func (store *MemoryStore) ServerInstances() ServerInstanceRepository { return store.serverInstances }
func (store *MemoryStore) RunEndpoints() RunEndpointRepository { return store.runEndpoints }
func (store *MemoryStore) Jobs() JobRepository { return store.jobs }
func (store *MemoryStore) Artifacts() ArtifactRepository { return store.artifacts }
func (store *MemoryStore) RuntimeBindings() RuntimeBindingRepository { return store.runtimeBindings }
func (store *MemoryStore) EncryptedComponentKeys() EncryptedComponentKeyRepository {
return store.componentKeys
}
@@ -260,6 +363,15 @@ func (store *MemoryStore) RunDistributions() RunDistributionRepository { return
func (store *MemoryStore) ClientManagerDistributions() ClientManagerDistributionRepository {
return store.clientDists
}
func (store *MemoryStore) ClientManagerInstallations() ClientManagerInstallationRepository {
return store.clientInstalls
}
func (store *MemoryStore) ClientManagerSessions() ClientManagerSessionRepository {
return store.clientSessions
}
func (store *MemoryStore) ClientManagerNonces() ClientManagerNonceRepository {
return store.clientNonces
}
func (store *MemoryStore) DependencyStatuses() DependencyStatusRepository { return store.dependencies }
func (store *MemoryStore) ClientManagerBuildJobs() ClientManagerBuildJobRepository {
return store.buildJobs
@@ -267,6 +379,8 @@ func (store *MemoryStore) ClientManagerBuildJobs() ClientManagerBuildJobReposito
func (store *MemoryStore) RunUpdateJobs() RunUpdateJobRepository { return store.updateJobs }
func (store *MemoryStore) LogStreams() LogStreamRepository { return store.logStreams }
func (store *MemoryStore) AuditEvents() AuditEventRepository { return store.auditEvents }
func (store *MemoryStore) MetricSamples() MetricSampleRepository { return store.metricSamples }
func (store *MemoryStore) Backups() BackupRepository { return store.backups }
type memoryRepository[T any, F any] struct {
mu sync.RWMutex
@@ -341,6 +455,16 @@ func (repository *memoryRepository[T, F]) Update(value T) error {
return nil
}
func (repository *memoryRepository[T, F]) Delete(id string) error {
repository.mu.Lock()
defer repository.mu.Unlock()
if _, exists := repository.byID[id]; !exists {
return ErrNotFound
}
delete(repository.byID, id)
return nil
}
type memoryJobRepository struct {
*memoryRepository[domain.Job, domain.JobFilter]
}
@@ -371,6 +495,12 @@ func matchUser(user domain.User, filter domain.UserFilter) bool {
return filter.Status == "" || user.Status == filter.Status
}
func matchAuthSession(session domain.AuthSessionRecord, filter domain.AuthSessionFilter) bool {
return (filter.UserID == "" || session.UserID == filter.UserID) &&
(filter.TokenHash == "" || session.TokenHash == filter.TokenHash) &&
(filter.Status == "" || session.Status == filter.Status)
}
func matchAIProvider(provider domain.AIProvider, filter domain.AIProviderFilter) bool {
return (filter.Kind == "" || provider.Kind == filter.Kind) &&
(filter.Status == "" || provider.Status == filter.Status)
@@ -444,6 +574,25 @@ func matchClientManagerDistribution(distribution domain.ClientManagerDistributio
(filter.Status == "" || distribution.Status == filter.Status)
}
func matchClientManagerInstallation(installation domain.ClientManagerInstallation, filter domain.ClientManagerInstallationFilter) bool {
return (filter.ServerInstanceID == "" || installation.ServerInstanceID == filter.ServerInstanceID) &&
(filter.ProfileKey == "" || installation.ProfileKey == filter.ProfileKey) &&
(filter.RunEndpointID == "" || installation.RunEndpointID == filter.RunEndpointID) &&
(filter.Status == "" || installation.Status == filter.Status)
}
func matchClientManagerSession(session domain.ClientManagerSession, filter domain.ClientManagerSessionFilter) bool {
return (filter.InstallationID == "" || session.InstallationID == filter.InstallationID) &&
(filter.ServerInstanceID == "" || session.ServerInstanceID == filter.ServerInstanceID) &&
(filter.ProfileKey == "" || session.ProfileKey == filter.ProfileKey) &&
(filter.Status == "" || session.Status == filter.Status)
}
func matchClientManagerNonce(nonce domain.ClientManagerRegistrationNonce, filter domain.ClientManagerNonceFilter) bool {
return (filter.InstallationID == "" || nonce.InstallationID == filter.InstallationID) &&
(filter.ExpiresBefore.IsZero() || nonce.ExpiresAt.Before(filter.ExpiresBefore) || nonce.ExpiresAt.Equal(filter.ExpiresBefore))
}
func matchDependencyStatus(status domain.DependencyStatus, filter domain.DependencyStatusFilter) bool {
return (filter.ServerInstanceID == "" || status.ServerInstanceID == filter.ServerInstanceID) &&
(filter.ProbeKey == "" || status.ProbeKey == filter.ProbeKey) &&
@@ -472,3 +621,14 @@ func matchAuditEvent(event domain.AuditEvent, filter domain.AuditEventFilter) bo
(filter.ResourceID == "" || event.ResourceID == filter.ResourceID) &&
(filter.Result == "" || event.Result == filter.Result)
}
func matchMetricSample(sample domain.MetricSample, filter domain.MetricSampleFilter) bool {
return (filter.ServerInstanceID == "" || sample.ServerInstanceID == filter.ServerInstanceID) &&
(filter.After.IsZero() || sample.CollectedAt.After(filter.After)) &&
(filter.Before.IsZero() || !sample.CollectedAt.After(filter.Before))
}
func matchBackup(record domain.BackupRecord, filter domain.BackupFilter) bool {
return (filter.ServerInstanceID == "" || record.ServerInstanceID == filter.ServerInstanceID) &&
(filter.State == "" || record.State == filter.State)
}