Implement story integration foundation: - Create Domain/Entities/StorySegment.cs with full CRUD methods - Create Domain/Entities/StoryProgress.cs for user story progress tracking - Create Application/DTOs/StorySegmentDto.cs with multiple DTO types - Create Domain/Interfaces/IStoryRepository.cs - Create Domain/Interfaces/IStoryProgressRepository.cs - Create Infrastructure/Data/Repositories/StoryRepository.cs - Create Infrastructure/Data/Repositories/StoryProgressRepository.cs - Add DbSets and entity configurations to AppDbContext - Add navigation properties to Level, Lesson, and User entities Next: Phase 2 - Backend Services (StoryService, StoryGenerationService) Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
115 lines
4.7 KiB
C#
115 lines
4.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using GermanApp.Domain.Entities;
|
|
|
|
namespace GermanApp.Domain.Interfaces;
|
|
|
|
/// <summary>
|
|
/// Repository interface for managing StorySegment entities.
|
|
/// This is part of the Domain layer.
|
|
/// </summary>
|
|
public interface IStoryRepository
|
|
{
|
|
/// <summary>
|
|
/// Gets a story segment by its ID.
|
|
/// </summary>
|
|
/// <param name="id">The segment ID</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>The story segment or null if not found</returns>
|
|
Task<StorySegment?> GetByIdAsync(int id, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Gets all story segments for a specific level.
|
|
/// </summary>
|
|
/// <param name="levelId">The level ID</param>
|
|
/// <param name="includeInactive">Whether to include inactive segments</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>List of story segments ordered by Order</returns>
|
|
Task<IReadOnlyList<StorySegment>> GetByLevelAsync(
|
|
int levelId,
|
|
bool includeInactive = false,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Gets all story segments for a specific lesson.
|
|
/// </summary>
|
|
/// <param name="lessonId">The lesson ID</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>List of story segments associated with the lesson</returns>
|
|
Task<IReadOnlyList<StorySegment>> GetByLessonAsync(
|
|
int lessonId,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Gets the next segment to unlock for a user after completing a lesson.
|
|
/// </summary>
|
|
/// <param name="levelId">The level ID</param>
|
|
/// <param name="completedLessonOrder">The order of the completed lesson</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>The next story segment to unlock, or null if none</returns>
|
|
Task<StorySegment?> GetNextSegmentToUnlockAsync(
|
|
int levelId,
|
|
int completedLessonOrder,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Gets story segments by their order range.
|
|
/// </summary>
|
|
/// <param name="levelId">The level ID</param>
|
|
/// <param name="startOrder">Starting order (inclusive)</param>
|
|
/// <param name="endOrder">Ending order (inclusive)</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>List of story segments in the specified order range</returns>
|
|
Task<IReadOnlyList<StorySegment>> GetByOrderRangeAsync(
|
|
int levelId,
|
|
int startOrder,
|
|
int endOrder,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Adds a new story segment.
|
|
/// </summary>
|
|
/// <param name="segment">The story segment to add</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>The added segment with generated ID</returns>
|
|
Task<StorySegment> AddAsync(StorySegment segment, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Updates an existing story segment.
|
|
/// </summary>
|
|
/// <param name="segment">The story segment to update</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
Task UpdateAsync(StorySegment segment, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Deletes a story segment by its ID.
|
|
/// </summary>
|
|
/// <param name="id">The segment ID</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
Task DeleteAsync(int id, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Gets the highest order value for segments in a level.
|
|
/// </summary>
|
|
/// <param name="levelId">The level ID</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>The highest order value, or 0 if no segments exist</returns>
|
|
Task<int> GetMaxOrderAsync(int levelId, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Checks if a story segment exists for the given ID.
|
|
/// </summary>
|
|
/// <param name="id">The segment ID</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>True if the segment exists</returns>
|
|
Task<bool> ExistsAsync(int id, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Gets all story segments that need audio generation.
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>List of segments with null or empty AudioUrl</returns>
|
|
Task<IReadOnlyList<StorySegment>> GetSegmentsNeedingAudioAsync(
|
|
CancellationToken cancellationToken = default);
|
|
}
|