Parent issue: #23
Parent: search for issue titled “Epic Stack catch-up: tracking”. Independent of packages 1–2, but still branch off current origin/dev.
Goal
Port the small, already-known Epic Stack bugfixes that apply to files this repo still has. One PR, no dependency major bumps.
Do this
Branch off origin/dev. PR into dev. Apply each fix below; skip none without saying why in the PR.
1. Note image list key / duplication on navigate
Upstream: epicweb-dev/epic-stack@833a057 / epicweb-dev/epic-stack#1047
File: app/routes/users+/$username_+/notes.$noteId.tsx
- In the images
select, add id: true
- Change
<li key={image.objectKey}> to <li key={image.id}>
Optional (only if you touch seed anyway): prisma/seed.ts used to pick note images with possible duplicates; upstream uses faker.helpers.arrayElements + Promise.all. Nice-to-have, not required.
2. Replacing an existing note image (data URL preview)
Upstream: epicweb-dev/epic-stack@7d1dbbb / epicweb-dev/epic-stack#1025
File: app/routes/users+/$username_+/__note-editor.tsx
Current (broken for data-URL previews):
{existingImage ? (
<Img ... />
) : (
<img ... />
)}
Change the condition to:
{existingImage && !previewImage.startsWith('data:') ? (
<Img ... />
) : (
<img ... />
)}
3. Debounce must preserve this
Upstream: epicweb-dev/epic-stack@19eeb4b / epicweb-dev/epic-stack#1090
File: app/utils/misc.tsx — debounce helper (~line 242)
Use a function that fn.apply(this, args) instead of an arrow that calls fn(...args). Match upstream’s ThisParameterType typing.
4. OTP inputMode="text"
Upstream: epicweb-dev/epic-stack@97135fc
File: app/components/ui/input-otp.tsx
On <OTPInput>, set default inputMode="text" before {...props} so callers can still override.
5. Notes sidebar avatar shrink
Upstream: epicweb-dev/epic-stack@fb1f753 / epicweb-dev/epic-stack#1035
File: app/routes/users+/$username_+/notes.tsx
Port the className tweaks (xl:flex-row, xl:size-24 instead of lg: variants that let the avatar shrink). Do not restyle the dashboard.
6. Accessibility labels
Upstream: epicweb-dev/epic-stack@33d6193 / epicweb-dev/epic-stack#1034
app/components/user-dropdown.tsx: aria-label="User menu" on the trigger Link; aria-hidden="true" on the avatar Img
app/routes/users+/index.tsx: aria-label={\${user.name || user.username} profile`}on the userLink`
If e2e selectors in tests/e2e/*.ts fail because of these labels, update the tests the same way upstream did (2fa / onboarding / passkey / search). Do not skip tests.
7. Prisma AI consent in test global setup
Upstream: epicweb-dev/epic-stack@5f32a7b / epicweb-dev/epic-stack#1086
File: tests/setup/global-setup.ts
When running prisma against the test DB, set env:
PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION: 'true'
Files allowed
Only the files named above, plus e2e tests if a11y changes break them, plus prisma/seed.ts if you take the optional seed tweak.
Do not
- Do not bump any npm packages
- Do not edit
dashboard+, Sentry, Vite, server, or routing config
- Do not start other catch-up packages
Acceptance
- Each of the seven fixes is present (or explicitly skipped with reason)
npm run typecheck and npm run test -- --run pass
- PR targets
dev
Staging smoke (human)
- Open a note with images, navigate away and back — images should not duplicate
- Edit a note, replace an existing image, confirm preview works
- User menu still opens; notes sidebar avatar is not squashed
PR target: dev (never main). Implement only this issue.
Parent issue: #23
Parent: search for issue titled “Epic Stack catch-up: tracking”. Independent of packages 1–2, but still branch off current
origin/dev.Goal
Port the small, already-known Epic Stack bugfixes that apply to files this repo still has. One PR, no dependency major bumps.
Do this
Branch off
origin/dev. PR intodev. Apply each fix below; skip none without saying why in the PR.1. Note image list key / duplication on navigate
Upstream: epicweb-dev/epic-stack@833a057 / epicweb-dev/epic-stack#1047
File:
app/routes/users+/$username_+/notes.$noteId.tsxselect, addid: true<li key={image.objectKey}>to<li key={image.id}>Optional (only if you touch seed anyway):
prisma/seed.tsused to pick note images with possible duplicates; upstream usesfaker.helpers.arrayElements+Promise.all. Nice-to-have, not required.2. Replacing an existing note image (data URL preview)
Upstream: epicweb-dev/epic-stack@7d1dbbb / epicweb-dev/epic-stack#1025
File:
app/routes/users+/$username_+/__note-editor.tsxCurrent (broken for data-URL previews):
Change the condition to:
3. Debounce must preserve
thisUpstream: epicweb-dev/epic-stack@19eeb4b / epicweb-dev/epic-stack#1090
File:
app/utils/misc.tsx—debouncehelper (~line 242)Use a
functionthatfn.apply(this, args)instead of an arrow that callsfn(...args). Match upstream’sThisParameterTypetyping.4. OTP
inputMode="text"Upstream: epicweb-dev/epic-stack@97135fc
File:
app/components/ui/input-otp.tsxOn
<OTPInput>, set defaultinputMode="text"before{...props}so callers can still override.5. Notes sidebar avatar shrink
Upstream: epicweb-dev/epic-stack@fb1f753 / epicweb-dev/epic-stack#1035
File:
app/routes/users+/$username_+/notes.tsxPort the className tweaks (
xl:flex-row,xl:size-24instead oflg:variants that let the avatar shrink). Do not restyle the dashboard.6. Accessibility labels
Upstream: epicweb-dev/epic-stack@33d6193 / epicweb-dev/epic-stack#1034
app/components/user-dropdown.tsx:aria-label="User menu"on the triggerLink;aria-hidden="true"on the avatarImgapp/routes/users+/index.tsx:aria-label={\${user.name || user.username} profile`}on the userLink`If e2e selectors in
tests/e2e/*.tsfail because of these labels, update the tests the same way upstream did (2fa / onboarding / passkey / search). Do not skip tests.7. Prisma AI consent in test global setup
Upstream: epicweb-dev/epic-stack@5f32a7b / epicweb-dev/epic-stack#1086
File:
tests/setup/global-setup.tsWhen running prisma against the test DB, set env:
PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION: 'true'Files allowed
Only the files named above, plus e2e tests if a11y changes break them, plus
prisma/seed.tsif you take the optional seed tweak.Do not
dashboard+, Sentry, Vite, server, or routing configAcceptance
npm run typecheckandnpm run test -- --runpassdevStaging smoke (human)
PR target:
dev(nevermain). Implement only this issue.