Skip to content

Epic Stack catch-up 3/7: Small bugfix batch #26

Description

@cursor

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.tsxdebounce 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions