Follow-ups from the codex review of #834:
- .gitignore: backend/storage/ is runtime-generated (media, previews,
thumbnails, business docs) and was only partially ignored — E2E runs
left it dangling as untracked, which is how ~12 MB of artifacts nearly
landed in a commit. Ignore the whole directory (nothing under it is
tracked); replaces the narrower business-docs rule.
- backend/.dockerignore: the granular storage/* rules missed
storage/previews, so locally generated previews were copied into
production images. Exclude storage entirely — the Dockerfile creates
the needed directories itself (RUN mkdir -p, Dockerfile:96).
- fileSecurityUtils.js: remove getSafeFilename — zero callers across the
repo, and its private extension whitelist silently drifted from the
real validation paths (see #834), which is exactly the trap dead
security code sets.