Skip to content

v0.3.0 — Phase 3: verify polish, resale transfers, marketing site

Choose a tag to compare

@ChronoCoders ChronoCoders released this 02 Oct 23:05
· 9 commits to main since this release

Overview

Phase 3 delivers the consumer-facing surface of Genuflow: a redesigned public verification page, a self-service resale/transfer flow, and a full marketing website at the root of the Next.js app.


Workstream 1 — Public verification page polish

Redesigned /verify/[product_id] for the consumer who scans a QR. The page now feels premium and luxury-brand-appropriate rather than developer-tool-appropriate.

  • Editorial layout: eyebrow → authentication seal → brand wordmark → serif product name → intro.
  • Centered authentication seal SVG (accent-tinted shield + check) signals confirmed vs awaiting anchor.
  • Anchor card with structured dl: Network, Block, Anchored timestamp, Transaction (truncated hash, opens Basescan in a new tab, external-link glyph), status pill (Confirmed / Pending / Not yet anchored).
  • Provenance timeline:
    • Chronologically sorted, oldest to newest.
    • Per-event-type SVG icons: manufactured, inspected, shipped, sold, transferred.
    • Connector line between entries, accent ring when anchored.
    • Surfaces detail.location, detail.new_owner_email, detail.notes in a subtle inset card when present.
  • Footer: "Powered by Genuflow" wordmark + tagline + monospace product ID for paste-anywhere lookups.
  • New branded not-found.tsx for invalid/unknown product codes.

Workstream 2 — Resale / transfer flow

When a consumer scans a QR on a product that has already been sold, they can register themselves as the new owner directly from the verification page. The action is public and unauthenticated.

Backend

  • POST /verify/:product_id/transfer — new public endpoint, no middleware, wired alongside the existing GET /verify/:product_id in crates/api/src/routes/verify.rs.
  • Body: { new_owner_email: String, note: Option<String> }.
  • Server invariants:
    • Product must exist (else 404).
    • Product must have at least one prior sold event (else 400 — items not yet sold are not transferable).
    • new_owner_email non-empty, contains @, ≤ 254 chars.
    • note ≤ 500 chars when present.
  • Records a Transferred event with detail = { new_owner_email, note } via db::events::create. Returns the created ProvenanceEvent.

Frontend

  • frontend/lib/api.ts — new transferOwnership(productId, body) calling through the same-origin Next.js proxy.
  • frontend/components/transfer-section.tsx — client component with idle → open → submitting → success | error state machine.
    • Idle: CTA card "Register ownership transfer".
    • Open: form with required email + optional 500-char note.
    • Success: confirmation card with check-mark glyph, the new owner email, and "anchored on next batch" copy.
  • Conditionally rendered on /verify/[product_id] only when events.some(e => e.event_type === "sold").

Workstream 3 — Genuflow.com marketing website

Full marketing site under frontend/app/(marketing)/, dark-mode default, DM Serif Display + DM Sans, #1D9E75 accent, fashion-magazine editorial aesthetic. Real content throughout — no lorem-ipsum, no placeholders.

Pages

  • / — Hero (editorial eyebrow, oversized serif, dual CTA), right-column Unsplash image, "the principle" section, three-step "how it works", three use-case cards, two testimonial quotes, pricing preview, closing CTA.
  • /how-it-works — Five-step deep walkthrough (issue identity → record events → anchor every two hours → verify anywhere → transfer across resale market) + architecture split between Genuflow and Base.
  • /use-cases — Index linking to the three category pages.
  • /use-cases/luxury — Handbags, leather, ready-to-wear. OECD framing, what we record, where the tag lives, end-to-end outcomes.
  • /use-cases/fashion-textiles — Built for the EU Digital Product Passport. Regulation overview, full data model (composition / manufacture / use & care / end of life).
  • /use-cases/watches-jewelry — Service history as product. What we record for watches vs jewelry, secondary-market outcomes.
  • /pricing — Three tiers: Atelier €0.40/product, Maison €0.28/product, Couture custom. Feature lists, five-question pricing FAQ.
  • /about — Mission, vision, four operating principles (brands own the relationship, the protocol outlives the company, no proprietary lock-in by default, multi-tenant means private), team note.
  • /blog — Index linking to three long-form articles.
  • /blog/eu-dpp-regulation — ~1,400 words on the ESPR, the DPP record's contents, the three non-negotiable properties (persistence, openness, tamper-evidence), why anchor to a public chain, what to build now.
  • /blog/counterfeit-statistics — ~1,000 words on OECD framing, why visual cues stopped working, the secondary-market multiplier, what actually works against counterfeit.
  • /blog/blockchain-authentication — ~1,400 words on cryptographic hashes, commitments, why a public chain, Merkle roots, what Genuflow actually anchors, what the technology does and does not guarantee.
  • /resources — Three whitepapers (DPP architecture, economics of authentication, migration from QR+DB) + three guides (integration playbook, tag-placement, transfer comms) + four open-standards cards (GS1 Digital Link, W3C Verifiable Credentials, ISO 3758, EU ESPR).
  • /docs — Full API reference with sticky TOC, working curl quickstart, endpoint documentation for products, events, verify, transfer, and anchors. Authentication explainer, error reference, real TypeScript request/response shapes.
  • /contact — Direct lines (general / sales / press), offices, client-side contact form that composes a mailto.

Shared components

  • components/marketing/nav.tsx — Sticky, responsive, mobile drawer. Links: How it works, Use cases, Pricing, Journal, Resources, About + Sign in / Request access CTAs.
  • components/marketing/footer.tsx — Five-column with Product / Use cases / Resources / Company.
  • components/marketing/section.tsx — Eyebrow, SectionTitle, PageHero, CTABand.
  • components/marketing/article.tsx — Editorial typography for blog posts, optional header image.
  • components/marketing/code-block.tsx — Language-labelled monospace blocks.
  • components/marketing/contact-form.tsx — Mailto-composing client form.
  • components/marketing/hero-image.tsx — HeroImage, BannerImage (capped at 400px), ArticleHeaderImage.

Imagery

Unsplash images placed on the homepage hero, the three use-case banners, the about banner, and the three blog article headers.


Notes for operators

  • The existing app/page.tsx (which redirected / to /login) was removed so the marketing homepage takes over /. The dashboard is reachable via the Sign in link in the marketing nav.
  • The verify page's transfer flow runs entirely through the existing same-origin Next.js proxy — no CORS, no new edge configuration.
  • The BannerImage component defaults to h-[320px] sm:h-[400px] per the approved design pass.

Verified gates

  • cargo clippy --workspace -- -D warnings clean.
  • next build clean — 28 routes total, all marketing routes statically prerendered.