add dashboard conversation backend service

This commit is contained in:
Chen Gong 2024-11-07 09:12:10 -06:00
parent 100a31d9d4
commit 9876b7b43b
11 changed files with 192 additions and 0 deletions

View file

@ -26,9 +26,11 @@ public interface IBotSharpRepository
List<User> GetUserByIds(List<string> ids) => throw new NotImplementedException();
User? GetUserByAffiliateId(string affiliateId) => throw new NotImplementedException();
User? GetUserByUserName(string userName) => throw new NotImplementedException();
Dashboard? GetDashboard(string id = null) => throw new NotImplementedException();
void CreateUser(User user) => throw new NotImplementedException();
void UpdateExistUser(string userId, User user) => throw new NotImplementedException();
void UpdateUserVerified(string userId) => throw new NotImplementedException();
void AddDashboardConversation(string userId, string conversationId) => throw new NotImplementedException();
void UpdateUserVerificationCode(string userId, string verficationCode) => throw new NotImplementedException();
void UpdateUserPassword(string userId, string password) => throw new NotImplementedException();
void UpdateUserEmail(string userId, string email) => throw new NotImplementedException();

View file

@ -22,4 +22,6 @@ public interface IUserService
Task<bool> UpdatePassword(string newPassword, string verificationCode);
Task<DateTime> GetUserTokenExpires();
Task<bool> UpdateUsersIsDisable(List<string> userIds, bool isDisable);
Task<bool> AddDashboardConversation(string userId, string conversationId);
Task<Dashboard?> GetDashboard(string userId);
}

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BotSharp.Abstraction.Users.Models;
public class Dashboard
{
public IList<DashboardConversation> ConversationList { get; set; } = [];
}
public class DashboardComponent
{
public required string Id { get; set; }
public string? Name { get; set; }
}
public class DashboardConversation : DashboardComponent
{
public string? ConversationId { get; set; }
public string? Instruction { get; set; } = "Default instruction: Ask bot to do something";
}

View file

@ -23,6 +23,7 @@ public class User
public bool Verified { get; set; }
public string? AffiliateId { get; set; }
public bool IsDisabled { get; set; }
public List<DashboardConversation> DashboardConversations { get; set; } = [];
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
}

View file

@ -41,6 +41,11 @@ public partial class FileRepository
return Users.FirstOrDefault(x => x.UserName == userName.ToLower());
}
public Dashboard? GetDashboard(string id = null)
{
return Dashboards.FirstOrDefault();
}
public void CreateUser(User user)
{
var userId = Guid.NewGuid().ToString();
@ -68,4 +73,26 @@ public partial class FileRepository
var path = Path.Combine(dir, USER_FILE);
File.WriteAllText(path, JsonSerializer.Serialize(user, _options));
}
public void AddDashboardConversation(string userId, string conversationId)
{
var user = GetUserById(userId);
if (user == null) return;
// one user only has one dashboard currently
var dash = Dashboards.FirstOrDefault();
dash ??= new();
var dashconv = new DashboardConversation
{
Id = Guid.NewGuid().ToString(),
ConversationId = conversationId
};
dash.ConversationList.Add(dashconv);
var dir = Path.Combine(_dbSettings.FileRepository, USERS_FOLDER, userId);
var path = Path.Combine(dir, DASHBOARD_FILE);
File.WriteAllText(path, JsonSerializer.Serialize(dash, _options));
}
}

View file

@ -23,6 +23,7 @@ public partial class FileRepository : IBotSharpRepository
private const string AGENT_INSTRUCTION_FILE = "instruction";
private const string AGENT_SAMPLES_FILE = "samples.txt";
private const string USER_FILE = "user.json";
private const string DASHBOARD_FILE = "dashboard.json";
private const string USER_AGENT_FILE = "agents.json";
private const string CONVERSATION_FILE = "conversation.json";
private const string STATS_FILE = "stats.json";
@ -74,6 +75,7 @@ public partial class FileRepository : IBotSharpRepository
}
private List<User> _users = new List<User>();
private List<Dashboard> _dashboards = [];
private List<Agent> _agents = new List<Agent>();
private List<UserAgent> _userAgents = new List<UserAgent>();
private List<Conversation> _conversations = new List<Conversation>();
@ -106,6 +108,36 @@ public partial class FileRepository : IBotSharpRepository
}
}
private IQueryable<Dashboard> Dashboards
{
get
{
if (!_dashboards.IsNullOrEmpty())
{
return _dashboards.AsQueryable();
}
var dir = Path.Combine(_dbSettings.FileRepository, USERS_FOLDER);
_dashboards = [];
if (Directory.Exists(dir))
{
foreach (var d in Directory.GetDirectories(dir))
{
var dashboardFile = Path.Combine(d, DASHBOARD_FILE);
if (!Directory.Exists(d) || !File.Exists(dashboardFile))
continue;
var json = File.ReadAllText(dashboardFile);
var dash = JsonSerializer.Deserialize<Dashboard>(json, _options);
if (dash == null) continue;
_dashboards.Add(dash);
}
}
return _dashboards.AsQueryable();
}
}
private IQueryable<Agent> Agents
{
get

View file

@ -640,4 +640,21 @@ public class UserService : IUserService
}
return true;
}
public async Task<bool> AddDashboardConversation(string userId, string conversationId)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
db.AddDashboardConversation(userId, conversationId);
await Task.CompletedTask;
return true;
}
public async Task<Dashboard?> GetDashboard(string userId)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var dash = db.GetDashboard();
await Task.CompletedTask;
return dash;
}
}

View file

@ -490,6 +490,18 @@ public class ConversationController : ControllerBase
}
#endregion
#region miscellaneous
[HttpPut("/agent/{agentId}/conversation/{conversationId}/PinToDashboard")]
public async Task<bool> PinConversationToDashboard([FromRoute] string agentId, [FromRoute] string conversationId)
{
var userService = _services.GetRequiredService<IUserService>();
var user = await userService.GetUser(_user.Id);
var pinned = await userService.AddDashboardConversation(user.Id, conversationId);
return pinned;
}
#endregion
#region Private methods
private void SetStates(IConversationService conv, NewMessageModel input)
{

View file

@ -0,0 +1,47 @@
using BotSharp.Abstraction.Options;
using BotSharp.Abstraction.Users.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BotSharp.OpenAPI.Controllers;
[Authorize]
[ApiController]
public class DashboardController : ControllerBase
{
private readonly IServiceProvider _services;
private readonly IUserIdentity _user;
public DashboardController(IServiceProvider services,
IUserIdentity user,
BotSharpOptions options)
{
_services = services;
_user = user;
}
#region User Components
[HttpGet("/dashboard/components")]
public async Task<UserDashboardModel> GetComponents(string userId)
{
var userService = _services.GetRequiredService<IUserService>();
var dashboardProfile = await userService.GetDashboard(userId);
if (dashboardProfile == null) return new UserDashboardModel();
var result = new UserDashboardModel
{
ConversationList = dashboardProfile.ConversationList.Select(
x => new UserDashboardConversationModel
{
Name = x.Name,
ConversationId = x.ConversationId,
Instruction = x.Instruction
}
).ToList()
};
return result;
}
#endregion
}

View file

@ -12,6 +12,7 @@ public class ConversationViewModel
[JsonPropertyName("agent_name")]
public string AgentName { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; } = string.Empty;
public UserViewModel User { get; set; } = new UserViewModel();

View file

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace BotSharp.OpenAPI.ViewModels.Users;
public class UserDashboardModel
{
[JsonPropertyName("conversation_list")]
public IList<UserDashboardConversationModel> ConversationList { get; set; } = [];
}
public class UserDashboardConversationModel
{
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("conversation_id")]
public string? ConversationId { get; set; }
[JsonPropertyName("instruction")]
public string? Instruction { get; set; }
}