Il form era gia' tokenizzato (~30 var CSS in :root): non riscriviamo nulla, iniettiamo un blocco di override DOPO il CSS di base, cosi' un errore di configurazione del merchant non puo' rompere il default. - theme.ts (modulo PURO, condiviso con la futura anteprima admin): ThemeTokens, FONT_PRESETS, themeStyle(). Sanificazione a monte: colori solo esadecimali, raggio e larghezza clampati, font da whitelist, CSS custom con rimozione di </style, @import, expression(), javascript: e cap a 4000 char. Derivati: --focus-ring da accent (rgba), --primary-bg-hover per shading. - recesso.server: tokenizzati anche font (--font) e larghezza (--card-max), che erano hardcoded; renderShell(inner, theme) inietta l'override; renderStep1..4 accettano e propagano il tema. - Settings: themeAccent/ButtonBg/ButtonText/Radius/Font/Width/CustomCss + migrazione. - proxy: loadTheme(shop) in loader e action, propagato ai 22 punti di render. Nell'early-return senza sessione il tema e' null (non conosciamo lo shop). fly.toml: min_machines_running resta 0 per scelta (TODO go-live, vedi PROTECTED-CUSTOMER-DATA.md §5.2).
Pizeta Recesso — App Shopify per la funzione di recesso
App Shopify riutilizzabile che rende un negozio conforme alla funzione elettronica di recesso ("pulsante di recesso") obbligatoria — Art. 54-bis Codice del Consumo (D.Lgs 209/2025, recepimento Dir. UE 2023/2673), in vigore per i contratti conclusi dal 19 giugno 2026.
Contesto e requisiti legali: vedi PLAN.md e
ANALISI-REQUISITI-LEGALI.md.
Struttura cartelle
pizeta-recesso-app/ ← repo git (docs + codice insieme)
├─ PLAN.md piano multi-agente + decisioni bloccate
├─ ANALISI-REQUISITI-LEGALI.md base legale verificata
├─ README.md questo file
└─ app/ app Shopify (template ufficiale Remix, TypeScript)
├─ app/routes/ route Remix (admin embedded + webhook)
├─ prisma/schema.prisma modello dati Postgres (multi-tenant per-shop)
├─ extensions/ theme app extension (storefront) — in arrivo
├─ shopify.app.toml config app (scopes, api_version pinnata, webhook)
├─ fly.toml deployment Fly (app "recesso-custom")
├─ Dockerfile build produzione
└─ .env.example template variabili d'ambiente
Prerequisiti
- Node ≥ 20.19 (vedi
app/package.json→engines) - Shopify CLI (
npm i -g @shopify/cli) - Fly CLI (
flyctl) per il deployment - Un Postgres raggiungibile (Fly Postgres o Supabase) per
DATABASE_URL
Setup sviluppo
cd app
npm install
# 1. Collega la registrazione app "Legal Return PCRT" (scrive client_id nel toml)
shopify app config link
# 2. Configura le env (mai committare .env)
cp .env.example .env # poi compila i valori
# 3. Provisiona il DB e applica lo schema Prisma
# (imposta prima DATABASE_URL nel .env)
npx prisma migrate dev --name init
# 4. Avvia il dev server — SOLO sullo store usa-e-getta pcrt-reso-test
shopify app dev --store pcrt-reso-test
⚠️ Landmine — mai shopify app dev su store da trasferire
shopify app dev (draft app) contro un development store disabilita in modo
irreversibile il trasferimento di quello store (PLAN §0-bis). Usare shopify app dev
/ draft SOLO su pcrt-reso-test. Mai su pizeta-pharma-2 o su store destinati al
cliente. L'app finita, installata via link custom, non ha questo problema.
Strategia due ambienti (custom vs public)
Una sola base di codice public-grade, distribuita Custom ora e Public in futuro (PLAN §0-ter). Gli ambienti sono isolati per costruzione:
| Ambiente | Distribuzione | Fly app | DB |
|---|---|---|---|
| Sviluppo/test | draft (app dev) |
— | locale |
| Custom LIVE | Custom install link | recesso-custom |
dedicato |
| Public (poi) | Public + review | recesso-public |
dedicato |
Registrazioni Partner distinte + Fly app distinte + DB distinti → un deploy della
public non può impattare gli store live sulla custom. Regole anti-rottura:
migrazioni DB solo additive/backward-compatible, theme extension versionate,
API version pinnata (bump solo dopo test su pcrt-reso-test).
Deployment (Fly)
I segreti si impostano con fly secrets (mai nel repo):
cd app
fly secrets set \
DATABASE_URL="postgresql://..." \
SHOPIFY_API_KEY="..." \
SHOPIFY_API_SECRET="..." \
SHOPIFY_APP_URL="https://recesso-custom.fly.dev"
fly deploy