feat: broaden from postcards to greeting cards (Grußkarten) — rebrand + card types #10
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
The whole app is currently framed as Postkarte (title 'Postkarte – eine Grußkarte zum Verschicken', postcard-centric copy/themes). m wants it broadened to greeting cards in general (Grußkarten) — birthdays, Christmas, invitations, thank-you, get-well, etc. — not just postcards.
The app is already generic underneath (text + media + layouts + custom links). This is mostly framing + a card-type concept + occasion-fitting design, not a rewrite.
New home domain is sendmy.cards (generic), so the branding is no longer tied to 'post'.
Depth — OPEN DECISION (m being asked via PWA chips)
Three levels, each building on the previous:
This issue will be scoped to m's chosen depth before building.
Sequencing
Overlaps the compose flow + templates + branding → after #8 (/to/ /from/) and #9 (link lifecycle) to avoid colliding with the active short-link work. Filed now to capture the direction; otto-head scopes + assigns once the short-link track lands and m has picked the depth.
Constraints (carry over)
DoD (placeholder — finalized once depth is chosen)
m's decision on depth (PWA, 2026-06-16): Option (b) + Custom.
Scope is now: a card-type / occasion selector at compose with a preset starter set (e.g. Geburtstag, Weihnachten, Einladung, Dankeschön, Gute Besserung, Liebe, Allgemein, Postkarte) plus a 'Custom' / 'Eigener Anlass' option where the sender types their own occasion label freely.
This makes #10 buildable. Still sequenced after #8/#9 (compose-flow overlap).
#10 done — greeting-card broadening, depth (b)+Custom
Built to m's PWA decision (2026-06-16): occasion selector (presets + free-text custom) driving copy/default-theme, persisted + reflected on the card, plus the Postkarte → Grußkarte rebrand. Deeper occasion-specific designs = (c) stay out of scope.
Commit:
a325d01d28Branch:
mai/hermes/issue-10-feat-broaden(pushed; not merged — otto-head merges/deploys)What shipped
1. Rebrand (Postkarte → Grußkarte). User-facing framing is now general greeting cards across landing, compose, rendered card and not-found — brand
💌 Grußkarte, hero/steps copy mentioning Geburtstag/Weihnachten/Einladung/Dankeschön, page titles + meta description. Internal names (postcardsschema, bucket, Go module) stay as-is — only the framing changed, so no infra churn.2. Occasion / card-type concept. New
Occasiondomain type with a preset set + a free-text custom escape hatch:<title>+ OG title (e.g. „Du hast eine Geburtstagskarte bekommen 🎂“). The neutral Allgemein default renders no badge, so old cards look exactly as before.3. Persistence — idempotent migration
006_occasion.sql.occasion text NOT NULL DEFAULT 'allgemein'+ nullableoccasion_label. AdditiveALTERkeeps the table'spostgresowner (same note as 002/003/005), so it's safe for the old running binary, and existing rows backfill to the neutralallgemein. Occasion is normalised on both write and read, so an unknown/hand-edited value can never break the renderer (falls back to general). Custom-with-empty-label degrades cleanly to general.Verification
go build/go vet/go test ./... -race— all green. New unit tests (NormalizeOccasion,DefaultThemeFor,Occasions,OccasionView) + render tests (compose selector present, error-re-render prefill, rendered badge/title, general = no badge).occasion=geburtstag, badge🎂 Geburtstag, title Geburtstagskarte), a custom card (→occasion=custom+ labelSchulabschluss, badge✨ Schulabschluss, generic noun), and a general card (→occasion=allgemein, no badge); an old-binary-style insert with no occasion defaulted toallgemein; a hand-edited bogus occasion still returns 200 with no badge. Test container + temp files removed afterwards.DoD
Notes for otto-head
(m/postcards has no Gitea labels — no label state machine to update; signalling via this comment + commit link + task status, per prior shifts.)
✅ Merged & deployed — greeting-card broadening live on sendmy.cards
Merged
a325d01(merge2354e70), deployed. Migration 006 applied. Verified live: landing now reads Grußkarte, compose has the occasion picker, a Geburtstag card renders title „eine Geburtstagskarte“ + 🎂 badge. Neutral Allgemein default = no badge (old cards unchanged). Custom free-text occasion works. Test data cleaned. build/vet/test -race green.Built exactly to m's depth decision (b)+Custom. Not closing — m closes.