rebours/CLAUDE.md
ordinarthur 6583a7295a
All checks were successful
Build & Deploy to K3s / build-and-deploy (push) Successful in 34s
chore: remove legacy Astro + Sanity + Fastify stack
The site has fully migrated to Next.js 15 + Payload CMS 3 + Postgres
(under ./nextjs). Delete the old root-level Astro app, Sanity Studio,
Fastify server and their Docker/nginx plumbing. CI already builds
nextjs/Dockerfile and deploys a single rebours-web pod; drop the
legacy-pod teardown step now that the old workloads are long gone.

Removed:
- src/, public/, sanity/ (Astro pages/layouts/lib, Sanity studio)
- server.mjs, astro.config.mjs (Fastify API, Astro config)
- Dockerfile.ssr, Dockerfile.api, nginx.conf (old 3-pod topology)
- package.json, pnpm-lock.yaml (root, replaced by nextjs/)
- seed-sanity*.mjs, migrate-images.mjs, clean-duplicates.mjs
- .env.example, .dockerignore (root, superseded by nextjs/)
- .astro/ build artifacts

Updated:
- CLAUDE.md rewritten for the Next.js/Payload/Postgres stack
- .gitignore trimmed (no more Astro/Sanity entries)
- .gitea/workflows/deploy.yml: drop "Tear down legacy workloads"

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 18:26:48 +02:00

6.2 KiB

REBOURS — Documentation technique

Architecture du projet

rebours/
├── nextjs/                           # App live (Next.js 15 + Payload CMS 3 + Postgres)
│   ├── src/
│   │   ├── app/
│   │   │   ├── (frontend)/           # Site public (/, /collection/[slug], /success)
│   │   │   └── (payload)/admin/      # Back-office Payload (/admin)
│   │   ├── collections/              # Schémas Payload (Products, Media, Users)
│   │   ├── components/admin/         # Custom admin UI (visual product editor)
│   │   ├── lib/payload.ts            # Helpers Payload (mediaUrl, mediaAlt)
│   │   ├── scripts/main.js           # JS client (cursor CAD, grid, panel, carousel)
│   │   ├── payload.config.ts         # Config Payload (collections, plugins, drafts)
│   │   └── migrations/               # Migrations Postgres (auto-générées)
│   ├── public/
│   │   ├── style.css                 # CSS global du site public
│   │   └── assets/                   # Favicons, son ambiant, fallback images
│   ├── Dockerfile                    # Image Docker unique (build + runtime)
│   ├── next.config.mjs
│   └── package.json
├── k8s/                              # Manifests K3s (namespace, configmap, service, deployment, postgres)
├── .gitea/workflows/deploy.yml       # CI/CD : build Docker + déploiement K3s
└── CLAUDE.md

Stack

Couche Techno
Front + Back Next.js 15 (App Router, SSR)
CMS Payload 3 (self-hosted, monté sur /admin)
Base de données PostgreSQL (StatefulSet K3s)
Paiement Stripe Checkout (price_data inline) + plugin-stripe
Images Payload Media → stockage local + sharp
Hébergement K3s sur Proxmox (Traefik en front)
Fonts Space Mono (Google Fonts)

Développement local

Prérequis

  • Node.js >= 20
  • pnpm
  • Docker (pour Postgres local) ou une instance Postgres accessible
  • Un fichier nextjs/.env (voir nextjs/.env.example)

Variables d'environnement (nextjs/.env)

DATABASE_URI=postgres://rebours:rebours@localhost:5432/rebours
PAYLOAD_SECRET=your_32_char_secret

STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

NEXT_PUBLIC_SERVER_URL=http://localhost:3000

Lancer le projet

cd nextjs
pnpm install
pnpm dev

Build

cd nextjs && pnpm build

CMS — Payload

Accès

Collection products

Éditeur visuel sur-mesure (src/components/admin/ProductPreviewEditor.tsx) : la page d'édition reproduit exactement le panneau produit public. Tous les champs éditables au clic (texte inline, carousel d'images, prix). Drawer « Réglages avancés » en bas pour les champs techniques (slug, SEO, Stripe ID).

Champs principaux : productDisplayName, name, slug, index, type, materials, year, status, description, specs, notes, images[] (array d'uploads), price (centimes), currency, availability, isPublished, seoTitle, seoDescription.

Autosave activé (interval 800 ms) via versions.drafts.autosave.

Sync Stripe

Le plugin @payloadcms/plugin-stripe synchronise automatiquement les produits et prix avec Stripe dès que STRIPE_SECRET_KEY est valide. Un hook beforeValidate court-circuite la sync tant que productDisplayName est vide (évite l'erreur Stripe sur autosave de doc neuf).


Stripe

Checkout

  1. Le front envoie le slug du produit à /api/checkout
  2. Le serveur fetch le produit via Payload Local API
  3. Création d'une session Stripe avec price_data inline
  4. Redirect vers Stripe
  5. Retour : /success?session_id=...

Endpoints

Route Méthode Description
/api/checkout POST Crée une session Stripe Checkout
/api/session/[id] GET Statut d'une session
/api/stripe/webhook POST Webhook Stripe (plugin-stripe)

Webhook prod : https://rebours.studio/api/stripe/webhook


Production

Architecture K3s

Internet :443 → Traefik (10.10.10.2) → Service rebours-web → Pod rebours-web :3000
                                                           ↘ Service rebours-postgres :5432

Pods (namespace rebours)

Workload Port Rôle
rebours-web (Deployment) 3000 Next.js + Payload (tout-en-un)
rebours-postgres (StatefulSet) 5432 Postgres + PVC

Variables d'environnement en prod

  • ConfigMap (k8s/configmap.yml) : NEXT_PUBLIC_SERVER_URL, DATABASE_URI
  • Secret rebours-db-secret : POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD
  • Secret rebours-app-secret : PAYLOAD_SECRET, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET
  • Secret gitea-registry-secret : pull de l'image depuis le registre Gitea

Les secrets d'app sont créés par la CI depuis les Gitea Actions secrets.

Déploiement

Push sur main → Gitea Actions build l'image Docker puis applique les manifests K3s.

git push gitea main

Repo Gitea : https://git.arthurbarre.fr/ordinarthur/rebours

Debugging prod

# Pods
ssh arthur@100.78.207.119 "sudo kubectl -n rebours get pods"

# Logs
ssh arthur@100.78.207.119 "sudo kubectl -n rebours logs deployment/rebours-web --tail=50"

# Redémarrer
ssh arthur@100.78.207.119 "sudo kubectl -n rebours rollout restart deployment/rebours-web"

# Shell Postgres
ssh arthur@100.78.207.119 "sudo kubectl -n rebours exec -it rebours-postgres-0 -- psql -U rebours"

Routing

URL Comportement
/ Page principale (SSR, Payload Local API)
/collection/[slug] Page produit (SSR), auto-open panel via window.__OPEN_PANEL__
/success?session_id=... Confirmation Stripe
/admin Back-office Payload
/api/* Routes Payload (REST + GraphQL) + endpoints custom (checkout, webhook)

Fichiers à ne jamais versionner

  • nextjs/.env
  • node_modules/
  • nextjs/.next/