Overview
All models live insrc/DualMind.API/Core/Models/. They use [JsonProperty("snake_case")] for Supabase compatibility.
All C# models use
[JsonProperty("snake_case")] attributes because Supabase PostgREST returns snake_case column names. The backend serializes responses as camelCase for the frontend.Entity models
User
public class User
{
[JsonProperty("user_id")] public Guid? UserId { get; set; }
[JsonProperty("full_name")] public string? FullName { get; set; }
[JsonProperty("email")] public string? Email { get; set; }
[JsonProperty("role")] public string? Role { get; set; } = "user";
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
[JsonProperty("last_login_at")] public DateTime? LastLoginAt { get; set; }
}
AIModel
public class AIModel
{
[JsonProperty("model_id")] public Guid? ModelId { get; set; }
[JsonProperty("model_name")] public string? ModelName { get; set; }
[JsonProperty("provider_name")] public string? ProviderName { get; set; }
[JsonProperty("api_url")] public string? ApiUrl { get; set; }
[JsonProperty("description")] public string? Description { get; set; }
[JsonProperty("status")] public string? Status { get; set; } = "active";
[JsonProperty("created_by")] public Guid? CreatedBy { get; set; }
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
[JsonProperty("updated_at")] public DateTime? UpdatedAt { get; set; }
}
Comparison
public class Comparison
{
[JsonProperty("comparison_id")] public Guid? ComparisonId { get; set; }
[JsonProperty("user_id")] public Guid? UserId { get; set; }
[JsonProperty("prompt_text")] public string? PromptText { get; set; }
[JsonProperty("model1_id")] public Guid? Model1Id { get; set; }
[JsonProperty("model2_id")] public Guid? Model2Id { get; set; }
[JsonProperty("model1_response")]public string? Model1Response { get; set; }
[JsonProperty("model2_response")]public string? Model2Response { get; set; }
[JsonProperty("model1_time_ms")] public int? Model1TimeMs { get; set; }
[JsonProperty("model2_time_ms")] public int? Model2TimeMs { get; set; }
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
}
ModelVote
public class ModelVote
{
[JsonProperty("vote_id")] public Guid? VoteId { get; set; }
[JsonProperty("user_id")] public Guid? UserId { get; set; }
[JsonProperty("comparison_id")] public Guid? ComparisonId { get; set; }
[JsonProperty("winner_model_id")] public Guid? WinnerModelId { get; set; }
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
}
ChatThread
public class ChatThread
{
[JsonProperty("thread_id")] public Guid? ThreadId { get; set; }
[JsonProperty("user_id")] public Guid? UserId { get; set; }
[JsonProperty("title")] public string? Title { get; set; }
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
}
ThreadMessage
public class ThreadMessage
{
[JsonProperty("message_id")] public Guid? MessageId { get; set; }
[JsonProperty("thread_id")] public Guid? ThreadId { get; set; }
[JsonProperty("prompt_text")] public string? PromptText { get; set; }
[JsonProperty("model1_id")] public Guid? Model1Id { get; set; }
[JsonProperty("model2_id")] public Guid? Model2Id { get; set; }
[JsonProperty("model1_response")] public string? Model1Response { get; set; }
[JsonProperty("model2_response")] public string? Model2Response { get; set; }
[JsonProperty("model1_time_ms")] public int? Model1TimeMs { get; set; }
[JsonProperty("model2_time_ms")] public int? Model2TimeMs { get; set; }
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
}
Provider and ProviderApiKey
public class Provider
{
[JsonProperty("provider_name")] public string? ProviderName { get; set; }
[JsonProperty("display_name")] public string? DisplayName { get; set; }
[JsonProperty("is_enabled")] public bool IsEnabled { get; set; }
[JsonProperty("priority")] public int Priority { get; set; }
[JsonProperty("created_at")] public DateTime? CreatedAt { get; set; }
[JsonProperty("updated_at")] public DateTime? UpdatedAt { get; set; }
}
public class ProviderApiKey
{
[JsonProperty("key_id")] public Guid KeyId { get; set; }
[JsonProperty("provider_name")] public string? ProviderName { get; set; }
[JsonProperty("api_key")] public string? ApiKey { get; set; }
[JsonProperty("display_mask")] public string? DisplayMask { get; set; }
[JsonProperty("is_active")] public bool IsActive { get; set; }
[JsonProperty("failure_count")] public int FailureCount { get; set; }
[JsonProperty("total_calls")] public int TotalCalls { get; set; }
[JsonProperty("last_used_at")] public DateTime? LastUsedAt { get; set; }
[JsonProperty("last_error_type")] public string? LastErrorType { get; set; }
[JsonProperty("cooldown_until")] public DateTime? CooldownUntil { get; set; }
[JsonProperty("created_by")] public Guid? CreatedBy { get; set; }
}
Request DTOs
ChatRequest (AI contracts)
public class ChatRequest
{
public string? ThreadId { get; set; }
public string? Prompt { get; set; }
public string? System { get; set; }
public string? Model { get; set; }
public string? Model1 { get; set; }
public string? Model2 { get; set; }
public string? SelectionMode { get; set; }
public int? MaxTokens { get; set; }
public double? Temperature { get; set; }
}
VoteRequest
public class VoteRequest
{
public Guid ComparisonId { get; set; }
public string WinnerModelName { get; set; }
public Guid? UserId { get; set; }
}
CreateThreadRequest
public class CreateThreadRequest
{
public string? Title { get; set; }
public Guid? UserId { get; set; }
}
SyncUserRequest
public class SyncUserRequest
{
public string Id { get; set; }
public string Email { get; set; }
public string? Phone { get; set; }
public string? Name { get; set; }
public string? AvatarUrl { get; set; }
public string? Provider { get; set; }
}
Response DTOs
ChatResponse
public class ChatResponse
{
public string Object { get; set; } // "ai.response"
public ContentOutput Output { get; set; }
public bool Success { get; set; }
public string Message { get; set; } // Convenience shortcut
public ModelInfo Model { get; set; }
public string Prompt { get; set; }
public string SelectionMode { get; set; }
public long ResponseTimeMs { get; set; }
public UsageInfo Usage { get; set; }
public DateTime Timestamp { get; set; }
}
public class ModelInfo
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string Provider { get; set; }
}
public class UsageInfo
{
public int PromptTokens { get; set; }
public int CompletionTokens { get; set; }
public int TotalTokens { get; set; }
}
GroqResponse (internal)
public class GroqResponse
{
public string Message { get; set; }
public string Model { get; set; }
public int PromptTokens { get; set; }
public int CompletionTokens { get; set; }
public int TotalTokens { get; set; }
}
ModelStatsDto
public class ModelStatsDto
{
public Guid ModelId { get; set; }
public string ModelName { get; set; }
public string ProviderName { get; set; }
public int TotalWins { get; set; }
public int TotalResponses { get; set; }
public double WinRate { get; set; }
}
FeatureFlagResponse
public class FeatureFlagResponse
{
public string Key { get; set; }
public bool Enabled { get; set; }
}