Skip to content

feat: create/publish posts & replies + upsert hardening - #3

Merged
chrisgeo merged 18 commits into
mainfrom
feat/publish-and-upsert-hardening
May 20, 2026
Merged

feat: create/publish posts & replies + upsert hardening#3
chrisgeo merged 18 commits into
mainfrom
feat/publish-and-upsert-hardening

Conversation

@chrisgeo

Copy link
Copy Markdown
Contributor

Summary

  • Upsert hardening (threads-core / threads-store / threads-ingest / provider): pure Post::merge, integrated into upsert_post_tx gated on the @username sentinel so a sparse reply-edge re-fetch can't clobber richer stored data, while full (numeric-author) fetches still overwrite. dto_to_post now synthesizes the @username sentinel; ingest persists the me profile and runs resolve_author to rewrite @handle posts to the real numeric id (fixes the engagement-seed miss).
  • Create/publish (manifest / threads-core / provider / threads-cli): new threads-cli post create command publishing text/image/video/carousel posts and replies via the official two-step flow (create container → poll status for media → publish), with remote quota preflight (250 posts / 1000 replies via threads_publishing_limit), a confirm-then-publish gate, and after-publish upsert into the local store. Adds HttpClient::post_json, 7 Provider methods, response DTOs, manifest actions/objects, and the threads_content_publish scope. Carousel uses type-safe create_carousel_item/create_carousel_container (no magic-string sentinels).
  • Design spec + two TDD plans committed under docs/superpowers/.

Test Plan

  • cargo test --workspace — 164/164 pass
  • cargo clippy --workspace --all-targets -- -D warnings — clean
  • Manual: threads-cli auth login (acquire threads_content_publish), then threads-cli post create --text "hello" --yes → verify it posts and is stored locally (threads-cli show <id>)
  • Manual: threads-cli post create --reply-to <own-post-id> --text "reply" → verify the reply
  • Manual (optional): --image-url <public-https> single + carousel (≥2)

Notes

  • Replying to other users' posts needs threads_keyword_search/threads_manage_mentions (surfaced as a non-blocking warning).
  • Deferred minors: inject is_terminal into the confirm gate for testability; thin tests for poll error-states / stdin; synthesize_post.root_id is approximate for nested replies on the fetch-failure fallback.

chrisgeo added 18 commits May 20, 2026 11:56
Integrate Post::merge into upsert_post_tx so that re-upserting a sparse
reply-edge version of an existing post (identifiable by a @username sentinel
author) never overwrites richer stored fields (text, created_at, permalink,
media, urls, mentions, is_quote_post, real author id).
…ublishing_limits/fetch_post + carousel methods to Provider trait
@chrisgeo
chrisgeo merged commit aac18f4 into main May 20, 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.

1 participant