-
Notifications
You must be signed in to change notification settings - Fork 18
basic challenge submission #27
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
Conversation
packages/nextjs/app/api/challenges/[challengeId]/submit/route.ts
Outdated
Show resolved
Hide resolved
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.
Looking good Shiv!! Thank you <3
Didn't test it, but left a first round of reviews.
P.S. Let's review #20 and coordinate with Pablo. But I think we could merge this first, back-merge into 20 and then merge 20?
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.
GREAT job Shiv! 🙌🔥
It's working nicely, just a couple of comments, we could review them in a future PR:
-
Sometimes when I submit a challenge, I can't see the challenge that I've just submitted in the builders page that opens, seems pretty random. After refreshing the page it appears.
-
Something strange with the
upsert
behaviour in the user_challenges table. Seems like it increases the id on update. It may be some default drizzle behaviour when there is a serialized id, need to investigate a bit more. If it's so, maybe we can change database schema and just delete that autonumeric id, sinceuserAddress
+challengeCode
could be a good primary key.
Ohh actually NextJs seems to cache the dynamic route in client when doing client side navigation ref. Your described could be nicely see if we Pushed an update at 4521936 so that after submiting the form the refetch the builders page so that we get updated data always when we move from challenge page => builders profile page after submitting the challenge.
Woahh yeah nice catch! Yeah thats the behviour of Here is the reson why postgresSQL have that design choicePostgreSQL increments the sequence counter during
This behavior is a trade-off between:
It's worth noting that sequence gaps can occur in many scenarios, not just with
This is why sequence numbers in PostgreSQL should never be relied upon to be strictly consecutive - they're guaranteed to be unique but not gap-free. So yeah lol we should be vigilant and not rely on serial id always being consecutive, sometime gap might be created in DB which is normal and reasons can be multiple not just Updated at 61334f8 to have composite key based on userAddress and challengeCode since that make sense! Thanks 🙌 |
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.
Woke up and found a great research! TYSM @technophile-04 ♥
The builder page is looking great and new primary key is working nicely too 🙌
const { mutate: submit, isPending } = useMutation({ | ||
mutationFn: async () => { | ||
if (!address) throw new Error("Wallet not connected"); | ||
try { | ||
new URL(frontendUrl); | ||
const etherscan = new URL(etherscanUrl); | ||
|
||
if (!VALID_BLOCK_EXPLORER_HOSTS.includes(etherscan.host)) { | ||
throw new Error("Please use a valid Etherscan testnet URL (Sepolia)"); | ||
} | ||
} catch (e) { | ||
throw new Error("Please enter valid URLs"); | ||
} | ||
|
||
const message = { | ||
...EIP_712_TYPED_DATA__CHALLENGE_SUBMIT.message, | ||
challengeId, | ||
frontendUrl, | ||
contractUrl: etherscanUrl, | ||
}; | ||
|
||
const signature = await signTypedDataAsync({ | ||
...EIP_712_TYPED_DATA__CHALLENGE_SUBMIT, | ||
message, | ||
}); | ||
|
||
return submitChallenge({ | ||
challengeId, | ||
userAddress: address, | ||
frontendUrl, | ||
contractUrl: etherscanUrl, | ||
signature, | ||
}); | ||
}, | ||
onSuccess: () => { | ||
notification.success("Challenge submitted successfully!"); | ||
router.push(`/builders/${address}`); | ||
router.refresh(); | ||
closeModal(); | ||
}, | ||
onError: (error: Error) => { | ||
notification.error(error.message); | ||
}, | ||
}); |
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.
As we talked in #21 (comment)
Would it make sense to move all the heavy data/logic into a hook?
Without thinking too much:
const { submitChallenge, isPending } = useSubmitChallenge({
onSuccess: closeModal,
});
// and then onClick
submitChallenge({
challengeId,
frontendUrl,
etherscanUrl,
});
Or if we wanted to give the hook more control
const {
frontendUrl,
setFrontendUrl,
etherscanUrl,
setEtherscanUrl,
submit,
isPending,
isValid,
} = useSubmitChallenge({
challengeId,
onSuccess: closeModal,
});
But probably Option 1 makes more sense?
What do you think?
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.
pushed at ed3d8e7
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.
I love it like this! Everything feels cleaner.
Thank you!
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.
Amazing stuff Shiv, thank you.
Just pushed ce814ce with a ToDo. Something I've been thinking and we need to take into consideration.
Merging this!!
Description:
Added the basic tables required for #11 and tried getting the flow correct.
/builders/[address]
page, where we show all the challenges submited and their status.For now we have
mockAutograding
which returns response to main autograder we can swap that later by making request to actual autograder.Demo
Screen.Recording.2025-02-18.at.5.23.33.PM.mov
To clean up the DB(might occur while testing both #20 and this PR):
data
dir from root of the repodocker compose down
docker compose up -d
yarn drizzle-kit push