Ensure completed request view is readonly

This commit is contained in:
Dominic Ferrando
2026-09-19 18:01:25 -04:00
parent dc7ebd6873
commit ae2ba4d317
2 changed files with 44 additions and 25 deletions
+8
View File
@@ -563,6 +563,10 @@ export const app = new Elysia()
params: t.Object({ id: t.String() }) params: t.Object({ id: t.String() })
}) })
.post("/:id/request-action", async ({ params: { id }, body: { reviewerNotes, activityVerifications } }) => { .post("/:id/request-action", async ({ params: { id }, body: { reviewerNotes, activityVerifications } }) => {
const verification = await s.Verifications.get(id);
if (!verification) throw new NotFoundError("Verification not found");
if (verification.status === "completed") throw status(409, { error: "Cannot modify a completed verification" });
const updated = await s.Verifications.requestAction(id, reviewerNotes ?? null, activityVerifications); const updated = await s.Verifications.requestAction(id, reviewerNotes ?? null, activityVerifications);
if (!updated) throw new NotFoundError("Verification not found"); if (!updated) throw new NotFoundError("Verification not found");
}, { }, {
@@ -573,6 +577,10 @@ export const app = new Elysia()
}) })
}) })
.post("/:id/complete", async ({ params: { id }, body: { activityVerifications }, accountId }) => { .post("/:id/complete", async ({ params: { id }, body: { activityVerifications }, accountId }) => {
const verification = await s.Verifications.get(id);
if (!verification) throw new NotFoundError("Verification not found");
if (verification.status === "completed") throw status(409, { error: "Cannot modify a completed verification" });
const updated = await s.Verifications.complete(id, accountId, activityVerifications); const updated = await s.Verifications.complete(id, accountId, activityVerifications);
if (!updated) throw new NotFoundError("Verification not found"); if (!updated) throw new NotFoundError("Verification not found");
}, { }, {
@@ -120,6 +120,7 @@
ACTIVITIES.filter((a) => verf[a] !== "unset").length, ACTIVITIES.filter((a) => verf[a] !== "unset").length,
); );
const allReviewed = $derived(reviewedCount === ACTIVITIES.length); const allReviewed = $derived(reviewedCount === ACTIVITIES.length);
const isReadOnly = $derived(verification?.status === "completed");
async function load() { async function load() {
loading = true; loading = true;
@@ -152,6 +153,7 @@
} }
function setVerf(activity: Activity, choice: VerfChoice) { function setVerf(activity: Activity, choice: VerfChoice) {
if (isReadOnly) return;
verf[activity] = choice; verf[activity] = choice;
} }
@@ -290,6 +292,7 @@
class="btn btn-sm {verf[activity] === 'pass' class="btn btn-sm {verf[activity] === 'pass'
? 'btn-success' ? 'btn-success'
: 'btn-outline btn-success'}" : 'btn-outline btn-success'}"
disabled={isReadOnly}
onclick={() => setVerf(activity, "pass")} onclick={() => setVerf(activity, "pass")}
> >
Pass Pass
@@ -298,13 +301,14 @@
class="btn btn-sm {verf[activity] === 'fail' class="btn btn-sm {verf[activity] === 'fail'
? 'btn-error' ? 'btn-error'
: 'btn-outline btn-error'}" : 'btn-outline btn-error'}"
disabled={isReadOnly}
onclick={() => setVerf(activity, "fail")} onclick={() => setVerf(activity, "fail")}
> >
Fail Fail
</button> </button>
<button <button
class="btn btn-sm btn-ghost" class="btn btn-sm btn-ghost"
disabled={verf[activity] === "unset"} disabled={isReadOnly || verf[activity] === "unset"}
onclick={() => setVerf(activity, "unset")} onclick={() => setVerf(activity, "unset")}
> >
Clear Clear
@@ -396,6 +400,7 @@
class="textarea textarea-bordered w-full" class="textarea textarea-bordered w-full"
rows="3" rows="3"
placeholder="What needs to be fixed?" placeholder="What needs to be fixed?"
disabled={isReadOnly}
bind:value={notes} bind:value={notes}
></textarea> ></textarea>
</label> </label>
@@ -415,6 +420,11 @@
&larr; Previous &larr; Previous
</button> </button>
{#if isReadOnly}
<span class="text-sm opacity-70"
>This verification is completed and read-only.</span
>
{:else}
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
{#if !allReviewed} {#if !allReviewed}
<span class="text-xs text-warning" <span class="text-xs text-warning"
@@ -440,6 +450,7 @@
: "Complete"} : "Complete"}
</button> </button>
</div> </div>
{/if}
</div> </div>
</div> </div>
{/if} {/if}