feat(post): embed a quoted post in a post - #239
Closed
aquie00t wants to merge 1 commit into
Closed
Conversation
A post can now quote another post, the way a quote tweet does: POST /posts takes an optional quotedPostId and every post response carries a quotedPost card, or null. The relation is self-referential on Post and cascades, so deleting a post deletes every post that quotes it and a card can never point at content that is gone. The card is deliberately lean - author, content, media and date, no counters and no viewer-specific flags - so embedding one costs no extra joins, and the include stops at one level, so a quote of a quote carries the post it quotes and nothing behind it. The quoted post is resolved before the write, so quoting an id that is already gone answers 404 rather than a constraint violation. The feed cache revives the nested date by hand: without it the same request would answer with a Date on a miss and a string for the next 60 seconds. Counters, notifications and a list of quoters follow in their own changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015JC6UgjwRSJ3KHToPYqBPC
This was referenced Aug 30, 2026
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Alıntı özelliğinin 4 PR'a bölünmüş hâlinin ilki: veri modeli, alıntı oluşturma ve alıntının yanıtta görünmesi.
Ne değişti
Post'aquotedPostId+ self-relation (PostQuotes,ON DELETE CASCADE) ve index. Migration elle yazıldı ve gerekçelendirildi.POST /postsgövdesine opsiyonelquotedPostId. Ayrı endpoint yok, tek oluşturma yolu korundu.quotedPosttaşıyor: yalın kart (yazar, içerik, medya, tarih) ya danull.PostItemSchemaortak olduğu için feed, kullanıcı postları, post detayı, create yanıtı ve bookmark listesi tek düzenlemeden yararlanıyor.quotedPost.createdAtelle canlandırılıyor; olmasa aynı istek cache miss'teDate, sonraki 60 saniyestringdönerdi.Kararlar
SET NULLalternatifi, "hiç alıntılamadı" ile "alıntıladığı silindi" ayrımı için ikinci bir kolon isterdi; ileride istenirse tek migration'lık iş.likeCount/isLikedtaşınmadığı için gömme ekstra join getirmiyor.postInclude()yardımcı fonksiyonu yerinePOST_AUTHOR_SELECT/QUOTED_POST_INCLUDEsabitleri kullanıldı: dönüş tipiniPrisma.PostIncludeyapmak payload çıkarımını genişletip mevcut cast'leri 4 yerde TS2352 ile bozuyordu.Doğrulama
pnpm test:unit→ 877/877 geçti (mapper +6, create-post +4, get-posts cache +2 yeni test).pnpm lint,pnpm format:check,tsc --noEmittemiz.migrate diffsıfır drift.quotedPostIdyazımı, kartıncreate/findById/findAll'da dönmesi, tek seviye gömme ve cascade silmenin iki seviyeye ulaşması doğrulandı.migrate resetçalışmadığı için CI'da koşacaklar.Sonraki PR'lar
quoteCountsayacı +CreatePostUseCase'inTransactionPort'a taşınmasıNotificationType.QUOTE+ realtime bildirimGET /posts/:id/quotes+ metinsiz alıntı (saf repost)🤖 Generated with Claude Code
https://claude.ai/code/session_015JC6UgjwRSJ3KHToPYqBPC