feat(marketing): our-website — URL QR code generator #8

Open
opened 2026-08-01 22:39:22 +00:00 by aaron-junot · 0 comments
Owner

Migrated from ROADMAP

Former path (se-backend): docs/marketing/backlog/our-website-qr-generator.md
Action: Local backlog markdown deleted after this issue; track work in Forgejo.


our-website — URL QR code generator

Status Backlog — see ROADMAP.md
Repos our-website (primary); se-backend marketing/ app + segno (fulfillment_qr.py reference)
Related our-website/README.md; our-website already calls POST /marketing/contact-us (same host/CORS pattern as other marketing endpoints)

Product intent

Marketing tool on our-website: enter a URL, generate a scannable QR code, preview it, and download PNG (and optionally SVG). Use case: event flyers, print collateral, blog/marketing handouts — aligned with other Cooperative Codebase surfaces that use the marketing API (/marketing/…), not marketplace routes.

Reference: se-backend already generates QR PNGs with segno 1.6.6 (direct dependency in pyproject.toml):

# marketplace/domain/fulfillment_qr.py (reuse pattern; endpoint lives under marketing/)
qr = segno.make(url, error="m")
qr.save(buf, kind="png", scale=6, border=2)

segno is Python-only — our-website (React/Vite SPA) cannot import it in the browser. Prefer a /marketing/ backend endpoint (Path B) so generation uses the same library as the rest of the stack; Path A (client JS) remains a fallback if we want zero backend change for v1.


Locked decisions (v1)

Topic Decision
Host (FE) New route on our-website, e.g. /tools/qr or /qr — marketing/ops page, not marketplace SPA
Host (BE) If server-side generation: new route under marketing/urls.py, e.g. GET /marketing/qr?url=… (name TBD in implementation)
Input Single URL field; validate http:// or https:// before generate
Output On-screen preview + Download PNG button
Default QR params Match fulfillment helper: error="m", border=2, readable scale
Auth None — public internal tool; rate-limit + URL length cap on BE
CORS Same cross-origin allowance as /marketing/contact-us for our-website origin(s)

Implementation paths

Add GET /marketing/qr (or …/qr.png) in the marketing app — wraps segno logic extracted/shared from render_fulfillment_qr_png. our-website fetches PNG for preview and download.

Pros: Same segno library as installed in se-backend; consistent with our-website’s existing marketing API integration; CORS pattern already proven for contact form.

Cons: Must rate-limit and cap URL length (public URL-echo surface).

Path A — Client-side (fallback)

JS QR library in our-website mirroring segno M / quiet-zone settings. No new marketing route.

Default: Path B unless implementation time forces a client-only v1.


Logo / whitelabel (stretch)

Center Cooperative Codebase logo on the QR (“whitelabel”).

Layer Logo support
segno alone No native center logo — Pillow paste after PNG
marketing API (stretch) Pillow paste in marketing view/service using logo asset; error="h" when overlay enabled
our-website (canvas) Render QR from API or client lib, composite logo in canvas before download

v1: Plain QR only. v2: Optional “Include logo” toggle + scan QA on phones.

Logo asset: our-website/public/images/logo.png.


our-website scope

  1. Route + page — URL input, Generate, preview, Download PNG.
  2. API client — Call GET /marketing/qr?url=… (Path B) or local generation (Path A).
  3. UI — Match site glassmorphism / shadcn; marketing/ops tone in copy.
  4. Nav — Footer or low-profile tools link.
  5. Deploy — SPA fallback for new route.

se-backend scope (marketing app)

  1. New view + URL under marketing/ (alongside contact-us, subscribe, …).
  2. Shared render_qr_png(url, …) helper (extract from fulfillment_qr.py or commons).
  3. Rate limit + max URL length; optional logo overlay (stretch).
  4. Document endpoint in marketing README / API notes when shipped.

Acceptance criteria

  • our-website page: paste URL → see QR → download PNG
  • Backend route lives under /marketing/, not /marketplace/
  • Invalid / empty URL → 400 with clear message
  • Codes scan on at least one phone camera (manual QA)
  • (Stretch) Logo overlay toggle with H error correction and scan QA

Out of scope

  • Dynamic / analytics QR (redirect tracking)
  • Batch CSV generation
  • Marketplace fulfillment email changes (only shared segno helper if extracted)
## Migrated from ROADMAP **Former path (se-backend):** `docs/marketing/backlog/our-website-qr-generator.md` **Action:** Local backlog markdown deleted after this issue; track work in Forgejo. --- # our-website — URL QR code generator | | | |---|---| | **Status** | Backlog — see [`ROADMAP.md`](../../ROADMAP.md) | | **Repos** | **our-website** (primary); **se-backend** [`marketing/`](../../../marketing/) app + **segno** ([`fulfillment_qr.py`](../../../marketplace/domain/fulfillment_qr.py) reference) | | **Related** | [`our-website/README.md`](../../../../our-website/README.md); our-website already calls **`POST /marketing/contact-us`** (same host/CORS pattern as other marketing endpoints) | --- ## Product intent **Marketing** tool on **our-website**: enter a URL, generate a scannable QR code, preview it, and **download PNG** (and optionally SVG). Use case: event flyers, print collateral, blog/marketing handouts — aligned with other Cooperative Codebase surfaces that use the **marketing API** (`/marketing/…`), not marketplace routes. **Reference:** se-backend already generates QR PNGs with **[segno](https://segno.readthedocs.io/)** 1.6.6 (direct dependency in `pyproject.toml`): ```python # marketplace/domain/fulfillment_qr.py (reuse pattern; endpoint lives under marketing/) qr = segno.make(url, error="m") qr.save(buf, kind="png", scale=6, border=2) ``` **segno is Python-only** — our-website (React/Vite SPA) cannot import it in the browser. Prefer a **`/marketing/`** backend endpoint (Path B) so generation uses the same library as the rest of the stack; Path A (client JS) remains a fallback if we want zero backend change for v1. --- ## Locked decisions (v1) | Topic | Decision | |-------|----------| | **Host (FE)** | New route on our-website, e.g. **`/tools/qr`** or **`/qr`** — marketing/ops page, not marketplace SPA | | **Host (BE)** | If server-side generation: new route under **[`marketing/urls.py`](../../../marketing/urls.py)**, e.g. **`GET /marketing/qr?url=…`** (name TBD in implementation) | | **Input** | Single URL field; validate `http://` or `https://` before generate | | **Output** | On-screen preview + **Download PNG** button | | **Default QR params** | Match fulfillment helper: **`error="m"`**, **`border=2`**, readable **`scale`** | | **Auth** | None — public internal tool; rate-limit + URL length cap on BE | | **CORS** | Same cross-origin allowance as **`/marketing/contact-us`** for our-website origin(s) | --- ## Implementation paths ### Path B — segno via marketing API (recommended) Add **`GET /marketing/qr`** (or `…/qr.png`) in the **marketing** app — wraps segno logic extracted/shared from `render_fulfillment_qr_png`. our-website fetches PNG for preview and download. **Pros:** Same **segno** library as installed in se-backend; consistent with our-website’s existing **marketing API** integration; CORS pattern already proven for contact form. **Cons:** Must rate-limit and cap URL length (public URL-echo surface). ### Path A — Client-side (fallback) JS QR library in **our-website** mirroring segno **M** / quiet-zone settings. No new marketing route. **Default:** **Path B** unless implementation time forces a client-only v1. --- ## Logo / whitelabel (stretch) Center **Cooperative Codebase logo** on the QR (“whitelabel”). | Layer | Logo support | |-------|----------------| | **segno alone** | **No** native center logo — [Pillow paste after PNG](https://segno.readthedocs.io/en/stable/pillow-qrcodes.html) | | **marketing API (stretch)** | Pillow paste in marketing view/service using logo asset; **`error="h"`** when overlay enabled | | **our-website (canvas)** | Render QR from API or client lib, composite logo in canvas before download | **v1:** Plain QR only. **v2:** Optional “Include logo” toggle + scan QA on phones. Logo asset: **`our-website/public/images/logo.png`**. --- ## our-website scope 1. **Route + page** — URL input, Generate, preview, Download PNG. 2. **API client** — Call **`GET /marketing/qr?url=…`** (Path B) or local generation (Path A). 3. **UI** — Match site glassmorphism / shadcn; marketing/ops tone in copy. 4. **Nav** — Footer or low-profile tools link. 5. **Deploy** — SPA fallback for new route. --- ## se-backend scope (marketing app) 1. New view + URL under **`marketing/`** (alongside `contact-us`, `subscribe`, …). 2. Shared **`render_qr_png(url, …)`** helper (extract from `fulfillment_qr.py` or `commons`). 3. Rate limit + max URL length; optional logo overlay (stretch). 4. Document endpoint in marketing README / API notes when shipped. --- ## Acceptance criteria - [ ] our-website page: paste URL → see QR → download PNG - [ ] Backend route lives under **`/marketing/`**, not `/marketplace/` - [ ] Invalid / empty URL → **400** with clear message - [ ] Codes scan on at least one phone camera (manual QA) - [ ] (Stretch) Logo overlay toggle with **`H`** error correction and scan QA --- ## Out of scope - Dynamic / analytics QR (redirect tracking) - Batch CSV generation - Marketplace fulfillment email changes (only shared segno helper if extracted)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cooperative-codebase/our-website#8
No description provided.