Conversation
refactor: optimize path change handling with useCallback for better p…
feat: add Android install banner component
feat: enhance video handling in HeroBackdropVideo component
clean up
gpt-realtime-2
* gpt-realtime-2 * chore : bump next version * fix: adjust padding for navbar action items * fix: native tab bar (mobile) * exclude logging * chore: reorg * chore: make things more modular wrt voice agents * feat: make voice agent more reliable * feat: enhance loading state and animations for markdown components * fixes to voice agent * fix: remove set state from useeffects & use react activity * feat: add prefetching to delete link and navigation links in NavBar * fix: styling of voice input * experiment
* gpt-realtime-2 * chore : bump next version * fix: adjust padding for navbar action items * fix: native tab bar (mobile) * exclude logging * chore: reorg * chore: make things more modular wrt voice agents * feat: make voice agent more reliable * feat: enhance loading state and animations for markdown components * fixes to voice agent * fix: remove set state from useeffects & use react activity * feat: add prefetching to delete link and navigation links in NavBar * fix: styling of voice input * experiment
chore: disable youtube hero backdrop variant
chatgpt apps
fix apps
fix load
fix padding
[codex] add claude hero background
Co-authored-by: theg1239 <theg1239@users.noreply.github.com>
Co-authored-by: theg1239 <theg1239@users.noreply.github.com>
Co-authored-by: theg1239 <theg1239@users.noreply.github.com>
…-bfb3 fix: protect unpublished papers and incomplete markdown caches
…-f78f fix: sanitize MCP widget links
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR bundles several independent improvements: an AI model rename (
Confidence Score: 4/5Safe to merge; all changes are additive hardening with no breaking interface changes. The transaction wrapper and new answer-key guard in the metadata action are logically correct and improve data integrity. The isClear filter and cache-key rename in past-paper-detail are a clean, consistent pair. The XSS fix in the widget is straightforward and well-applied. The only minor concerns are a redundant ne clause and the expected slow expiry of old Redis cache entries under the previous key prefix. app/actions/update-paper-metadata.ts and lib/data/past-paper-detail.ts carry the most logic change and are worth a quick second read. Important Files Changed
Sequence DiagramsequenceDiagram
participant Mod as Moderator
participant Action as updatePaperMetadata
participant DB as Database (tx)
participant Cache as Next.js/Redis Cache
Mod->>Action: submit metadata update
Action->>Action: auth check (MODERATOR only)
Action->>Action: zod schema parse
Action->>DB: BEGIN TRANSACTION
DB->>DB: fetch existingPaper (get previousQuestionPaperId)
alt "hasAnswerKey = true"
DB->>DB: fetch questionPaper
DB->>DB: check conflictingLink (another answer key for same QP?)
DB->>DB: check linkedAnswerKey (current paper already a question paper?)
end
DB->>DB: UPDATE pastPaper SET ...
DB->>Action: "COMMIT → {questionPaperId, previousQuestionPaperId}"
Action->>Cache: revalidateTag(past_paper:id)
Action->>Cache: revalidateTag(past_paper:previousQuestionPaperId)
Action->>Cache: revalidateTag(past_paper:questionPaperId)
Action->>Cache: invalidatePastPapersSurfaceCache()
Action-->>Mod: "{success: true}"
|
| const [linkedAnswerKey] = await tx | ||
| .select({ | ||
| id: pastPaper.id, | ||
| title: pastPaper.title, | ||
| }) | ||
| .from(pastPaper) | ||
| .where( | ||
| and( | ||
| eq(pastPaper.questionPaperId, parsed.id), | ||
| ne(pastPaper.id, parsed.id), | ||
| ), | ||
| ) | ||
| .limit(1); |
There was a problem hiding this comment.
The
ne(pastPaper.id, parsed.id) predicate in the linkedAnswerKey query is never effective. The query already filters on eq(pastPaper.questionPaperId, parsed.id), so the only row whose id could equal parsed.id would be a paper whose questionPaperId equals its own id — a self-reference that is caught earlier in the same transaction. Removing the redundant clause makes the intent clearer.
| const [linkedAnswerKey] = await tx | |
| .select({ | |
| id: pastPaper.id, | |
| title: pastPaper.title, | |
| }) | |
| .from(pastPaper) | |
| .where( | |
| and( | |
| eq(pastPaper.questionPaperId, parsed.id), | |
| ne(pastPaper.id, parsed.id), | |
| ), | |
| ) | |
| .limit(1); | |
| const [linkedAnswerKey] = await tx | |
| .select({ | |
| id: pastPaper.id, | |
| title: pastPaper.title, | |
| }) | |
| .from(pastPaper) | |
| .where( | |
| eq(pastPaper.questionPaperId, parsed.id), | |
| ) | |
| .limit(1); |
No description provided.