Skip to content

v1.5.0

Choose a tag to compare

@SumitGA SumitGA released this 06 Sep 11:21
· 4 commits to main-branch since this release

Admin-only release. The public site is unchanged, so promoting the admin
project is what matters here.

The cover field could only upload. Using one picture in two posts — a
series cover, a diagram that belongs in both — meant a second copy:
storage spent twice on a finite plan, and two public_ids for one image,
so a later cleanup could only ever find half of it.

"Choose existing" now lists what is already in the account, for covers
and for body images. Picked images are still written to post_images: the
upsert is keyed on (post_id, public_id), and shared ownership is exactly
what stops deleting one post removing an asset another post still uses.

Listing goes through the Admin API, since there is no public way to
enumerate an account's assets — correctly, as that would expose
everything ever uploaded. Gated on a real Supabase session, the same as
signing and deleting; verified returning 401 with no token and with a
bad one. Only public_id, dimensions, size and date reach the browser.

Both directions were manual. Retyping is where canonical_url gets
forgotten, and a cross-post without it hands the ranking to the other
site — the opposite of the reason for publishing here.

Import parses the frontmatter and fills title, excerpt, tags, series and
cover. A cover hosted outside this Cloudinary account is reported rather
than silently dropped, because a cover that quietly vanished would be
found much later, on the live site.

"Copy for dev.to" emits the block with canonical_url already pointing
here, plus the body. It sets published: false so a cross-post is
reviewed there before going live, strips hyphens from tags and caps them
at four, because dev.to rejects both.

The parser is hand-written rather than a YAML dependency: this
frontmatter is flat scalars and one comma list. 23 tests cover it,
including the exact dev.to header Part 2 was pasted from — commented
keys ignored, empty values not written, quotes stripped, round trip.

URLs for picked images are encodeURI'd. A public_id may contain a space
— this account already has "My Brand/watermark" — and markdown ends a
link target at the first space, so an unencoded URL silently produces a
broken image. Uploads were never affected: Cloudinary returns an encoded
URL.

The picker UI itself was not clicked through, since that needs admin
credentials. The route, the mapping and the parser are all verified;
the modal is not.

  • The active tag chip on the blog index measures 3.93:1, below AA.
  • Both posts share a cover image, so the index shows the same artwork
    twice.
  • Production still requires a manual "Promote to Production" in Vercel.
  • Callout blocks (> [!NOTE]) are not rendered.