尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗App per gestire e approfondire i propri veicoli (auto e moto): schede tecniche per sezione (motore, carrozzeria, assetto, impianto frenante, trasmissione, elettronica), ricerca IA di risorse online (forum, manuali PDF, video, schemi tecnici/esplosi) e chat IA sui documenti caricati (es. libretto uso e manutenzione).
App/
├── web/ App Next.js (App Router) — frontend + backend IA → deploy su Vercel
└── supabase/ Migrazioni SQL (schema DB, RLS, storage buckets)
web/app/api/agent/* per la ricerca web
categorizzata e la chat sui documenti. È l'unico servizio a pagamento a consumo (nessun costo
fisso mensile: paghi solo quando qualcuno usa davvero le funzioni IA).Non c'è nessun backend separato: le API route di Next.js girano come funzioni serverless su Vercel, usano la sessione Supabase dell'utente (quindi le query rispettano automaticamente le policy di Row Level Security) e chiamano l'API Anthropic lato server, senza mai esporre la chiave al browser.
supabase/migrations/0001_init.sql, poi esegui. Questo crea tutte le tabelle, le policy di Row Level Security e i bucket di storage (vehicle-files, vehicle-images), entrambi privati.Project URL → NEXT_PUBLIC_SUPABASE_URLanon public key → NEXT_PUBLIC_SUPABASE_ANON_KEYANTHROPIC_API_KEY.edorebu00/MyVehicle.web.web/.env.example:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYANTHROPIC_API_KEYCLAUDE_MODEL (opzionale, default claude-sonnet-5)cd web
cp .env.example .env.local # compila le variabili
npm install
npm run dev # http://localhost:3000
Nessun costo fisso mensile: paghi solo se e quando l'IA viene effettivamente utilizzata.
L'app si installa dalla schermata Home e si apre a schermo intero, senza barra del browser. Non serve nessuno store: su Android compare l'invito all'installazione, su iPhone si passa da Condividi → «Aggiungi a Home».
Nessuna scelta architetturale è cambiata per ottenerlo — restano componenti server, API route e autenticazione a cookie. Sono stati aggiunti soltanto:
app/manifest.ts — nome, icone, colori e scorciatoie;public/sw.js — service worker volutamente prudente: non mette mai in cache /api/ né
/auth/, e per le pagine va sempre in rete (il contenuto dipende da chi ha fatto l'accesso),
con la pagina /offline come ripiego. Gli unici file messi in cache sono gli asset immutabili
di Next;components/InstallPrompt.tsx — invito all'installazione, con le istruzioni di iOS dove
l'evento di sistema non esiste; si chiude e non ritorna;app/icon.svg con npm run icons (comprese le maskable per Android).Se cambi il logo basta sostituire app/icon.svg: npm run build rigenera tutto. Il nome dei
file contiene l'impronta dell'SVG, quindi cambiando il logo cambia anche il manifest — è l'unico
modo perché Chrome si accorga della modifica e aggiorni l'icona già installata sulla schermata
Home. Su iPhone invece l'icona viene fotografata al momento dell'installazione e iOS non la
rilegge mai: lì serve rimuovere l'app dalla Home e riaggiungerla.
Attenzione al middleware: manifest.webmanifest e sw.js sono esclusi dal matcher. Se ci
passassero dentro verrebbero rimandati al login e l'app non risulterebbe mai installabile — è un
guasto silenzioso, l'app continua a funzionare e sembra solo che «l'installazione non si possa
fare».
La PWA evita i costi e le revisioni degli store, ma non gli obblighi di legge: l'app tratta email, targhe, numeri di telaio e documenti caricati. Mancano ancora un'informativa privacy e la cancellazione dell'account (oggi si cancella un veicolo, non il proprio profilo). Entrambe sono richieste dal GDPR a prescindere da dove l'app viene distribuita.
Il costo è dominato dalla chat: il testo dei documenti caricati viene rispedito al modello a ogni messaggio, e un manuale di medie dimensioni vale da solo ~60.000 token per messaggio, cioè centinaia di volte tutto il resto del prompt. Le scelte sono ordinate per questo.
web/lib/chatPrompt.ts): davanti istruzioni e documenti, con un punto di cache; in coda la
lingua, che l'utente può cambiare. Dal secondo messaggio in poi i documenti si pagano ~un
decimo. Su una conversazione di dieci messaggi sono circa il 75-80% in meno.ORDER BY esplicito (senza, Postgres può restituirli in ordine
diverso e la cache non viene mai riletta) e la finestra della cronologia avanza a blocchi di
sei messaggi invece che scorrere di uno alla volta.web/lib/extractedText.ts): intestazioni e piè
di pagina ricorrenti, numeri di pagina, spaziatura e parole spezzate a fine riga vengono tolti
al momento del caricamento. Quanto si risparmia dipende dal documento — su un manuale con
intestazioni su ogni pagina è dell'ordine del 20-40% — e si risparmia su ogni messaggio futuro.submit_findings, che viene comunque inviato; erano ripetute anche nel prompt di
sistema, e si pagavano due volte. ~36% in meno di testo fisso per chiamata, stesse regole.web_search_20260209): i risultati arrivano ripuliti
dall'impaginazione invece di riversarla nel contesto, dove verrebbe rispedita a ogni giro. Il
ritentativo, quando serve, ha metà delle ricerche a disposizione: deve chiudere, non ricominciare.Notizie e prossime gare sono l'unica funzione IA che gira senza che nessuno la chieda: un
calendario scritto nel codice sarebbe sbagliato entro poche settimane, e date inventate sono
peggio di nessuna data. Il costo è tenuto basso dalla cache (web/lib/motorsport.ts): il
risultato vale 24 ore ed è condiviso da tutti i visitatori, quindi si paga una chiamata al
giorno per lingua effettivamente visitata, non una per visita — nell'ordine di 1 € al mese.
Per cambiare la frequenza si modifica CACHE_SECONDS.
Se la chiave Anthropic manca o la ricerca fallisce, la sezione semplicemente non compare: la
home resta in piedi. Il riquadro è dentro un <Suspense>, così alla scadenza della cache il
resto della pagina non aspetta la ricerca web.
La cache dei prompt non si rompe con un errore: le richieste continuano a funzionare, cambia solo il conto. Le due difese:
cd web && npm run check:cache
verifica le proprietà da cui dipende il riuso (prefisso identico fra turni, blocco volatile in
coda, finestra della cronologia stabile) — da rieseguire dopo ogni modifica a un prompt — e i
log del server, dove ogni chiamata stampa una riga [token] con token riletti dalla cache,
riscritti e nuovi. A regime i riletti devono dominare: se restano a zero, qualcosa a monte del
punto di cache sta cambiando a ogni richiesta.
service_role key, quindi non c'è modo di aggirare le policy: un id di un veicolo o
di un documento altrui semplicemente non restituisce righe.vehicle-files e vehicle-images sono privati e le policy consentono
lettura/scrittura/cancellazione solo sotto il prefisso <user_id>/.... I download avvengono con
link firmati validi 60 secondi.http/https)
sia prima di essere salvati sia prima di essere renderizzati, così uno schema come javascript:
non può diventare codice eseguito al click.frame-ancestors/X-Frame-Options (anti clickjacking), nosniff,
Referrer-Policy, Permissions-Policy e HSTS sono impostati in next.config.mjs.search_results è scrivibile direttamente dal
browser. I risultati ripescati dalla cronologia vengono quindi risanificati anche quando si
rileggono, esattamente come quelli appena arrivati dal modello.pdf-parse 1.1.1 include al suo interno una copia di pdf.js 1.10.100, del 2018, e i PDF
caricati dagli utenti sono l'input non fidato più pesante che l'app elabori lato server.
L'esecuzione di codice nota su quelle versioni di pdf.js (CVE-2024-4367) passa dalla generazione
dei glifi durante il rendering su canvas: qui si chiama solo getTextContent(), quindi quel
percorso non viene attraversato. Resta il rischio generico di un parser vecchio e non più
mantenuto, limitato da maxDuration = 90, dal tetto di 20 MB per file, dal limite di frequenza e
dal tetto di 500 pagine analizzate.
La soluzione è passare a pdf-parse 2.x, che usa pdfjs-dist 5.x (2025). Non è stato fatto
qui perché la 2.x carica @napi-rs/canvas, un binario nativo, anche per la sola estrazione
testo: su Vercel va verificato sul deploy reale (dimensione della funzione, serverExternalPackages,
binari per piattaforma), e non aveva senso rischiare la produzione per chiudere un percorso che
non risulta raggiungibile. È un cambiamento a sé, da fare potendo verificare il deploy.
pgvector su Supabase e un modello di embeddings (es. Voyage AI, partner consigliato da Anthropic).maxDuration = 180, chat e processing documenti maxDuration = 90.