Add dev hook for basic location review rebuild
This commit is contained in:
parent
1cf0174466
commit
66e28b7f0e
@ -1,5 +1,7 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using PlotLine.Data;
|
||||
using PlotLine.Models;
|
||||
using PlotLine.Services;
|
||||
using PlotLine.ViewModels;
|
||||
@ -23,8 +25,17 @@ public sealed class AdminController(
|
||||
IStoryIntelligenceImportCommitService storyIntelligenceImportCommit,
|
||||
INameIntelligenceService nameIntelligence,
|
||||
IIllustrationLibraryService illustrationLibrary,
|
||||
IProjectRepository projects,
|
||||
IBookRepository books,
|
||||
IOnboardingBuildRepository onboardingBuilds,
|
||||
ICoreImportBasicLocationService coreImportBasicLocations,
|
||||
IWebHostEnvironment environment,
|
||||
ILogger<AdminController> logger) : Controller
|
||||
{
|
||||
private static readonly Guid DiscoveryBasicLocationReviewPreviewId = Guid.Parse("50760000-3068-4000-8000-000000005076");
|
||||
private const int DiscoveryProjectId = 3068;
|
||||
private const int DiscoveryBookId = 5076;
|
||||
|
||||
[HttpGet("")]
|
||||
[HttpGet("index")]
|
||||
public async Task<IActionResult> Index()
|
||||
@ -41,6 +52,110 @@ public sealed class AdminController(
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet("development/core-basic-location-review/discovery")]
|
||||
public async Task<IActionResult> DevelopmentDiscoveryBasicLocationReview(bool reset = true)
|
||||
{
|
||||
if (!environment.IsDevelopment())
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (currentUser.UserId is not int userId)
|
||||
{
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
var project = await projects.GetAsync(DiscoveryProjectId);
|
||||
var book = await books.GetAsync(DiscoveryBookId);
|
||||
if (project is null || book is null || book.ProjectID != DiscoveryProjectId)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var sceneSources = await onboardingBuilds.ListSceneManuscriptSourcesByBookAsync(DiscoveryBookId);
|
||||
if (sceneSources.Count == 0)
|
||||
{
|
||||
TempData["AdminError"] = "Book 5076 has no canonical scene source text to prepare.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
await coreImportBasicLocations.ResetAndPrepareAsync(userId, DiscoveryBasicLocationReviewPreviewId, DiscoveryProjectId, DiscoveryBookId, null, sceneSources);
|
||||
}
|
||||
else
|
||||
{
|
||||
await coreImportBasicLocations.EnsurePreparedAsync(userId, DiscoveryBasicLocationReviewPreviewId, DiscoveryProjectId, DiscoveryBookId, null, sceneSources);
|
||||
}
|
||||
|
||||
var model = await coreImportBasicLocations.GetReviewAsync(
|
||||
userId,
|
||||
DiscoveryBasicLocationReviewPreviewId,
|
||||
"Discovery retained Book 5076",
|
||||
project.ProjectName,
|
||||
book.BookDisplayTitle);
|
||||
if (model is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return View("~/Views/Onboarding/ScanLocations.cshtml", new CoreImportBasicLocationReviewViewModel
|
||||
{
|
||||
PreviewID = model.PreviewID,
|
||||
ReviewID = model.ReviewID,
|
||||
Status = model.Status,
|
||||
DocumentTitle = model.DocumentTitle,
|
||||
SelectedProjectName = model.SelectedProjectName,
|
||||
SelectedBookTitle = model.SelectedBookTitle,
|
||||
FormController = "Admin",
|
||||
FormAction = nameof(SaveDevelopmentDiscoveryBasicLocationReview),
|
||||
ContinueButtonText = "Save selected locations",
|
||||
RawObservationCount = model.RawObservationCount,
|
||||
CandidateCount = model.CandidateCount,
|
||||
Candidates = model.Candidates,
|
||||
ExistingLocationOptions = model.ExistingLocationOptions
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("development/core-basic-location-review/discovery")]
|
||||
[RequestFormLimits(ValueCountLimit = 20000, KeyLengthLimit = 4096, ValueLengthLimit = 1024 * 1024)]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SaveDevelopmentDiscoveryBasicLocationReview(CoreImportBasicLocationReviewForm form, string intent = "save")
|
||||
{
|
||||
if (!environment.IsDevelopment())
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (currentUser.UserId is not int userId)
|
||||
{
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
if (form.PreviewID != DiscoveryBasicLocationReviewPreviewId)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
if (string.Equals(intent, "skip", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await coreImportBasicLocations.SkipAsync(userId, form.PreviewID);
|
||||
TempData["AdminMessage"] = "Development basic location review skipped for Book 5076.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
await coreImportBasicLocations.SaveDecisionsAsync(userId, form);
|
||||
if (string.Equals(intent, "continue", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await coreImportBasicLocations.CompleteAsync(userId, form.PreviewID);
|
||||
TempData["AdminMessage"] = "Development basic location review materialised selected locations for Book 5076.";
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
TempData["OnboardingReviewMessage"] = "Development location review choices saved.";
|
||||
return RedirectToAction(nameof(DevelopmentDiscoveryBasicLocationReview), new { reset = false });
|
||||
}
|
||||
|
||||
[HttpPost("name-intelligence/validate")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ValidateNameIntelligence(CancellationToken cancellationToken)
|
||||
|
||||
@ -7,6 +7,7 @@ namespace PlotLine.Data;
|
||||
public interface ICoreImportBasicLocationReviewRepository
|
||||
{
|
||||
Task<CoreImportBasicLocationReview?> GetByPreviewAsync(int userId, Guid previewId);
|
||||
Task ResetByPreviewAsync(int userId, Guid previewId);
|
||||
Task<CoreImportBasicLocationReview> CreateAsync(int userId, Guid previewId, int projectId, int bookId, int? buildId);
|
||||
Task<CoreImportBasicLocationCandidate> SaveCandidateAsync(int reviewId, CoreImportBasicLocationCandidate candidate);
|
||||
Task DeleteEvidenceAsync(int candidateId);
|
||||
@ -30,6 +31,15 @@ public sealed class CoreImportBasicLocationReviewRepository(ISqlConnectionFactor
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
|
||||
public async Task ResetByPreviewAsync(int userId, Guid previewId)
|
||||
{
|
||||
using var connection = connectionFactory.CreateConnection();
|
||||
await connection.ExecuteAsync(
|
||||
"dbo.CoreImportBasicLocationReview_ResetByPreview",
|
||||
new { UserID = userId, PreviewID = previewId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
|
||||
public async Task<CoreImportBasicLocationReview> CreateAsync(int userId, Guid previewId, int projectId, int bookId, int? buildId)
|
||||
{
|
||||
using var connection = connectionFactory.CreateConnection();
|
||||
|
||||
@ -8,6 +8,7 @@ namespace PlotLine.Services;
|
||||
public interface ICoreImportBasicLocationService
|
||||
{
|
||||
Task<CoreImportBasicLocationReview?> EnsurePreparedAsync(int userId, Guid previewId, int projectId, int bookId, int? buildId, IReadOnlyList<SceneManuscriptSourceRecord> sceneSources);
|
||||
Task<CoreImportBasicLocationReview?> ResetAndPrepareAsync(int userId, Guid previewId, int projectId, int bookId, int? buildId, IReadOnlyList<SceneManuscriptSourceRecord> sceneSources);
|
||||
Task<CoreImportBasicLocationReviewViewModel?> GetReviewAsync(int userId, Guid previewId, string documentTitle, string projectName, string bookTitle);
|
||||
Task<bool> IsCompleteAsync(int userId, Guid previewId);
|
||||
Task SaveDecisionsAsync(int userId, CoreImportBasicLocationReviewForm form);
|
||||
@ -57,6 +58,18 @@ public sealed class CoreImportBasicLocationService(
|
||||
return await reviews.GetByPreviewAsync(userId, previewId);
|
||||
}
|
||||
|
||||
public async Task<CoreImportBasicLocationReview?> ResetAndPrepareAsync(
|
||||
int userId,
|
||||
Guid previewId,
|
||||
int projectId,
|
||||
int bookId,
|
||||
int? buildId,
|
||||
IReadOnlyList<SceneManuscriptSourceRecord> sceneSources)
|
||||
{
|
||||
await reviews.ResetByPreviewAsync(userId, previewId);
|
||||
return await EnsurePreparedAsync(userId, previewId, projectId, bookId, buildId, sceneSources);
|
||||
}
|
||||
|
||||
public async Task<CoreImportBasicLocationReviewViewModel?> GetReviewAsync(int userId, Guid previewId, string documentTitle, string projectName, string bookTitle)
|
||||
{
|
||||
var review = await reviews.GetByPreviewAsync(userId, previewId);
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
SET ANSI_NULLS ON;
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE dbo.CoreImportBasicLocationReview_ResetByPreview
|
||||
@UserID int,
|
||||
@PreviewID uniqueidentifier
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DELETE dbo.CoreImportBasicLocationReviews
|
||||
WHERE UserID = @UserID
|
||||
AND PreviewID = @PreviewID;
|
||||
END;
|
||||
GO
|
||||
@ -956,6 +956,9 @@ public sealed class CoreImportBasicLocationReviewViewModel
|
||||
public string DocumentTitle { get; init; } = "Word manuscript";
|
||||
public string SelectedProjectName { get; init; } = string.Empty;
|
||||
public string SelectedBookTitle { get; init; } = string.Empty;
|
||||
public string FormController { get; init; } = "Onboarding";
|
||||
public string FormAction { get; init; } = "SaveBasicLocations";
|
||||
public string ContinueButtonText { get; init; } = "Save locations and review characters";
|
||||
public int RawObservationCount { get; init; }
|
||||
public int CandidateCount { get; init; }
|
||||
public IReadOnlyList<CoreImportBasicLocationCandidateViewModel> Candidates { get; init; } = [];
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form asp-controller="Onboarding" asp-action="SaveBasicLocations" method="post">
|
||||
<form asp-controller="@Model.FormController" asp-action="@Model.FormAction" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<input type="hidden" name="PreviewID" value="@Model.PreviewID" />
|
||||
|
||||
@ -122,7 +122,7 @@
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-secondary" type="submit" name="intent" value="save">Save choices</button>
|
||||
<button class="btn btn-outline-secondary" type="submit" name="intent" value="skip">Skip locations</button>
|
||||
<button class="btn btn-primary" type="submit" name="intent" value="continue">Save locations and review characters</button>
|
||||
<button class="btn btn-primary" type="submit" name="intent" value="continue">@Model.ContinueButtonText</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user