tommaso 2c8c2a7429 Resi Shopify + notifiche merchant + A6 (finestra/esclusioni) + dashboard recessi
Integrazione Resi Shopify:
- Alla conferma del recesso, crea un Reso nativo (returnCreate) per gli ordini
  evasi -> gestione nella UI Resi nativa. Ordini non evasi: skip (merchant gestisce
  annullo/rimborso). Query via order.fulfillments (returnableFulfillments non
  esiste nella API 2026-04). Campo WithdrawalRequest.shopifyReturnId.

Notifiche al merchant (dietro toggle Settings):
- Email di notifica a ogni recesso (sendMerchantNotification) + tag "Recesso"
  sull'ordine (tagsAdd, scope write_orders). Toggle notifyEnabled/notifyEmail/tagEnabled.

A6 - completezza compliance (dietro toggle, default OFF, non tocca il flusso testato):
- Finestra 14gg: computeDeadline/isWindowExpired (rif = data evasione o ordine +
  defaultWindowDays). Esclusioni Art. 59: checkExclusions su regole ExclusionRule
  (ALL/PRODUCT/TAG). lookupOrder esteso (fulfillments + lineItems product/tags).
  checkCompliance() aggancia lookup+confirm. Toggle enforceWindow/enforceExclusions.
- Pagina admin Esclusioni (CRUD regole) + sezione Regole di recesso in Impostazioni.

Dashboard: pagina Recessi (registro legale read-only). NavMenu: Recessi/Impostazioni/Esclusioni.
Scope: +write_returns,+write_orders. Editor email vincolato (oggetto/intro/nota + anteprima).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mv83a29B4eFv5ixoj6PoE1
2026-07-07 14:47:07 +02:00

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.jsonengines)
  • 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
Description
No description provided
Readme 490 KiB
Languages
TypeScript 93.8%
Liquid 2.6%
CSS 1.8%
JavaScript 1.6%
Dockerfile 0.2%