Skip to content

fix: keep Temporal workflow when a scheduled post is edited without a time change#1690

Open
giladresisi wants to merge 1 commit into
mainfrom
fix/edit-keep-workflow-unchanged-time
Open

fix: keep Temporal workflow when a scheduled post is edited without a time change#1690
giladresisi wants to merge 1 commit into
mainfrom
fix/edit-keep-workflow-unchanged-time

Conversation

@giladresisi

Copy link
Copy Markdown
Collaborator

Problem

Editing a future scheduled post — via the dashboard or the public API (POST /public/v1/posts with the existing ids) — sent type: 'schedule', which always terminated and recreated the post's Temporal workflow, even when only the content or settings changed and the publish time stayed the same. At 100k+ sleeping workflows that is needless churn (terminate + start per edit), and it diverged from the agent's updatePostTool, which already leaves the workflow alone for non-time changes.

Fix

Decide it server-side in PostsService.createPost: capture the post's current publish time before the upsert overwrites it, and only (re)start the workflow when it's a new post or an existing QUEUE post whose time actually moved. Content and settings are re-read from the DB at publish time, so an unchanged time needs no restart; a genuine time change still restarts it.

Done in the service (not the edit modal) so it's authoritative and covers every caller — dashboard and public API — and can't be fooled by client-side date state.

Testing (repro + validate, both surfaces)

Counted Temporal runs for the post before/after an identical time-unchanged edit:

Surface Without fix (main) With fix
Dashboard edit (settings only, same time) new workflow created no new workflow
POST /public/v1/posts (same ids, same time) 1 → 2 runs 2 → 2 runs

A real date change still recreates the workflow (TERMINATE_EXISTING, one new run) in both cases. Decision logic also spot-checked against real stored dates (unchanged → skip, moved → restart).

🤖 Generated with Claude Code

… time change

Editing a future scheduled post (dashboard or public API) sent type
'schedule', which always terminated and recreated the post's Temporal
workflow - even when only content or settings changed and the publish
time stayed the same. At 100k+ sleeping workflows that is needless
churn, and it diverges from the agent's updatePostTool, which already
leaves the workflow alone for non-time changes.

Decide it server-side in createPost: capture the post's current publish
time before the upsert, and only (re)start the workflow when it's a new
post or an existing QUEUE post whose time actually moved. Content and
settings are re-read from the DB at publish time, so an unchanged time
needs no restart; a genuine time change still restarts it.

Done in the service rather than the edit modal so it's authoritative and
covers every caller (dashboard, public API), and can't be fooled by
client-side date state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@postiz-contribution postiz-contribution Bot added the contribution:approved Approved contributor label Jul 8, 2026
@postiz-contribution

Copy link
Copy Markdown

Contribution-checker quality warning
Heuristic score: 0/100 (low). This is a non-blocking warning surfaced by the project's quality settings.

Heuristics that flagged:

  • Excessive inline code references: 7 inline refs (>3)
  • PR doesn't use the repo's PR template: 5 required checkbox items missing (max 1, match ≥80%)
  • Body adds too many extra headers beyond the template: 3 extra headers (>1)
  • AI watermark phrase: Matched: "Generated with Claude Code"
  • Commit message too long: Longest: 1056 chars
  • Excessive added comments: 7 added comment lines (ratio 0.44)

If this is a genuine contribution, please add detail to your PR description and tighten the diff scope before reviewers look at it.

@postiz-agent

postiz-agent Bot commented Jul 8, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

content: removeLinks ? stripLinks(updateContent[i]) : updateContent[i],
}));

const scheduledDate =

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: On non-UTC servers, creating a scheduledDate with dayjs().format() and parsing it with dayjs.utc() causes an incorrect time comparison for posts with type: 'now'.
Severity: MEDIUM

Suggested Fix

Ensure timezone consistency. When generating the scheduledDate for type === 'now', use dayjs.utc() to create a UTC-based time string. Replace dayjs().format('YYYY-MM-DDTHH:mm:00') with dayjs.utc().format('YYYY-MM-DDTHH:mm:00') to align the generated time with the UTC-based comparison logic used later.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts#L903

Potential issue: A timezone mismatch occurs when editing a post with `body.type ===
'now'` on a server not running in the UTC timezone. The code generates a `scheduledDate`
using `dayjs().format()`, which creates a string representing the server's local time
but lacks a timezone offset. This string is later parsed by `dayjs.utc()`, which
incorrectly assumes the time is in UTC. This discrepancy causes the time comparison
against the existing `publishDate` to fail, leading to an unnecessary workflow restart
even when the scheduled time has not been modified.

Did we get this right? 👍 / 👎 to inform future reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution:approved Approved contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant