feat: add JSON-based data store for tickets and config
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
using Disco.Plugins.ServiceTracker.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.Plugins.ServiceTracker.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// JSON file-based data store for ServiceTracker metadata.
|
||||
/// Stores ticket extensions and configuration in the plugin data directory.
|
||||
/// </summary>
|
||||
public class ServiceTrackerDataStore
|
||||
{
|
||||
private readonly string _dataDirectory;
|
||||
private readonly string _ticketsPath;
|
||||
private readonly string _configPath;
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
public ServiceTrackerDataStore(string pluginDataDirectory)
|
||||
{
|
||||
_dataDirectory = pluginDataDirectory;
|
||||
_ticketsPath = Path.Combine(_dataDirectory, "tickets.json");
|
||||
_configPath = Path.Combine(_dataDirectory, "config.json");
|
||||
|
||||
if (!Directory.Exists(_dataDirectory))
|
||||
Directory.CreateDirectory(_dataDirectory);
|
||||
}
|
||||
|
||||
// --- Configuration ---
|
||||
|
||||
public ServiceTrackerConfig LoadConfig()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (!File.Exists(_configPath))
|
||||
{
|
||||
var defaultConfig = ServiceTrackerConfig.CreateDefault();
|
||||
SaveConfig(defaultConfig);
|
||||
return defaultConfig;
|
||||
}
|
||||
var json = File.ReadAllText(_configPath);
|
||||
return JsonConvert.DeserializeObject<ServiceTrackerConfig>(json) ?? ServiceTrackerConfig.CreateDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveConfig(ServiceTrackerConfig config)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
File.WriteAllText(_configPath, json);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Tickets ---
|
||||
|
||||
public List<ServiceTicket> LoadAllTickets()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (!File.Exists(_ticketsPath))
|
||||
return new List<ServiceTicket>();
|
||||
|
||||
var json = File.ReadAllText(_ticketsPath);
|
||||
return JsonConvert.DeserializeObject<List<ServiceTicket>>(json) ?? new List<ServiceTicket>();
|
||||
}
|
||||
}
|
||||
|
||||
public ServiceTicket GetTicket(int jobId)
|
||||
{
|
||||
return LoadAllTickets().FirstOrDefault(t => t.JobId == jobId);
|
||||
}
|
||||
|
||||
public void SaveTicket(ServiceTicket ticket)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var tickets = LoadAllTicketsUnsafe();
|
||||
var existing = tickets.FindIndex(t => t.JobId == ticket.JobId);
|
||||
ticket.LastModifiedDate = DateTime.Now;
|
||||
|
||||
if (existing >= 0)
|
||||
tickets[existing] = ticket;
|
||||
else
|
||||
tickets.Add(ticket);
|
||||
|
||||
SaveAllTicketsUnsafe(tickets);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteTicket(int jobId)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var tickets = LoadAllTicketsUnsafe();
|
||||
tickets.RemoveAll(t => t.JobId == jobId);
|
||||
SaveAllTicketsUnsafe(tickets);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddNote(int jobId, TicketNote note)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var tickets = LoadAllTicketsUnsafe();
|
||||
var ticket = tickets.FirstOrDefault(t => t.JobId == jobId);
|
||||
if (ticket != null)
|
||||
{
|
||||
if (ticket.Notes == null)
|
||||
ticket.Notes = new List<TicketNote>();
|
||||
ticket.Notes.Add(note);
|
||||
ticket.LastModifiedDate = DateTime.Now;
|
||||
SaveAllTicketsUnsafe(tickets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Internal methods (caller must hold lock)
|
||||
private List<ServiceTicket> LoadAllTicketsUnsafe()
|
||||
{
|
||||
if (!File.Exists(_ticketsPath))
|
||||
return new List<ServiceTicket>();
|
||||
var json = File.ReadAllText(_ticketsPath);
|
||||
return JsonConvert.DeserializeObject<List<ServiceTicket>>(json) ?? new List<ServiceTicket>();
|
||||
}
|
||||
|
||||
private void SaveAllTicketsUnsafe(List<ServiceTicket> tickets)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(tickets, Formatting.Indented);
|
||||
File.WriteAllText(_ticketsPath, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user