d3ro-voice/apps/api-server/Dtos/Dtos.cs
Yun Chan 5a34f66981 feat(admin): 예전/최신 어드민 통합 — 실데이터 복원 + 인증 아키텍처 정리
예전 배포본(HEAD)의 상세 기능을 새 아키텍처(인증=.NET 백엔드, 데이터=Supabase)
위에 실데이터로 복원. 예전 HEAD는 서명 쿠키를 거부하고 위조 쿠키는 통과시키는
인증 결함이 있었고, 삭제된 페이지 다수는 백엔드 호출 0인 하드코딩 목업이었음.

인증/세션
- 로그인 이메일 전용화(username 폐지), 에러 키별 안내 메시지
- ADMIN_COOKIE_SECURE 옵션: TLS 없는 LAN HTTP 배포에서 Secure 쿠키 유실로
  로그인이 유지되지 않던 문제 해결 (login/logout route, admin-session, compose, .env.example)
- Supabase 미설정 시 우아한 저하: isSupabaseAdminConfigured + UnavailableAdminPanel

기능 복원 (실데이터)
- Release Hub: Forgejo API 실데이터(다운로드 수/SHA-256 체크섬/릴리스 이력)
- Ad Monetization: 데스크톱 미디에이션 10개 어댑터 로스터(fail-closed) + ad_reward_claims 통계
- License Issuer: 서버사이드 Ed25519 서명(/api/admin/license, super_admin 전용),
  개인키는 ADMIN_LICENSE_PRIVATE_KEY env로만, 발급 감사를 .NET AdminAuditEntries에 기록
- Service Models: STT 7종/LLM 5종 프리셋 드롭다운 + 자동채움
- 대시보드 ARR/MRR KPI: Supabase 구독 실집계(티어 월단가 기반)
- 사용자 상세 티어별 기능 배지(pro_plus 조건부)

.NET
- SuperAdminOnly 정책 추가, /api/admin/license-audit 엔드포인트, LicenseAuditDto
2026-08-23 23:38:08 +09:00

190 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
namespace D3ROVoice.Api.Dtos;
// Auth DTOs
public record RegisterDto(string Email, string Password);
public record LoginDto(string Email, string Password);
public record AuthResponseDto(string Token, string Email, string Role, DateTime ExpiresAt);
public record UserInfoDto(int Id, string Email, string Role, DateTime CreatedAt, DateTime? LastLoginAt, bool IsActive);
// License issuance audit trail (offline Ed25519 license keys issued from the admin console)
public record LicenseAuditDto(
string LicenseId,
string CustomerEmail,
string Tier,
string Validity,
long? ExpiresAt);
// LLM DTOs
public record LlmGenerateRequest(string Prompt, string? Model = null, string? SystemPrompt = null, double Temperature = 0.7, int MaxTokens = 2048);
public record LlmGenerateResponse(string Text, string Model, int PromptTokens, int CompletionTokens, double TotalDurationMs, decimal Cost);
public record LlmChatMessage(string Role, string Content);
public record LlmChatRequest(List<LlmChatMessage> Messages, string? Model = null, double Temperature = 0.7, int MaxTokens = 2048);
// Admin DTOs
public record CreateModelEndpointDto(
string ModelId,
string ModelName,
string Provider,
string EndpointUrl,
string ApiKey,
decimal CostPer1kPromptTokens,
decimal CostPer1kCompletionTokens,
string? Memo = null
);
public record UpdateModelEndpointDto(
string ModelName,
string Provider,
string EndpointUrl,
string ApiKey,
decimal CostPer1kPromptTokens,
decimal CostPer1kCompletionTokens,
bool IsActive,
string? Memo = null
);
public record ServerStatsDto(
int TotalUsers,
int ActiveUsersToday,
int TotalRequests,
decimal TotalCost,
double ServerUptimeSeconds,
int ErrorCount,
List<ServerErrorLogDto> RecentErrors
);
public record ServerErrorLogDto(int Id, string ErrorType, string Message, string? Endpoint, DateTime CreatedAt);
public record UsageReportDto(
int TotalRequests,
int TotalPromptTokens,
int TotalCompletionTokens,
decimal TotalCost,
List<UserUsageSummaryDto> UserSummaries,
List<ModelUsageSummaryDto> ModelSummaries
);
public record UserUsageSummaryDto(int UserId, string Email, int TotalRequests, int TotalTokens, decimal TotalCost);
public record ModelUsageSummaryDto(string ModelId, string ModelName, int TotalRequests, int TotalTokens, decimal TotalCost);
// STT DTOs
public record SttTranscribeRequest(
string? AudioBase64 = null,
string? Language = "ko",
string? InitialPrompt = null,
string? ModelId = null,
string? Provider = null,
double? Temperature = 0.0
);
public record SttTranscribeResponse(
string Text,
double Confidence,
string Language,
double DurationSeconds,
string Provider,
string ModelId,
double LatencyMs,
decimal Cost
);
public record SttProviderEndpointDto(
int Id,
string Name,
string ProviderType,
string EndpointUrl,
string ApiKey,
string ModelId,
string Method,
string Language,
string? Prompt,
double Temperature,
decimal CostPerMinute,
decimal CostPerSecond,
bool IsDefault,
bool IsActive,
int FallbackPriority,
string? ExtraHeadersJson,
DateTime CreatedAt,
DateTime? UpdatedAt
);
public record CreateSttEndpointDto(
string Name,
string ProviderType,
string EndpointUrl,
string? ApiKey,
string ModelId,
string Method,
string? Language,
string? Prompt,
double Temperature,
decimal CostPerMinute,
decimal CostPerSecond,
bool IsDefault,
bool IsActive,
int FallbackPriority,
string? ExtraHeadersJson,
string? Memo = null
);
public record UpdateSttEndpointDto(
string Name,
string ProviderType,
string EndpointUrl,
string? ApiKey,
string ModelId,
string Method,
string? Language,
string? Prompt,
double Temperature,
decimal CostPerMinute,
decimal CostPerSecond,
bool IsDefault,
bool IsActive,
int FallbackPriority,
string? ExtraHeadersJson,
string? Memo = null
);
public record AdminActionDto(string? Memo);
public record SttTestResultDto(
bool Success,
string Message,
double LatencyMs,
string? TranscriptPreview,
string? Provider,
string? ModelId
);
public record DirectSttTestDto(string EndpointUrl, string? ApiKey);
public record SttUsageReportDto(
int TotalTranscriptions,
double TotalAudioMinutes,
decimal TotalCost,
double AvgLatencyMs,
List<SttProviderUsageSummaryDto> ProviderSummaries,
List<SttUserUsageSummaryDto> UserSummaries
);
public record SttProviderUsageSummaryDto(
string Provider,
string ModelId,
int TotalRequests,
double TotalAudioMinutes,
decimal TotalCost,
double AvgLatencyMs
);
public record SttUserUsageSummaryDto(
int UserId,
string Email,
int TotalRequests,
double TotalAudioMinutes,
decimal TotalCost
);