尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Site qui permet de prendre rendez-vous chez des tatoueur, envoyer des images et chatter directement avec la personne et qu'elle puisse payer directement
翻译准备中
正在加载完整 README。
查看完整 README ↗Marketplace mobile-first qui met en relation des clients et des tatoueurs.
Je veux un tatoueur → je vois ceux autour de moi → je regarde leurs tatouages → je choisis → je contacte/réserve.
Le mobile (375–430 px) est la version de référence ; le desktop en est une adaptation.
Cahier des charges : docs/SPEC.md · décisions de conception : docs/DECISIONS.md.
Prérequis : Node.js ≥ 20.9.
npm install # copie aussi le worker MapLibre dans public/vendor (postinstall)
npm run dev # http://localhost:3000
Production :
npm run build && npm run start
Il n'y a pas encore de backend utilisateur : la connexion (/connexion) ne demande qu'un prénom.
Profil → « Passer en mode tatoueur·se / client » pour changer de côté ; « Réinitialiser la démo » remet les données à zéro.
vercel.json fixe le framework (Next.js), les commandes et la région (Paris, cdg1) : le projet se
déploie même si le projet Vercel a été créé sur un dépôt vide (préréglage « Other » sinon, qui ne
publie que public/ → 404). npm install lance le postinstall (copie du worker MapLibre) puis next build.
main) — fusionner la branche de travail dans main pour mettre à jour le site principal.FileStorage avant une vraie mise en production.| Commande | Rôle |
|---|---|
npm run dev | Serveur de développement (Turbopack) |
npm run build / npm run start | Build et serveur de production |
npm run lint | ESLint (config Next + TypeScript) |
npm run typecheck | next typegen + tsc --noEmit (TypeScript strict) |
npm test | Tests unitaires Vitest (tests/unit) |
npm run test:e2e | Tests Playwright sur iPhone SE 375, iPhone 15 393, iPhone Pro Max 430, Pixel 7 412, Desktop 1280 |
npm run icons | Régénère les icônes PWA depuis le logo SVG |
node scripts/screenshots.mjs [url] --sizes=375,430 | Captures d'écran des écrans clés (FAKE_TILES=1 hors réseau) |
node scripts/bundle-size.mjs [url] | Poids du JS initial par page (gzip et brotli) |
Les tests e2e démarrent npm run start sur le port 3100 (faire npm run build avant), ou utilisent PLAYWRIGHT_BASE_URL.
CHROMIUM_PATH permet d'indiquer un Chromium déjà installé.
Voir .env.example.
| Variable | Défaut | Rôle |
|---|---|---|
NEXT_PUBLIC_MAP_STYLE_URL | (vide) | Style MapLibre (URL JSON). Vide = fond clair CARTO Positron (raster gratuit, attribution OSM/CARTO affichée) |
UPLOAD_DIR | .data/uploads | Dossier du stockage disque des images uploadées |
STRIPE_SECRET_KEY | (vide) | Clé secrète Stripe. Vide = paiement en mode démo |
STRIPE_PRICE_MONTHLY / STRIPE_PRICE_ANNUAL | (vide) | Identifiants de prix Stripe (sinon prix créés à la volée depuis lib/pro-offer.ts) |
STRIPE_WEBHOOK_SECRET | (vide) | Secret de signature du webhook Stripe (/api/billing/webhook). Vide = webhook désactivé |
ADMIN_PASSWORD | (vide) | Mot de passe de la page /admin (validation des profils tatoueurs). Vide = page désactivée |
NEXT_PUBLIC_SITE_URL | https://fastattoo.com | URL publique (sitemap, robots) |
app/ Routes (App Router)
page.tsx Accueil
explorer/ Carte + bottom sheet (cœur du produit)
tatoueurs/[slug]/ Profil tatoueur, /demande = formulaire 8 étapes
messages/ Liste et fil de discussion
favoris/ profil/ connexion/ notifications/ offline/
pro/ Espace tatoueur : dashboard, demandes, calendrier, portfolio, onboarding, abonnement
api/billing/ config, checkout, verify, subscription, upgrade (Stripe)
mon-abonnement/ Abonnement du tatoueur (slides pour passer à l'annuel)
devenir-tatoueur/paiement/ Paiement obligatoire (fin d'inscription ; accès bloqué sinon, voir proxy.ts)
proxy.ts Renvoie un tatoueur connecté sans abonnement actif vers le paiement
api/artists/ search, suggest, cards, [slug]
api/uploads/ Upload d'images (normalisation sharp)
media/ Variantes d'images (art de démo, avatars, uploads)
manifest.ts Manifest PWA
components/
ui/ Primitives (Button, Sheet, Picture, Icon, Chip…)
layout/ Navigation basse / desktop, runtime (toasts, SW)
explore/ Carte MapLibre, bottom sheet, carrousel, filtres, recherche
artist/ Cards, portfolio masonry, plein écran, avis, mini-carte
request/ chat/ client/ pro/ account/ pwa/ home/
lib/ Logique métier pure et testable
data/ Interface ArtistRepository + implémentation mémoire + données de démo
search/ parse.ts (recherche intelligente), engine.ts, filtres ↔ URL
storage/ Interface FileStorage + stockage disque local
billing/ Forfaits (plans.ts, testé) + client Stripe (stripe.ts)
notifications/ Canaux de notification (in-app, push navigateur)
store/ État client (Zustand) des Phases 3–5 + données de démo
art/ Générateur procédural des visuels de démo
images.ts geo.ts calendar.ts dates.ts masonry.ts
public/sw.js Service worker
tests/unit, tests/e2e Vitest, Playwright
| Élément | Statut |
|---|---|
| Recherche, filtres, géolocalisation, carte, pagination | Réel (API + moteur testé), sur données de démo |
| Tatoueurs, portfolios, avis, créneaux publics | Démo : 30 tatoueurs générés (8 villes), visuels de tatouage générés procéduralement (pas de vraies photos) |
| Pipeline d'images (5 tailles, AVIF/WebP, cache immuable) | Réel, y compris pour les photos uploadées |
| Upload de photos (portfolio, inspirations, messages) | Réel, stockage disque local ; non authentifié |
| Connexion / inscription | Simulée : pas de mot de passe, session sur l'appareil |
| Demandes, messagerie, rendez-vous, calendrier, favoris, avis laissés, notifications | Simulés côté client (localStorage) : un seul appareil, pas de temps réel entre deux utilisateurs |
| Statistiques tatoueur | « Vues du profil » = valeur de démo ; demandes et taux de réponse calculés |
| Notifications push | Architecture prête (canaux + push dans le SW) ; pas d'envoi serveur |
| Abonnement tatoueur (179 €/an « 1 mois offert » ou 19 €/mois, paiement immédiat, sans essai) | Réel via Stripe Checkout à l'inscription (/devenir-tatoueur/inscription) si STRIPE_SECRET_KEY est défini, enregistré dans Neon ; slides + passage à l'annuel sur /mon-abonnement. L'espace pro /pro reste une démo (aucun encaissement) |
| Mise en avant, commission (reste de la Phase 6) | Non implémentés — point d'extension Artist.promoted |
npm run lint, npm run typecheck, npm test (33 tests) : OK.npm run test:e2e : 89 tests OK sur les 5 viewports (1 test mobile ignoré sur desktop).docs/DECISIONS.md § Performance pour les chiffres et les limites connues.