Skip to content

feat(posts): support scheduled publishing#3974

Merged
idoshamun merged 2 commits into
mainfrom
codex/scheduled-posts
Jul 2, 2026
Merged

feat(posts): support scheduled publishing#3974
idoshamun merged 2 commits into
mainfrom
codex/scheduled-posts

Conversation

@idoshamun

Copy link
Copy Markdown
Member

Summary

  • Add scheduled freeform post creation using flags.scheduledAt and hidden visibility until publish time.
  • Add scheduled post listing plus schedule editing through the existing post edit mutation.
  • Wire CDC to Temporal so scheduled posts publish later, refresh createdAt/score on publish, and cancel stale workflows on edit/delete/publish.
  • Add a partial index for scheduled post flag lookups and focused GraphQL/Temporal tests.

Validation

  • pnpm run build
  • pnpm run lint
  • NODE_ENV=test npx jest __tests__/posts.ts --testEnvironment=node --runInBand
  • NODE_ENV=test npx jest __tests__/temporal/notifications/activities.ts __tests__/temporal/notifications/utils.ts --testEnvironment=node --runInBand
  • NODE_ENV=test npx jest __tests__/temporal/notifications/workflows.ts --testEnvironment=node --runInBand

@idoshamun idoshamun force-pushed the codex/scheduled-posts branch from 93da7fb to ce9ded4 Compare July 2, 2026 12:57
@pulumi

pulumi Bot commented Jul 2, 2026

Copy link
Copy Markdown

🍹 The Update (preview) for dailydotdev/api/prod (at d33b947) was successful.

Resource Changes

    Name                                                    Type                           Operation
~   vpc-native-check-analytics-report-cron                  kubernetes:batch/v1:CronJob    update
~   vpc-native-temporal-deployment                          kubernetes:apps/v1:Deployment  update
~   vpc-native-hourly-notification-cron                     kubernetes:batch/v1:CronJob    update
~   vpc-native-materialize-monthly-best-post-archives-cron  kubernetes:batch/v1:CronJob    update
~   vpc-native-bg-deployment                                kubernetes:apps/v1:Deployment  update
~   vpc-native-squad-posts-analytics-refresh-cron           kubernetes:batch/v1:CronJob    update
~   vpc-native-personalized-digest-cron                     kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tags-str-cron                         kubernetes:batch/v1:CronJob    update
~   vpc-native-sync-subscription-with-cio-cron              kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-opportunities-cron              kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-gifted-plus-cron                       kubernetes:batch/v1:CronJob    update
~   vpc-native-update-highlighted-views-cron                kubernetes:batch/v1:CronJob    update
~   vpc-native-user-profile-analytics-clickhouse-cron       kubernetes:batch/v1:CronJob    update
~   vpc-native-validate-active-users-cron                   kubernetes:batch/v1:CronJob    update
~   vpc-native-channel-highlights-cron                      kubernetes:batch/v1:CronJob    update
~   vpc-native-ws-deployment                                kubernetes:apps/v1:Deployment  update
~   vpc-native-personalized-digest-deployment               kubernetes:apps/v1:Deployment  update
~   vpc-native-update-achievement-rarity-cron               kubernetes:batch/v1:CronJob    update
~   vpc-native-deployment                                   kubernetes:apps/v1:Deployment  update
~   vpc-native-worker-job-deployment                        kubernetes:apps/v1:Deployment  update
~   vpc-native-private-deployment                           kubernetes:apps/v1:Deployment  update
~   vpc-native-expire-super-agent-trial-cron                kubernetes:batch/v1:CronJob    update
-   vpc-native-api-clickhouse-migration-6c5c6ea8            kubernetes:batch/v1:Job        delete
~   vpc-native-user-posts-analytics-refresh-cron            kubernetes:batch/v1:CronJob    update
~   vpc-native-update-source-public-threshold-cron          kubernetes:batch/v1:CronJob    update
~   vpc-native-subscription-anniversary-achievements-cron   kubernetes:batch/v1:CronJob    update
~   vpc-native-generic-referral-reminder-cron               kubernetes:batch/v1:CronJob    update
~   vpc-native-post-lifecycle-state-clickhouse-cron         kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-user-companies-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tag-materialized-views-cron           kubernetes:batch/v1:CronJob    update
~   vpc-native-update-current-streak-cron                   kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-images-cron                     kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-stale-user-transactions-cron           kubernetes:batch/v1:CronJob    update
~   vpc-native-update-trending-cron                         kubernetes:batch/v1:CronJob    update
-   vpc-native-api-db-migration-6c5c6ea8                    kubernetes:batch/v1:Job        delete
+   vpc-native-api-clickhouse-migration-0fcce16f            kubernetes:batch/v1:Job        create
~   vpc-native-user-profile-updated-sync-cron               kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-expired-better-auth-sessions-cron      kubernetes:batch/v1:CronJob    update
~   vpc-native-calculate-top-readers-cron                   kubernetes:batch/v1:CronJob    update
~   vpc-native-rotate-daily-quests-cron                     kubernetes:batch/v1:CronJob    update
~   vpc-native-daily-digest-cron                            kubernetes:batch/v1:CronJob    update
... and 15 other changes

Comment thread src/common/postScheduling.ts Outdated
visible: true,
visibleAt: now,
createdAt: now,
score: getPostScore(now),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why do we need score? Is it something we have anywhere?

Comment thread src/common/postScheduling.ts
Comment thread src/common/postScheduling.ts Outdated
export const getPostScheduledAt = ({
flags,
}: PostScheduleFlagsInput): Date | null => {
const parsedFlags =

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why flags can be a string?

Comment thread src/common/postScheduling.ts Outdated
Comment on lines +108 to +109
deleted: false,
banned: false,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

we shouldnt touch these fields. ignore them

Comment thread src/entity/posts/Post.ts Outdated
@Index('IDX_post_flags_banned', { synchronize: false })
@Index('IDX_post_flags_deleted', { synchronize: false })
@Index('IDX_post_flags_vordr', { synchronize: false })
@Index('IDX_post_flags_scheduledAt', { synchronize: false })

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why do we need this index?

Comment thread src/schema/posts.ts Outdated
includeInvisiblePosts?: boolean;
};

const withInvisiblePosts = (

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't like this prototype hacking. Suggest alternatives

@idoshamun idoshamun left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I see a lot Object.prototype tricks which I dont really like and we have no where else in the codebase.

Have we added the new workflow to our temporal service here so it won't be left out?

@idoshamun idoshamun marked this pull request as ready for review July 2, 2026 13:35
@idoshamun idoshamun merged commit b24b06e into main Jul 2, 2026
9 checks passed
@idoshamun idoshamun deleted the codex/scheduled-posts branch July 2, 2026 13:35
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.

1 participant