7.8 KiB
7.8 KiB
Structure du Projet
📁 Organisation des fichiers
mes-budgets-participatifs/
├── src/
│ ├── app/ # Pages Next.js (App Router)
│ │ ├── page.tsx # Page d'accueil
│ │ ├── admin/ # Pages d'administration (protégées)
│ │ │ ├── page.tsx # Dashboard principal
│ │ │ ├── settings/ # Paramètres SMTP
│ │ │ └── campaigns/[id]/ # Pages de gestion par campagne
│ │ ├── api/ # API Routes
│ │ │ ├── send-participant-email/
│ │ │ ├── test-email/
│ │ │ └── test-smtp/
│ │ ├── campaigns/[id]/ # Pages publiques (anciennes routes)
│ │ │ ├── propose/ # Dépôt de propositions
│ │ │ └── vote/[participantId] # Vote public
│ │ ├── p/[slug]/ # Pages publiques (nouvelles routes courtes)
│ │ │ ├── page.tsx # Dépôt de propositions par slug
│ │ │ └── success/ # Page de succès pour dépôt
│ │ │ └── page.tsx
│ │ └── v/[shortId]/ # Pages de vote (nouvelles routes courtes)
│ │ ├── page.tsx # Vote par short_id
│ │ └── success/ # Page de succès pour vote
│ │ └── page.tsx
│ ├── components/ # Composants React
│ │ ├── ui/ # Composants Shadcn/ui
│ │ ├── AuthGuard.tsx # Protection des routes
│ │ ├── Navigation.tsx # Navigation principale
│ │ ├── SmtpSettingsForm.tsx # Configuration SMTP
│ │ └── [Modals] # Modales de gestion
│ ├── lib/ # Services et configuration
│ │ ├── supabase.ts # Configuration Supabase
│ │ ├── services.ts # Services de données
│ │ ├── email.ts # Service d'envoi d'emails
│ │ ├── encryption.ts # Chiffrement des données sensibles
│ │ └── utils.ts # Utilitaires
│ └── types/ # Types TypeScript
├── database/
│ └── supabase-schema.sql # Schéma de base de données
├── scripts/
│ └── test-security.js # Tests de sécurité
└── docs/ # Documentation
🔗 Routes de l'application
Routes publiques
Nouvelles routes courtes (recommandées)
-
/p/[slug]- Dépôt de propositions- Exemple :
/p/budget-2024 - Utilise le slug de la campagne pour un lien court et lisible
- Exemple :
-
/v/[shortId]- Vote public- Exemple :
/v/ABC123 - Utilise un identifiant court unique pour chaque participant
- Exemple :
Anciennes routes (compatibilité)
-
/campaigns/[id]/propose- Dépôt de propositions- Exemple :
/campaigns/123e4567-e89b-12d3-a456-426614174000/propose
- Exemple :
-
/campaigns/[id]/vote/[participantId]- Vote public- Exemple :
/campaigns/123e4567-e89b-12d3-a456-426614174000/vote/987fcdeb-51a2-43d1-b789-123456789abc
- Exemple :
Routes d'administration
/admin- Dashboard principal/admin/settings- Paramètres SMTP/admin/campaigns/[id]/propositions- Gestion des propositions/admin/campaigns/[id]/participants- Gestion des participants/admin/campaigns/[id]/stats- Statistiques de la campagne
🗄️ Structure de la base de données
Tables principales
campaigns
id(UUID) - Identifiant uniquetitle(TEXT) - Titre de la campagnedescription(TEXT) - Descriptionstatus(TEXT) - Statut : 'deposit', 'voting', 'closed'budget_per_user(INTEGER) - Budget par utilisateurspending_tiers(TEXT) - Montants disponibles (ex: "10,25,50,100")slug(TEXT, UNIQUE) - Slug pour les liens courtscreated_at,updated_at(TIMESTAMP)
participants
id(UUID) - Identifiant uniquecampaign_id(UUID) - Référence vers la campagnefirst_name,last_name(TEXT) - Nom et prénomemail(TEXT) - Adresse emailshort_id(TEXT, UNIQUE) - Identifiant court pour les liens de votecreated_at(TIMESTAMP)
propositions
id(UUID) - Identifiant uniquecampaign_id(UUID) - Référence vers la campagnetitle,description(TEXT) - Titre et descriptionauthor_first_name,author_last_name,author_email(TEXT) - Informations de l'auteurcreated_at(TIMESTAMP)
votes
id(UUID) - Identifiant uniquecampaign_id(UUID) - Référence vers la campagneparticipant_id(UUID) - Référence vers le participantproposition_id(UUID) - Référence vers la propositionamount(INTEGER) - Montant votécreated_at,updated_at(TIMESTAMP)
Fonctions PostgreSQL
generate_slug(title TEXT)
Génère automatiquement un slug unique à partir du titre d'une campagne.
generate_short_id()
Génère automatiquement un identifiant court unique pour les participants.
🔧 Services et utilitaires
Services principaux (src/lib/services.ts)
campaignService
getAll()- Récupère toutes les campagnescreate(campaign)- Crée une nouvelle campagne (génère automatiquement le slug)update(id, updates)- Met à jour une campagnedelete(id)- Supprime une campagnegetBySlug(slug)- Récupère une campagne par son sluggetStats(campaignId)- Récupère les statistiques d'une campagne
participantService
getByCampaign(campaignId)- Récupère les participants d'une campagnecreate(participant)- Crée un nouveau participant (génère automatiquement le short_id)update(id, updates)- Met à jour un participantdelete(id)- Supprime un participantgetByShortId(shortId)- Récupère un participant par son short_id
propositionService
getByCampaign(campaignId)- Récupère les propositions d'une campagnecreate(proposition)- Crée une nouvelle propositionupdate(id, updates)- Met à jour une propositiondelete(id)- Supprime une proposition
voteService
getByParticipant(campaignId, participantId)- Récupère les votes d'un participantcreate(vote)- Crée un nouveau votedeleteByParticipant(campaignId, participantId)- Supprime tous les votes d'un participant
🚀 Scripts utilitaires
scripts/test-security.js
Script pour tester la sécurité de l'application et vérifier les politiques RLS.
Usage :
npm run test:security
Fonctionnalités :
- Vérifie que les tables existent et sont accessibles
- Teste les politiques RLS (Row Level Security)
- Valide les permissions d'accès
- Génère un rapport de sécurité détaillé
🔒 Sécurité
Authentification
- Utilisation de Supabase Auth pour l'authentification des administrateurs
- Protection des routes d'administration avec
AuthGuard
Autorisation
- Row Level Security (RLS) activé sur toutes les tables
- Contrôle d'accès basé sur les rôles utilisateur
Validation des données
- Validation côté client et serveur
- Sanitisation des entrées utilisateur
- Protection contre les injections SQL
📱 Interface utilisateur
Composants UI
- Utilisation de Shadcn/ui pour une interface cohérente
- Design responsive et accessible
- Support du mode sombre
- Composants réutilisables
Pages publiques
- Interface épurée et intuitive
- Formulaires de dépôt et de vote optimisés
- Feedback visuel en temps réel
- Gestion des erreurs et des états de chargement
Interface d'administration
- Dashboard avec statistiques en temps réel
- Gestion complète des campagnes, propositions et participants
- Import/export de données
- Envoi d'emails personnalisés