mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
260 lines
7.7 KiB
Go
260 lines
7.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"bugulma/backend/internal/domain"
|
|
)
|
|
|
|
type AdminService struct {
|
|
orgService *OrganizationService
|
|
userService *UserService
|
|
verificationService *VerificationService
|
|
i18nService *I18nService
|
|
}
|
|
|
|
func NewAdminService(
|
|
orgService *OrganizationService,
|
|
userService *UserService,
|
|
verificationService *VerificationService,
|
|
i18nService *I18nService,
|
|
) *AdminService {
|
|
return &AdminService{
|
|
orgService: orgService,
|
|
userService: userService,
|
|
verificationService: verificationService,
|
|
i18nService: i18nService,
|
|
}
|
|
}
|
|
|
|
// DashboardStats represents dashboard statistics
|
|
type DashboardStats struct {
|
|
TotalOrganizations int64 `json:"totalOrganizations"`
|
|
VerifiedOrganizations int64 `json:"verifiedOrganizations"`
|
|
ActiveConnections int64 `json:"activeConnections"`
|
|
NewThisMonth int64 `json:"newThisMonth"`
|
|
PendingVerifications int64 `json:"pendingVerifications"`
|
|
PendingTranslations int64 `json:"pendingTranslations"`
|
|
SystemAlerts int64 `json:"systemAlerts"`
|
|
}
|
|
|
|
// GetDashboardStats retrieves dashboard statistics
|
|
func (s *AdminService) GetDashboardStats(ctx context.Context) (*DashboardStats, error) {
|
|
// Get all organizations
|
|
allOrgs, err := s.orgService.GetAll(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get organizations: %w", err)
|
|
}
|
|
|
|
stats := &DashboardStats{
|
|
TotalOrganizations: int64(len(allOrgs)),
|
|
}
|
|
|
|
// Count verified organizations
|
|
verifiedCount := int64(0)
|
|
now := time.Now()
|
|
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
|
newThisMonth := int64(0)
|
|
|
|
for _, org := range allOrgs {
|
|
if org.Verified {
|
|
verifiedCount++
|
|
}
|
|
if org.CreatedAt.After(monthStart) {
|
|
newThisMonth++
|
|
}
|
|
}
|
|
|
|
stats.VerifiedOrganizations = verifiedCount
|
|
stats.NewThisMonth = newThisMonth
|
|
|
|
// Get pending verifications
|
|
verificationQueue, err := s.verificationService.GetVerificationQueue(ctx, VerificationQueueFilters{
|
|
Status: func() *domain.VerificationStatus {
|
|
status := domain.VerificationPending
|
|
return &status
|
|
}(),
|
|
})
|
|
if err == nil {
|
|
stats.PendingVerifications = int64(len(verificationQueue))
|
|
}
|
|
|
|
// Get pending translations (simplified - would need more detailed i18n stats)
|
|
translationStats, err := s.i18nService.GetTranslationStats(ctx, "")
|
|
if err == nil {
|
|
// Calculate missing translations
|
|
if totalKeys, ok := translationStats["total_unique_keys"].(int64); ok {
|
|
if translatedCounts, ok := translationStats["translated_counts"].(map[string]int64); ok {
|
|
// Count missing for each locale
|
|
var totalMissing int64
|
|
for locale, count := range translatedCounts {
|
|
if locale != DefaultLocale {
|
|
missing := totalKeys - count
|
|
if missing > 0 {
|
|
totalMissing += missing
|
|
}
|
|
}
|
|
}
|
|
stats.PendingTranslations = totalMissing
|
|
}
|
|
}
|
|
}
|
|
|
|
// Active connections would come from matching/proposal service
|
|
// For now, set to 0
|
|
stats.ActiveConnections = 0
|
|
stats.SystemAlerts = 0
|
|
|
|
return stats, nil
|
|
}
|
|
|
|
// OrganizationStats represents organization statistics
|
|
type OrganizationStats struct {
|
|
Total int64 `json:"total"`
|
|
Verified int64 `json:"verified"`
|
|
Pending int64 `json:"pending"`
|
|
Unverified int64 `json:"unverified"`
|
|
NewThisMonth int64 `json:"newThisMonth"`
|
|
BySector map[string]int64 `json:"bySector"`
|
|
BySubtype map[string]int64 `json:"bySubtype"`
|
|
VerificationRate float64 `json:"verificationRate"`
|
|
}
|
|
|
|
// GetOrganizationStats retrieves organization statistics
|
|
func (s *AdminService) GetOrganizationStats(ctx context.Context, filters map[string]interface{}) (*OrganizationStats, error) {
|
|
allOrgs, err := s.orgService.GetAll(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get organizations: %w", err)
|
|
}
|
|
|
|
stats := &OrganizationStats{
|
|
Total: int64(len(allOrgs)),
|
|
BySector: make(map[string]int64),
|
|
BySubtype: make(map[string]int64),
|
|
}
|
|
|
|
now := time.Now()
|
|
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
|
|
|
for _, org := range allOrgs {
|
|
if org.Verified {
|
|
stats.Verified++
|
|
} else {
|
|
stats.Unverified++
|
|
}
|
|
if org.CreatedAt.After(monthStart) {
|
|
stats.NewThisMonth++
|
|
}
|
|
stats.BySector[string(org.Sector)]++
|
|
stats.BySubtype[string(org.Subtype)]++
|
|
}
|
|
|
|
// Get pending verifications
|
|
verificationQueue, err := s.verificationService.GetVerificationQueue(ctx, VerificationQueueFilters{})
|
|
if err == nil {
|
|
stats.Pending = int64(len(verificationQueue))
|
|
}
|
|
|
|
if stats.Total > 0 {
|
|
stats.VerificationRate = float64(stats.Verified) / float64(stats.Total) * 100
|
|
}
|
|
|
|
return stats, nil
|
|
}
|
|
|
|
// UserActivityStats represents user activity statistics
|
|
type UserActivityStats struct {
|
|
TotalUsers int64 `json:"totalUsers"`
|
|
ActiveUsers int64 `json:"activeUsers"`
|
|
InactiveUsers int64 `json:"inactiveUsers"`
|
|
NewThisMonth int64 `json:"newThisMonth"`
|
|
ByRole map[string]int64 `json:"byRole"`
|
|
LastLoginStats map[string]int64 `json:"lastLoginStats"` // last_7_days, last_30_days, never
|
|
}
|
|
|
|
// GetUserActivityStats retrieves user activity statistics
|
|
func (s *AdminService) GetUserActivityStats(ctx context.Context, filters map[string]interface{}) (*UserActivityStats, error) {
|
|
userStats, err := s.userService.GetUserStats(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get user stats: %w", err)
|
|
}
|
|
|
|
stats := &UserActivityStats{
|
|
ByRole: make(map[string]int64),
|
|
LastLoginStats: make(map[string]int64),
|
|
}
|
|
|
|
if total, ok := userStats["total"].(int64); ok {
|
|
stats.TotalUsers = total
|
|
}
|
|
if active, ok := userStats["active"].(int); ok {
|
|
stats.ActiveUsers = int64(active)
|
|
}
|
|
if inactive, ok := userStats["inactive"].(int); ok {
|
|
stats.InactiveUsers = int64(inactive)
|
|
}
|
|
if newThisMonth, ok := userStats["new_this_month"].(int); ok {
|
|
stats.NewThisMonth = int64(newThisMonth)
|
|
}
|
|
if byRole, ok := userStats["by_role"].(map[string]int64); ok {
|
|
stats.ByRole = byRole
|
|
}
|
|
|
|
return stats, nil
|
|
}
|
|
|
|
// MatchingStats represents matching statistics
|
|
type MatchingStats struct {
|
|
TotalMatches int64 `json:"totalMatches"`
|
|
ActiveMatches int64 `json:"activeMatches"`
|
|
SuccessfulMatches int64 `json:"successfulMatches"`
|
|
MatchRate float64 `json:"matchRate"`
|
|
}
|
|
|
|
// GetMatchingStats retrieves matching statistics
|
|
func (s *AdminService) GetMatchingStats(ctx context.Context, filters map[string]interface{}) (*MatchingStats, error) {
|
|
// TODO: Implement when matching service is available
|
|
stats := &MatchingStats{
|
|
TotalMatches: 0,
|
|
ActiveMatches: 0,
|
|
SuccessfulMatches: 0,
|
|
MatchRate: 0,
|
|
}
|
|
return stats, nil
|
|
}
|
|
|
|
// SystemHealth represents system health metrics
|
|
type SystemHealth struct {
|
|
Status string `json:"status"` // healthy, degraded, down
|
|
Database string `json:"database"`
|
|
Cache string `json:"cache"`
|
|
ExternalServices map[string]string `json:"externalServices"`
|
|
Uptime int64 `json:"uptime"` // seconds
|
|
ResponseTime int64 `json:"responseTime"` // milliseconds
|
|
ErrorRate float64 `json:"errorRate"`
|
|
ActiveConnections int64 `json:"activeConnections"`
|
|
}
|
|
|
|
// GetSystemHealth retrieves system health metrics
|
|
func (s *AdminService) GetSystemHealth(ctx context.Context) (*SystemHealth, error) {
|
|
health := &SystemHealth{
|
|
Status: "healthy",
|
|
Database: "connected",
|
|
Cache: "connected",
|
|
ExternalServices: make(map[string]string),
|
|
Uptime: 0,
|
|
ResponseTime: 0,
|
|
ErrorRate: 0,
|
|
}
|
|
|
|
// TODO: Implement actual health checks
|
|
// - Database connectivity
|
|
// - Cache connectivity
|
|
// - External service status
|
|
// - System metrics
|
|
|
|
return health, nil
|
|
}
|