using ClaudeDo.Data.Models; using Microsoft.EntityFrameworkCore; namespace ClaudeDo.Data.Repositories; public sealed class SessionSkillRepository { private readonly ClaudeDoDbContext _context; public SessionSkillRepository(ClaudeDoDbContext context) => _context = context; public async Task> ListAsync(CancellationToken ct = default) { return await _context.SessionSkills.AsNoTracking() .OrderBy(s => s.Name) .ToListAsync(ct); } public async Task GetAsync(string name, CancellationToken ct = default) => await _context.SessionSkills.AsNoTracking().FirstOrDefaultAsync(s => s.Name == name, ct); public async Task UpsertAsync(SessionSkillEntity entity, CancellationToken ct = default) { var existing = await _context.SessionSkills.FirstOrDefaultAsync(s => s.Name == entity.Name, ct); if (existing is null) { _context.SessionSkills.Add(entity); } else { existing.SourceUrl = entity.SourceUrl; existing.PinnedRef = entity.PinnedRef; existing.Subpath = entity.Subpath; existing.Description = entity.Description; existing.AddedAt = entity.AddedAt; } await _context.SaveChangesAsync(ct); } public async Task DeleteAsync(string name, CancellationToken ct = default) { await _context.SessionSkills .Where(s => s.Name == name) .ExecuteDeleteAsync(ct); } public async Task DeleteBySourceAsync(string sourceUrl, CancellationToken ct = default) { await _context.SessionSkills .Where(s => s.SourceUrl == sourceUrl) .ExecuteDeleteAsync(ct); } public async Task> ListBySourceAsync(string sourceUrl, CancellationToken ct = default) { return await _context.SessionSkills.AsNoTracking() .Where(s => s.SourceUrl == sourceUrl) .OrderBy(s => s.Name) .ToListAsync(ct); } }