-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add landerPublishedAt #2511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add landerPublishedAt #2511
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe changes introduce a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant BrandingForm
participant updateProgramAction
participant PrismaDB
User->>BrandingForm: Submit publish form
BrandingForm->>updateProgramAction: Call with form data
updateProgramAction->>PrismaDB: Update Program (set landerPublishedAt if landerData)
PrismaDB-->>updateProgramAction: Return updated Program
updateProgramAction-->>BrandingForm: Return result
BrandingForm-->>User: Update UI, reset form state
sequenceDiagram
participant Script
participant CSVFile
participant PrismaDB
participant OutputCSV
Script->>CSVFile: Read raw lead event data
Script->>PrismaDB: Query Links by link IDs
Script->>PrismaDB: Query Customers by customer IDs (in chunks)
Script->>Script: Map events to link keys and customer external IDs
Script->>OutputCSV: Write processed events
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
@CodeRabbit final review pls |
|
Tip For best results, initiate chat on the files or code changes. @steven-tey Sure thing! However, I still need to look at the concrete code changes introduced on this branch before I can give you an informed “final review” (e.g. double-check types, query consistency, unused vars, perf regressions, etc.). Could you please re-run the bot with the repository checked out so I can inspect the actual diffs? Simply reply: (or “full review” if you prefer a ground-up sweep). |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (8)
packages/prisma/schema/program.prisma (1)
48-50: Consider indexinglanderPublishedAtfor frequent “is published?” look-upsThe sitemap, public pages, and application flow now filter on
WHERE landerPublishedAt IS NOT NULL.
Adding a single-column index will keep those queries snappy once the table grows.model Program { ... landerData Json? @db.Json landerPublishedAt DateTime? + + @@index(landerPublishedAt) resources Json? @db.Json ... }apps/web/lib/actions/partners/update-program.ts (1)
120-125: Revalidation trigger might fire spuriouslyBecause
landerDatais treated as truthy even when identical JSON is re-sent, every “save” causes expensiverevalidatePath()calls. A deep-equality check (or at leastJSON.stringifycomparison) againstprogram.landerDatawould reduce unnecessary cache invalidations.apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/apply/page.tsx (1)
18-20: Fine for now – but consider symmetry with the landing page guardThe apply form no longer checks
landerPublishedAt. If the landing page is hidden (unpublished) but/applyis guessed, users reach the form directly. Decide whether that’s intentional; if not, mirror the same guard as the landing page.apps/web/app/sitemap.ts (1)
22-25: Consider guarding against future-datedlanderPublishedAtand add an index for performance
- If
landerPublishedAtcan be set to a future timestamp (e.g. scheduled publishing), you probably want to exclude those programs from the sitemap:- landerPublishedAt: { - not: null, - }, + landerPublishedAt: { + not: null, + lte: new Date(), // exclude future-dated entries + },
- This field will now be part of a hot path that runs on every sitemap request. Add a composite database index on
(landerPublishedAt, landerData)to avoid a sequential scan as the table grows.apps/web/scripts/tinybird/delete-links.ts (1)
8-21: Build the data-source list once and loop – reduces duplicationSlight refactor eliminates repetition and makes adding/removing sources trivial.
- const deleteRes = await Promise.allSettled([ - deleteData({ dataSource: "dub_links_metadata", deleteCondition }), - deleteData({ dataSource: "dub_links_metadata_latest", deleteCondition }), - deleteData({ dataSource: "dub_regular_links_metadata_latest", deleteCondition }), - ]); + const sources = [ + "dub_links_metadata", + "dub_links_metadata_latest", + "dub_regular_links_metadata_latest", + ]; + + const deleteRes = await Promise.allSettled( + sources.map((dataSource) => deleteData({ dataSource, deleteCondition })), + );apps/web/scripts/framer/process-lead-events.ts (1)
99-103: Disconnect the Prisma client to allow Node to exit gracefully- fs.writeFileSync( + fs.writeFileSync( `processed_framer_lead_events_${BATCH}.csv`, Papa.unparse(processedData), ); + + await prisma.$disconnect();apps/web/ui/partners/design/branding-form.tsx (2)
127-129:getValuesis only needed for reset – avoid re-render triggers
getValuescauses a subscription; you can snapshot values insideonSuccesswithout storing the function informState.- formState: { isDirty, isSubmitting, isSubmitSuccessful }, - getValues, + formState: { isDirty, isSubmitting, isSubmitSuccessful },and inside
onSuccess:- const currentValues = getValues(); - reset(currentValues); + reset(undefined); // resets using latest defaultValues (already mutated)
157-162: SimplifydisablePublishButton– remove the ternaryLint flagged this; boolean coercion is sufficient.
- const disablePublishButton = - !isDirty && program.landerPublishedAt ? true : false; + const disablePublishButton = !isDirty && Boolean(program.landerPublishedAt);🧰 Tools
🪛 Biome (1.9.4)
[error] 161-161: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with(lint/complexity/noUselessTernary)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/apply/page.tsx(1 hunks)apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/layout.tsx(0 hunks)apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/page.tsx(1 hunks)apps/web/app/sitemap.ts(1 hunks)apps/web/lib/actions/partners/update-program.ts(1 hunks)apps/web/lib/zod/schemas/programs.ts(1 hunks)apps/web/scripts/framer/process-lead-events.ts(1 hunks)apps/web/scripts/tinybird/delete-links.ts(1 hunks)apps/web/ui/partners/design/branding-form.tsx(6 hunks)packages/prisma/schema/program.prisma(1 hunks)
💤 Files with no reviewable changes (1)
- apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/layout.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/ui/partners/design/branding-form.tsx (3)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-37)apps/web/lib/types.ts (1)
ProgramWithLanderDataProps(412-414)apps/web/lib/actions/partners/update-program.ts (1)
updateProgramAction(26-134)
🪛 Biome (1.9.4)
apps/web/ui/partners/design/branding-form.tsx
[error] 161-161: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (4)
apps/web/lib/zod/schemas/programs.ts (1)
47-50:landerPublishedAtfield added correctly – remember downstream serialization nuances👍 The new nullable date is declared consistently with
landerData(nullish()covers bothnull&undefined).
Just double-check all API layers that serialize this schema to JSON stringifyDateobjects (they’ll otherwise arrive as"2024-06-03T15:00:00.000Z"strings). If any client code still expects aDateinstance, add explicittransform()calls here.apps/web/lib/actions/partners/update-program.ts (1)
84-86:Details
❓ Verification inconclusive
landerPublishedAtis overwritten on every save – persist original publish timeEach update where
landerDatais truthy assigns a freshnew Date(), erasing the original publish timestamp (e.g., tweaking copy or color inadvertently resets “published” history).- landerPublishedAt: landerData ? new Date() : undefined, + // Set only the first time a lander is published + landerPublishedAt: + landerData && !program.landerPublishedAt + ? new Date() + : undefined,This preserves the initial publish date while still allowing manual null-reset via
landerData: null.
🏁 Script executed:
#!/bin/bash # Locate the update-program.ts file and display context around lines 1-200 file=$(rg -l "updateProgram" -g "apps/web/lib/actions/partners/update-program.ts") echo "Found file: $file" sed -n '1,200p' "$file"Length of output: 4301
🏁 Script executed:
#!/bin/bash # Display the contents of get-program-or-throw.ts to verify that landerPublishedAt is selected sed -n '1,200p' apps/web/lib/api/programs/get-program-or-throw.tsLength of output: 1866
🏁 Script executed:
#!/bin/bash # Locate and display schemas for ProgramSchema and ProgramWithLanderDataSchema sed -n '1,300p' apps/web/lib/zod/schemas/programs.tsLength of output: 4840
Persist original
landerPublishedAtonly on first publish and allow explicit reset
updateProgramActioncurrently always overwriteslanderPublishedAtwheneverlanderDatais truthy—and because you’re not loading the existinglanderPublishedAt, you cannot check if it’s already set. To fix:• In apps/web/lib/actions/partners/update-program.ts, load the old timestamp:
const program = await getProgramOrThrow( { workspaceId: workspace.id, programId }, { includeLanderData: true } );• In the
prisma.program.updatecall, replace the one-liner with conditional data branching:await prisma.program.update({ where: { id: programId }, data: { // …other fields… landerData: landerData === null ? Prisma.JsonNull : landerData, // explicit null-reset ...(landerData === null ? { landerPublishedAt: null } // first-time publish only : program.landerPublishedAt == null ? { landerPublishedAt: new Date() } : {}), domain, // …remaining fields… }, });This ensures:
- The first time you provide
landerData, the timestamp is set.- Subsequent updates (even if you tweak the data) won’t reset it.
- Passing
landerData: nullexplicitly clears both the JSON and the publish date.[fixed_required]
apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/page.tsx (1)
21-23: EnsurelanderPublishedAtis actually selected bygetProgram
getProgram()is invoked withinclude: ["rewards", "defaultDiscount"], butlanderPublishedAtis now critical for the 404 gate.
Verify the fetcher always returns this column; otherwise legitimately published programs might 404.apps/web/ui/partners/design/branding-form.tsx (1)
131-138: Minor:resetafter mutate can race – await bothEnsure the cache is updated before resetting form state.
- await mutateProgram(); - toast.success("Program updated successfully."); - // Reset form state to clear isSubmitSuccessful - const currentValues = getValues(); - reset(currentValues); + await mutateProgram(); + reset(getValues()); // clear dirty / submit flags + toast.success("Program updated successfully.");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (3)
apps/web/scripts/tinybird/delete-links.ts (2)
37-38: Fail fast whenTINYBIRD_API_KEYis missing
Same concern raised on the previous commit still applies – the request silently 401s if the env-var is not provided. Guard beforefetch.+if (!process.env.TINYBIRD_API_KEY) { + throw new Error("TINYBIRD_API_KEY is not set"); +}
40-40: URL-encode the form body to avoid malformed requests
deleteConditioncan contain spaces/quotes. UseURLSearchParamsinstead of string interpolation.- body: `delete_condition=${deleteCondition}`, + body: new URLSearchParams({ delete_condition: deleteCondition }).toString(),apps/web/scripts/framer/process-lead-events.ts (1)
30-31:⚠️ Potential issue
fs.createReadStreamsecond arg is mis-used (duplicate of earlier note)Passing the string
"utf-8"is treated as a file-system flag, not encoding.
Use an options object instead:- fs.createReadStream(`get_framer_lead_events_${BATCH}.csv`, "utf-8"), + fs.createReadStream(`get_framer_lead_events_${BATCH}.csv`, { + encoding: "utf-8", + }),
🧹 Nitpick comments (4)
apps/web/scripts/tinybird/delete-links.ts (1)
45-45: Add top-level error handling to avoid unhandled-rejection noise-main(); +main().catch((err) => { + console.error(err); + process.exit(1); +});packages/prisma/schema/program.prisma (1)
49-49: Consider indexinglanderPublishedAtfor query performanceBoth the sitemap generator and several UI checks now filter on
landerPublishedAt IS NOT NULL. Adding an index will keep those queries fast as data grows.@@index(domain) + @@index(landerPublishedAt)apps/web/scripts/framer/process-lead-events.ts (1)
25-27: Hard-coded workspace ID
const FRAMER_WORKSPACE_ID = "xxx";risks accidental commit of internal IDs.
Consider reading from an env var:-const FRAMER_WORKSPACE_ID = "xxx"; +const FRAMER_WORKSPACE_ID = + process.env.FRAMER_WORKSPACE_ID ?? (() => { throw new Error("FRAMER_WORKSPACE_ID missing"); })();apps/web/ui/partners/design/branding-form.tsx (1)
158-163: Simplify boolean expression & satisfy linterThe ternary is unnecessary and flagged by Biome. A concise, type-safe alternative:
-const disablePublishButton = - !isDirty && program.landerPublishedAt ? true : false; +const disablePublishButton = !isDirty && !!program.landerPublishedAt;🧰 Tools
🪛 Biome (1.9.4)
[error] 161-161: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with(lint/complexity/noUselessTernary)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/apply/page.tsx(1 hunks)apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/layout.tsx(0 hunks)apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/page.tsx(1 hunks)apps/web/app/sitemap.ts(1 hunks)apps/web/lib/actions/partners/update-program.ts(1 hunks)apps/web/lib/zod/schemas/programs.ts(1 hunks)apps/web/scripts/framer/process-lead-events.ts(1 hunks)apps/web/scripts/tinybird/delete-links.ts(1 hunks)apps/web/ui/partners/design/branding-form.tsx(6 hunks)packages/prisma/schema/program.prisma(1 hunks)
💤 Files with no reviewable changes (1)
- apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/layout.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/ui/partners/design/branding-form.tsx (3)
apps/web/lib/swr/use-program.ts (1)
useProgram(6-37)apps/web/lib/types.ts (1)
ProgramWithLanderDataProps(412-414)apps/web/lib/actions/partners/update-program.ts (1)
updateProgramAction(26-134)
🪛 Biome (1.9.4)
apps/web/ui/partners/design/branding-form.tsx
[error] 161-161: Unnecessary use of boolean literals in conditional expression.
Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with
(lint/complexity/noUselessTernary)
🔇 Additional comments (7)
apps/web/lib/zod/schemas/programs.ts (1)
48-50: Schema extension looks good
landerPublishedAtis correctly typed asz.date().nullish(), mirroring the Prisma model. No further action needed.apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/page.tsx (1)
21-22: Logic switch tolanderPublishedAtis sensible
The new guard aligns the 404 behaviour with the publish flag. Looks correct.apps/web/app/(ee)/partners.dub.co/(apply)/[programSlug]/apply/page.tsx (1)
18-20: Removal ofdefaultRewardIdguard – double-check downstream assumptionsDropping the
program.defaultRewardIdcheck means the page now renders even when no default reward is configured. Make sure every component on this page (ProgramRewardList,ProgramApplicationForm, etc.) behaves correctly whendefaultDiscount(or any reward-related props) arenull/undefined; otherwise users could hit runtime errors or see broken UI.If those components still require a default reward, consider re-introducing a guard or adding internal null handling.
apps/web/app/sitemap.ts (1)
22-24: LGTM – tighter filter improves sitemap correctnessAdding
landerPublishedAt: { not: null }ensures only published programs appear in partner sitemaps. Nice alignment with the new publication flow.apps/web/ui/partners/design/branding-form.tsx (3)
43-46: Renamedmutate→mutateProgramimproves clarityGood call; avoids shadowing and makes intent explicit.
127-138: Resetting withgetValues()– confirm draft syncUsing current values clears
isSubmitSuccessful, but it also resets theisDirtyflag even when local draft differs from remote state. Verify that the draft-saving logic still triggers when needed after a publish.
241-243: Disable condition now matches simplified flagAfter adopting the simplification above, remember to keep
disabled={disablePublishButton}as is—no further change needed.
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2511:
To re-run the tests, please comment |
TWilson023
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, will just highlight this comment in case you want to address that
|
🤖 Bug0 QA Agent Here are the results of the automated tests for PR #2511:
To re-run the tests, please comment |
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Chores