Abstract27
Siti web per piccole attività, a canone mensile invece che una spesa unica
Incasso mensile: 887 USD (fonte indicata nella scheda)
Cosa fa
Agenzia che crea e gestisce siti per blogger e piccole attività con un abbonamento mensile basso, invece di far pagare tutto il sito in una volta.
Come guadagna
Ha entrate ricorrenti ogni mese, verificate su TrustMRR. Prezzi e piani esatti sono indicati sul sito del progetto.
Rendilo tuo
- Per attività locali italiane: sito, scheda Google e modifiche incluse nel canone.
- Pochi modelli ben fatti per settore, così ogni sito si consegna in un giorno.
Le frasi da scrivere all'AI
1. Base del sito e grafica
Crea un'app web in italiano chiamata "Sito a Canone": il gestionale di una piccola agenzia che crea siti per attività locali con un canone mensile: area clienti con richieste di modifica, pagamenti automatici e controllo che i siti siano online. Usa React, Vite, TypeScript e Tailwind CSS.
Pagine da creare:
1. Pagina pubblica dell'agenzia con i pacchetti (es. 29, 49, 79 € al mese) e lavori fatti
2. Area cliente: il mio sito, le mie richieste, le mie fatture
3. Nuova richiesta di modifica con testo e allegati
4. Pannello agenzia: clienti, richieste da fare, siti offline
5. Statistiche: entrate mensili ricorrenti, clienti persi
Stile: affidabile e vicino: sfondo bianco, blu #2563EB, arancione #F97316 per le azioni, carattere "Inter", area clienti semplicissima. Nessuna immagine generica di stock.
Tutto deve funzionare perfettamente da telefono. Tutti i testi in italiano, chiari e senza parole tecniche.
2. Database, account e sicurezza
Collega il progetto a Supabase e attiva la registrazione con email e password.
Crea queste tabelle:
- "clienti": attività, dominio del sito, pacchetto, stato dell'abbonamento, collegati all'utente cliente
- "richieste": testo, allegati, stato (nuova, in lavorazione, fatta), tempo impiegato
- "controlli_online": esito dei controlli del sito ogni 5 minuti
Regole di sicurezza obbligatorie:
- ogni cliente vede solo il suo sito, le sue richieste e i suoi controlli
- solo l'agenzia (amministratori) vede tutto e cambia gli stati
- il pacchetto e lo stato dell'abbonamento li cambia solo Stripe
Usa esattamente il codice SQL che trovi nei "Dettagli tecnici" di questa scheda: eseguilo nel SQL Editor di Supabase prima di continuare, poi collega le pagine alle tabelle.
3. Richieste di modifica
Il cliente entra nell'area clienti e con "Nuova richiesta" scrive cosa vuole cambiare (es. "aggiornare gli orari di agosto") e allega foto o PDF. Il pacchetto stabilisce quante richieste al mese sono incluse: il contatore è sempre visibile.
L'agenzia vede le richieste in una bacheca a colonne, le prende in carico, segna il tempo impiegato e le chiude: il cliente riceve un'email "Fatto!" con il link alla pagina modificata.
Il canone si paga con abbonamento Stripe; se un pagamento fallisce il cliente vede l'avviso e l'agenzia riceve una notifica.
4. Siti sempre online
Ogni 5 minuti una funzione controlla che ogni sito risponda (codice nei Dettagli tecnici): stato HTTP, tempo di risposta, e scadenza del certificato del dominio. Se un sito non risponde per 2 controlli di seguito, l'agenzia riceve un avviso subito.
Pannello statistiche: entrate mensili ricorrenti, clienti nuovi e persi del mese, ore di lavoro per cliente rispetto al canone (per capire quali pacchetti rendono).
5. Pagamenti con Stripe
Aggiungi un abbonamento a da 29 € al mese per sito. Gratis l'utente ha: il pacchetto base include 2 richieste al mese. Con il piano Pro sblocca: richieste illimitate, blog, statistiche delle visite e tempi di risposta garantiti.
A pagamento riuscito il webhook porta l'utente al piano Pro; se l'abbonamento viene disdetto o non rinnovato lo riporta al piano gratuito.
Per la sessione di pagamento e il webhook segui la guida "Pagamenti con Stripe" di Fattibile.
6. Controlli specifici di questo progetto
Oltre ai controlli della guida "Controllo finale", verifica in particolare:
1. Monitoraggio: spegni un sito di prova e verifica che l'avviso arrivi entro 10 minuti, e che non arrivino avvisi ripetuti ogni 5 minuti.
Correggi quello che non va e scrivimi cosa hai cambiato.
Dettagli tecnici
Controllo che i siti siano online
La Edge Function chiamata ogni 5 minuti: controlla ogni sito con un tempo massimo di 10 secondi e registra esito e velocità.
// supabase/functions/controlla-siti/index.ts
import { createClient } from "npm:@supabase/supabase-js";
const db = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!);
async function controlla(dominio: string) {
const inizio = performance.now();
try {
const r = await fetch("https://" + dominio, {
method: "GET",
redirect: "follow",
signal: AbortSignal.timeout(10_000), // massimo 10 secondi
});
return { online: r.ok, stato: r.status, ms: Math.round(performance.now() - inizio) };
} catch {
return { online: false, stato: 0, ms: null }; // timeout, DNS o certificato non valido
}
}
Deno.serve(async () => {
const { data: clienti } = await db.from("clienti").select("id, dominio").eq("attivo", true);
const esiti = await Promise.all(
(clienti ?? []).map(async (c) => ({ cliente_id: c.id, ...(await controlla(c.dominio)) })),
);
await db.from("controlli_online").insert(esiti);
return new Response("ok");
});Siti offline da avvisare
Trova i siti con gli ultimi 2 controlli falliti, che non sono già stati segnalati: così l'avviso parte una volta sola.
create table clienti (
id uuid primary key default gen_random_uuid(),
utente_id uuid not null references auth.users(id) on delete cascade, -- il cliente
attivita text not null,
dominio text not null,
pacchetto text not null default 'base',
attivo boolean not null default true,
avviso_offline_inviato boolean not null default false
);
alter table clienti enable row level security;
create policy "il mio sito" on clienti for select using (auth.uid() = utente_id);
create table controlli_online (
id bigint generated always as identity primary key,
cliente_id uuid not null,
online boolean not null,
stato int not null,
ms int,
controllato_il timestamptz not null default now()
);
create index on controlli_online (cliente_id, controllato_il desc);
with ultimi as (
select cliente_id, online,
row_number() over (partition by cliente_id order by controllato_il desc) as n
from controlli_online
where controllato_il > now() - interval '30 minutes'
)
select c.id, c.dominio
from clienti c
where (select count(*) from ultimi u where u.cliente_id = c.id and u.n <= 2 and not u.online) = 2
and not c.avviso_offline_inviato; -- si rimette a false quando torna online
Pezzi comuni a tutti i progetti
Glossario
- Cron
- Un'operazione programmata che parte da sola a orari fissi, per esempio ogni lunedì mattina.
- Entrate ricorrenti (MRR)
- Quanto incassa ogni mese un'attività con gli abbonamenti attivi.