Site vitrine et back-office pour une agence immobiliere haut de gamme specialisee dans les demeures d'exception a Paris, Lyon, Annecy et dans le Sud.
La page d'accueil propose une experience de scroll cinematographique : en scrollant, on "entre" dans une demeure et on traverse les pieces (facade, salon, cuisine, suite, exterieur), chacune revelant un texte et des compteurs animes.
- Next.js 16 (App Router) + TypeScript strict
- Tailwind CSS v4 (tokens du design system dans
src/app/globals.css) - GSAP + ScrollTrigger + Lenis (scroll journey)
- Framer Motion (micro-interactions)
- Prisma 6 + SQLite (base de donnees)
- Stripe (acomptes de visite)
- Leaflet + OpenStreetMap (cartes, sans cle API)
- Resend (emails transactionnels, optionnel)
- Vitest (tests unitaires)
npm install
cp .env.example .env.local # renseigner les variables
npx prisma migrate deploy # cree la base SQLite
npx prisma db seed # importe le catalogue de demonstration
npm run dev # http://localhost:3000Scripts : npm run dev, build, start, lint, typecheck, test.
Tout est documente dans .env.example. Minimum pour le dev :
DATABASE_URL(SQLite par defaut)ADMIN_PASSWORD,ADMIN_TOKEN(acces back-office)
Optionnel : STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET (paiement),
RESEND_API_KEY / CONTACT_TO_EMAIL (emails). Sans ces cles, les
fonctionnalites correspondantes sont desactivees proprement (rien ne casse).
Site public :
- Accueil avec scroll journey, biens phares, villes, avis, CTA estimation
- Catalogue
/biensavec filtres (transaction, type, ville, prix, chambres, surface) et tri, lu depuis la base - Fiche bien : galerie + lightbox, carte Leaflet, formulaire de visite, reservation avec acompte Stripe, biens similaires, donnees structurees JSON-LD
- Pages agence, services, avis, contact (carte des bureaux), pages legales RGPD
- Banniere de consentement cookies
Back-office /admin (protege par mot de passe) :
- Tableau de bord : demandes de contact et reservations, export CSV
- Triage des leads (nouveau / traite)
- Gestion des biens : creation, edition, suppression, mise en avant, publication
Prisma + SQLite, configure via prisma.config.ts (schema, seed, chargement
des .env). Modeles : Property, Lead, Reservation (cf.
prisma/schema.prisma). Les pages publiques lisent la base (rendu dynamique),
le catalogue est editable depuis le back-office.
- Migration :
npx prisma migrate deploy - Seed :
npx prisma db seed(importesrc/data/properties.ts) - Passage a Postgres : changer
providerdansschema.prisma, mettre une URL Postgres dansDATABASE_URL, puisnpx prisma migrate deploy.
Reservation de visite avec acompte via Stripe Checkout (hebergee). Le webhook
/api/webhooks/stripe (signature verifiee) enregistre la reservation. Configurer
l'endpoint webhook dans Stripe vers https://DOMAINE/api/webhooks/stripe.
Leaflet + tuiles CARTO (gratuit, sans cle). Le domaine des tuiles est autorise
dans la CSP de next.config.ts.
sitemap.xml (incluant les biens), robots.txt, JSON-LD (RealEstateAgent et
Product) et image OpenGraph dynamique par bien.
npm test(Vitest, tests unitaires danssrc/lib/*.test.ts)- GitHub Actions (
.github/workflows/ci.yml) : lint, typecheck, test, build a chaque push / PR. Dependabot configure pour npm et les actions.
Build standalone Next.js, Dockerfile multi-stage non-root avec healthcheck,
docker-compose.yml (service web + reverse proxy Caddy avec HTTPS automatique).
Les migrations Prisma sont appliquees automatiquement au demarrage du conteneur
et la base SQLite est persistee dans le volume Docker db_data
(DATABASE_URL=file:/app/data/prod.db par defaut).
docker compose up -d --buildRenseigner DOMAIN et les variables dans un .env a cote du compose.
Security headers dans next.config.ts (CSP, HSTS, X-Frame-Options,
Referrer-Policy, Permissions-Policy ; unsafe-eval autorise uniquement en dev
pour le HMR). Anti-spam sur les formulaires (honeypot + rate-limit), rate-limit
sur la connexion admin avec comparaison du mot de passe en temps constant.
Session admin signee (HMAC-SHA256, expiration 8 h) : le cookie ne contient
jamais le secret, il est infalsifiable et verifie par le proxy (src/proxy.ts)
et par chaque server action. Webhook Stripe a signature verifiee, idempotent
(pas de double notification si Stripe rejoue un evenement) et qui n'enregistre
que les sessions reellement payees. Aucun secret cote client ; variables
sensibles dans .env (jamais commitees).
src/
app/ routes (public + /admin + /api)
components/ UI (journey, cartes, formulaires, admin)
data/ contenu de demonstration (avis, villes, journey, images)
lib/ db, properties, stripe, email, auth, utils
prisma/ schema, migrations, seed
- Marque :
src/lib/brand.ts(constanteBRAND) - Couleurs / typo :
src/app/globals.css(bloc@theme) - Biens : back-office
/admin/biens(ou seed initial danssrc/data)