Skip to content

PROD | Tasks App - Task(s) Created Using Template Not Saving - #1386

Merged
arpandhakal merged 12 commits into
productionfrom
main
Jul 10, 2026
Merged

PROD | Tasks App - Task(s) Created Using Template Not Saving#1386
arpandhakal merged 12 commits into
productionfrom
main

Conversation

@arpandhakal

Copy link
Copy Markdown
Collaborator

No description provided.

cursor Bot and others added 11 commits July 2, 2026 11:08
* Handle expected Prisma request errors
* Warn on known Prisma errors instead of silencing them
…orkspaces (#1366)

* feat(notifications): evaluation-framed reminder emails for override workspaces
…mplate

Applying a template fanned out every sub-template's task creation at once
via Promise.all. For a template with many sub-templates (e.g. 90), the ~90
concurrent createTask calls exhausted the Prisma connection pool, so some
subtasks failed to save and the subsequent task-detail query timed out
(P2024 / "Timed out fetching a new connection from the connection pool").

Run the fan-out in bounded batches (subtaskTemplateBatchSize) so concurrency
stays small regardless of pool size. Ordering is preserved (timestamp is
still derived from index). Applied at both the internal and public API
template-apply sites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
createSubtasksFromTemplate rolled back on failure by soft-deleting `parentId`
— which is the *parent* (main) task, not the failed subtask. So any single
subtask-creation error (e.g. the connection-pool P2024) silently deleted the
task the user had just created and verified, and Realtime made it vanish from
their screen ("task disappeared on its own" in OUT-3964). The rollback was also
wrong (it orphaned already-created sibling subtasks) and unnecessary — createTask
already cleans up a half-created subtask via its own catch.

Now each subtemplate is applied best-effort: the whole per-subtemplate unit
(getAppliedTemplateDescription + create) runs inside one try/catch that skips
and logs on failure instead of throwing. Because the handler no longer rejects,
runInBatches never aborts, so every subtemplate is attempted and one failure no
longer skips later batches or returns an error after a partial write (fixes the
two P1 review findings). The parent task is never deleted or orphaned.

Refactored createSubtasksFromTemplate to object params and folded the applied-
description fetch inside it, so both the internal and public call sites share the
same failure isolation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per product decision: don't apply a template partially or fail silently. If any
subtask fails to create, roll back the parent task and throw, so the caller gets
a clear error instead of a half-populated task with silently-missing subtasks.

The concurrency batching from the earlier commit is retained and is what makes
this safe: it prevents the connection-pool exhaustion (P2024) that was causing
the failures — and would otherwise trigger this rollback and make the task
"disappear". The rollback now also covers a failed getAppliedTemplateDescription
(folded inside the try), so any failure rolls back consistently.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…late-fanout

OUT-3964 | Tasks App - Task(s) Created Using Template Not Saving
@arpandhakal
arpandhakal requested a review from priosshrsth July 10, 2026 08:55
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tasks-app Ready Ready Preview, Comment Jul 10, 2026 8:56am

Request Review

@arpandhakal arpandhakal self-assigned this Jul 10, 2026
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Deployment failed with the following error:

Deploying Serverless Functions to multiple regions is restricted to the Pro and Enterprise plans.

Learn More: https://vercel.link/multiple-function-regions

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates task template subtask creation and reminder email copy. The main changes are:

  • Bounded batch processing for subtasks created from templates.
  • Subtemplate description lookup moved into the shared subtask helper.
  • Evaluation-specific HTML reminder email bodies for override workspaces.
  • Tests and snapshots updated for the new reminder payload shape.

Confidence Score: 4/5

The changed reminder override path and template rollback path need fixes before merging.

  • Override reminders can be sent without body or htmlBody when the evaluation title becomes empty.
  • Batched subtask creation can delete the parent while sibling subtasks from the same batch are still writing.
  • The HTML escaping change looks appropriate for the current text-content insertion point.

src/jobs/notifications/send-reminder-email.ts; src/app/api/tasks/tasksShared.service.ts

Important Files Changed

Filename Overview
src/jobs/notifications/send-reminder-email.ts Builds override reminder emails with HTML bodies and no plain-text fallback.
src/app/api/notification/notification.helpers.ts Adds optional evaluation-specific HTML reminder copy and escapes interpolated titles.
src/app/api/tasks/tasksShared.service.ts Refactors subtask template creation and rolls back the parent when a subtask fails.
src/app/api/tasks/tasks.service.ts Uses bounded batches when applying subtask templates during internal task creation.
src/app/api/tasks/public/public.service.ts Uses the same bounded subtask template batching for public task creation.
src/utils/array.ts Adds generic chunking and bounded batch execution helpers.
src/constants/tasks.ts Adds the fixed subtask template batch size constant.

Comments Outside Diff (2)

  1. src/jobs/notifications/send-reminder-email.ts, line 44-50 (link)

    P1 Override Email Has No Body

    When an override workspace produces an empty evaluationTitle, getReminderEmailDetails returns htmlBody: undefined and this branch still omits the plain body. JSON.stringify drops the undefined field, so Copilot can receive an email with subject/header/title but no message content, causing the reminder to render empty or fail delivery while the job treats notification creation as successful.

  2. src/app/api/tasks/tasksShared.service.ts, line 626-633 (link)

    P1 Rollback Races Sibling Subtasks

    The callers now run up to five subtemplate handlers at the same time, but this catch deletes the parent from inside the first failing handler. Promise.all does not cancel the other handlers in that batch, so sibling subtasks can continue writing against a parent that is being deleted, leaving a partially applied template or failed sibling rollback instead of the intended all-or-nothing task creation.

Reviews (1): Last reviewed commit: "Merge branch 'production' into main" | Re-trigger Greptile

@arpandhakal
arpandhakal merged commit e08a327 into production Jul 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants