feat(cache): attachment-level image caching and RSC-safe fix #105
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
feat(cache): attachment-level image caching, RSC-safe fix
β¨ Features Updates && π Bug Fix && π Code Refactor && π¦ Dependency Update
π Description
This PR refactors how Airtable-backed images are cached and served. Instead of pushing Airtableβs signed
srcURLs down to the client and letting the/api/imagesroute warm R2 on demand, image caching is now handled at the attachment level on the server:transformAttachment(provided by TS-Airtable), which:ensureImageInR2).urlto a stable local path (/api/images/{attId}/{variant}/{filename})./api/imagesAPI route has been simplified to only read from R2. It no longer acceptssrcormodequery params and simply:Acceptheader.On the fetching side,
getImgUrlFromAttachmentObjis much simpler: it just returns theurlof the first attachment. When used with the updated cache store, thaturlis already the stable/api/images/...path, so components donβt have to know about Airtable or cache-warming at all.Alongside the caching changes, this PR also:
**.mdignore from the ESLint config so.md/.mdxfiles are linted automatically.eslint-disablecomments that referenced a rule weβre no longer using./lettersinstead of the older agile research paper.Overall, this keeps Airtable URLs server-side, makes the image pipeline simpler, and simplifies how components consume image URLs.
π Feature Changes
src/lib/image-cache.tsencapsulates all image caching logic (key building, transcoding, R2 writes, and access tagging)./api/images/[...path]now:buildImageObjectKey+r2Get/r2Head.src/modequery parameters.transformAttachment) (provided by TS-Airtable) so that client code only ever sees stable/api/images/...URLs and never Airtable signed URLs.π Refactor Changes
ensureImageInR2), instead of being tied to the API route.tryHead) to find the best available format.src/lib/image-cache.tsand reused by both the Airtable cache store and possibly the API route.getImgUrlFromAttachmentObjhas a minimal surface (no morevariantorprefetchoptions).srcquery handling from/api/images.perfectionist/sort-importsoverride forsrc/lib/airtable/airtable.ts; imports there are now sorted normally.π Bug Fixes
β Checklist
next dev,next build,next start).recordsCache+transformAttachmentshould be used.pnpm audit.π Dependency Changes
transformAttachmenthook for attachment-level caching㪠Additional Notes
ESLint / formatting changes
eslint.config.mjsno longer ignores**.md, and lint-staged now runs ESLint onjs/jsx/ts/tsx/json/md/mdxinstead of using Prettier for Markdown.devDependenciesand the extra lint-staged mapping forsrc/**/*.{md,json}has been deleted.Type and logging updates
src/types/images.d.tsdefinesImageFormatandImageVariantto avoid stringly-typed formats and variants.src/types/kv-logger.d.tsadds a newCacheKindvariant:'transformAttachmentError', used whentransformAttachmentfails.createCloudflareApiKvCacheStorelogstransformAttachmentErrorevents viasafeLogbut always falls back to the original attachmenturlso calls remain resilient.Docs
src/content/apply.mdnow points applicants to the/letterspage instead of the agile research paper, which is more aligned with the current onboarding experience.