-
Notifications
You must be signed in to change notification settings - Fork 6
Add printer market #116
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 printer market #116
Conversation
Introduces database schema and migration for printers and printer orders, including new enums and relations. Adds admin and public UI for managing printers and upgrades in the dashboard, with create, update, and delete functionality. Updates Svelte components and database schema to support the new printer market feature.
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.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 11 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for (const item of selectedItems) { | ||
| if (item.startsWith('marketItem-')) { | ||
| const id = parseInt(item.slice('marketItem-'.length)); | ||
| if (!id) throw error(400, { message: 'malformed market item filter' }); | ||
| marketItemFilter.push(id); | ||
| } else if (item.startsWith('printer-')) { | ||
| const id = parseInt(item.slice('printer-'.length)); | ||
| if (!id) throw error(400, { message: 'malformed printer filter' }); | ||
| printerFilter.push(id); |
Copilot
AI
Jan 18, 2026
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.
The validation check 'parseInt(id) || null' at line 68 and 72 will incorrectly treat a valid ID of 0 as invalid because 0 is falsy in JavaScript. While printer IDs likely start at 1, this is still a potential bug. The validation should use 'isNaN(id)' or 'id === 0' explicitly if 0 is an invalid ID, rather than relying on truthiness checks.
| const name = formData.get('name')?.toString(); | ||
| const description = formData.get('description')?.toString(); | ||
| const image = formData.get('image')?.toString(); | ||
| const isBase = formData.get('isBase') === 'on'; |
Copilot
AI
Jan 18, 2026
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.
The 'isBase' field is being checked via 'formData.get('isBase') === 'on'', but 'isBase' is not a form field name that's actually submitted from the admin form. The form uses a checkbox with id 'isBase' that changes the local 'formType' state, but there's no hidden input or form field named 'isBase' being submitted. This will cause the server to always treat submissions as upgrades (isBase will always be false), leading to incorrect data being saved.
| const isBase = formData.get('isBase') === 'on'; | |
| const formType = formData.get('formType')?.toString() || 'base'; | |
| const isBase = formType === 'base'; |
| class="h-4 w-4" | ||
| /> | ||
| <label for="isBase" class="font-semibold cursor-pointer">Base Printer</label> | ||
| </div> |
Copilot
AI
Jan 18, 2026
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.
The admin form is missing a hidden input or proper form field to submit whether the printer is a base printer or upgrade. The checkbox at line 157-167 changes local state (formType) but doesn't have a 'name' attribute, so the server won't receive this information. This causes the server-side logic at line 29 and 70 of +page.server.ts to always evaluate 'isBase' as false. Add a hidden input field that tracks the formType value, or add a 'name' attribute to the checkbox.
| </div> | |
| </div> | |
| <input type="hidden" name="isBase" value={formType === 'base' ? 'true' : 'false'} /> |
| <label class="block"> | ||
| <span class="mb-1 block font-semibold">Min Shop Score</span> | ||
| <input | ||
| type="number" | ||
| name="minShopScore" | ||
| bind:value={form.minShopScore} | ||
| min="0" | ||
| class="w-full rounded-lg border border-primary-700 bg-primary-900 p-2 text-primary-100" | ||
| /> | ||
| </label> | ||
| <label class="block"> | ||
| <span class="mb-1 block font-semibold">Max Shop Score</span> | ||
| <input | ||
| type="number" | ||
| name="maxShopScore" | ||
| bind:value={form.maxShopScore} | ||
| min="0" | ||
| class="w-full rounded-lg border border-primary-700 bg-primary-900 p-2 text-primary-100" | ||
| /> | ||
| </label> | ||
| <label class="block"> |
Copilot
AI
Jan 18, 2026
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.
There's inconsistent indentation with mixed tabs and spaces. Line 184 and 204 use spaces for indentation while the rest of the file uses tabs. This should be corrected to maintain consistent code formatting throughout the file.
| if (locals.user.idvToken) { | ||
| let userData = null; | ||
|
|
||
| try { | ||
| const token = decrypt(locals.user.idvToken); | ||
| userData = await getUserData(token); | ||
| } catch { | ||
| userDataError = true; | ||
| } | ||
|
|
||
| addresses = userData?.addresses; | ||
| } else { | ||
| userDataError = true; | ||
| } | ||
|
|
||
| return { | ||
| printerData: { | ||
| ...basePrinter, | ||
| clayPrice: basePrinter.clayPrice || 40 | ||
| }, | ||
| isBase: true, | ||
| addresses, | ||
| userDataError | ||
| }; | ||
| } else { | ||
| const [upgrade] = await db | ||
| .select() | ||
| .from(printer) | ||
| .where( | ||
| and( | ||
| eq(printer.deleted, false), | ||
| eq(printer.isPublic, true), | ||
| eq(printer.id, id), | ||
| isNotNull(printer.requiresId) | ||
| ) | ||
| ) | ||
| .limit(1); | ||
|
|
||
| if (!upgrade) { | ||
| throw error(404, { message: 'printer upgrade not found' }); | ||
| } | ||
|
|
||
| const computedPrice = calculateMarketPrice( | ||
| upgrade.minPrice, | ||
| upgrade.maxPrice, | ||
| upgrade.minShopScore, | ||
| upgrade.maxShopScore, | ||
| locals.user.shopScore | ||
| ); | ||
|
|
||
| const discountAmount = (upgrade.maxPrice - computedPrice) / upgrade.maxPrice; | ||
|
|
||
| let userDataError = false; | ||
| let addresses = null; | ||
|
|
||
| if (locals.user.idvToken) { | ||
| let userData = null; | ||
|
|
||
| try { | ||
| const token = decrypt(locals.user.idvToken); | ||
| userData = await getUserData(token); | ||
| } catch { | ||
| userDataError = true; | ||
| } | ||
|
|
||
| addresses = userData?.addresses; | ||
| } else { | ||
| userDataError = true; | ||
| } |
Copilot
AI
Jan 18, 2026
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.
There's duplicated code for fetching user address data. Lines 36-49 and lines 91-104 contain identical logic for fetching addresses via idvToken. This code should be extracted into a helper function to improve maintainability and reduce duplication.
|
|
||
| export async function load({ locals, params, url }) { | ||
| if (!locals.user) { | ||
| throw error(500); |
Copilot
AI
Jan 18, 2026
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.
The function throws a 500 error when the user is not authenticated (line 12). A 500 status code indicates an internal server error, but an unauthenticated user is not a server error - it's a client error. This should return a 401 (Unauthorized) or 403 (Forbidden) status code instead, or redirect to a login page.
| throw error(500); | |
| throw error(401, { message: 'unauthenticated' }); |
ArcaEge
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.
Sending more detailed info in the slack channel
|
Merge the stuff I pushed to the printer-shop branch on this repo into your own fork (I can't commit to your fork sorry), then have a look at what I sent in Slack |
Fix some of the issues with the pr
|
Merged |
No description provided.