Skip to content

Repository files navigation

💰 +Count - Gestion collaborative de dépenses partagées.

+Count Logo

Une application web moderne pour simplifier la gestion de vos dépenses en groupe...

Symfony PHP PostgreSQL Twig

✍️ Guide de projet | 📖 Documentation principale | 💻 Voir la Démo


📑 Table des Matières

Cliquez pour déplier ...

🎓 Intérêt académique

Ce projet illustre l'application concrète de compétences techniques avancées en développement web full-stack à l'aide de frameworks tel que Symfony :

Compétences Backend

  • 🎯 Architecture MVC avec Symfony 7.4
  • 🔄 Doctrine ORM pour la gestion de la persistance (doc)
  • 🛡️ Services métier pour une logique réutilisable (doc)
  • 📦 DTOs pour le transfert de données structurées
  • ✅ Validation côté serveur avec contraintes (doc)
  • 🔐 Security Component pour l'authentification (doc)

Compétences Frontend

  • Templates Twig modulaires (doc)
  • Dark Mode avec gestion d'état persistant
  • Responsive Design (320px → ∞)
  • JavaScript Vanilla moderne (ES6+)
  • Animations CSS3 pour fluidité

Compétences Base de Données

  • PostgreSQL avec schéma relationnel optimisé
  • Migrations versionnées (doc)
  • Relations complexes (OneToMany, ManyToMany)
  • Notion de Soft Delete

💡 L'intérêt fonctionnel

Le Problème

La gestion des dépenses partagées (colocation, voyages, sorties) génère bien souvent :

  • ❌ Calculs manuels fastidieux
  • ❌ Incompréhensions sur les remboursements
  • ❌ Manque de transparence
  • ❌ Absence d'historique centralisé

La Solution +Count

Page d'acceuil. Page d'acceuil.

✅ Automatisation des calculs pour l'équilibre des dépenses
✅ Transparence totale sur toutes les dépenses
✅ Collaboration avec système de rôles
✅ Historique permanent et accessible pour tous les membres ✅ Interface agréable, intuitive et multi-plateforme (responsive...)

Cas d'Usage

Contexte Utilisation
Colocation Courses, loyer, factures partagées
Voyage Suivi des dépenses courantes en temps réel
Sorties Restaurants, activités entre amis
Toute dépense de groupe Randonnées , Organisation de fêtes...

🏗️ Architecture du Projet

Structure Simplifiée

+count/
├── 📁 src/
│   ├── Controller/        # Contrôleurs MVC
│   ├── Entity/           # Modèles Doctrine
│   ├── Repository/       # Accès données
│   ├── Service/          # Logique métier
│   ├── Form/             # Types de formulaires
│   └── Security/         # Authentification
│
├── 📁 templates/
│   ├── _layouts/         # Layouts de base
│   ├── _components/      # Composants réutilisables
│   └── wallets/          # Pages wallets
│
├── 📁 public/
│   ├── styles/           # CSS (main, forms, wallets...)
│   └── scripts/          # JavaScript
│
└── 📁 migrations/        # Migrations BDD

Architecture du projet avec Symfony (en couches...)

┌─────────────────────┐
│   PRÉSENTATION      │  Controller + Twig
├─────────────────────┤
│   MÉTIER            │  Services + DTOs
├─────────────────────┤
│   PERSISTANCE       │  Entities + Repositories
├─────────────────────┤
│   BASE DE DONNÉES   │  PostgreSQL
└─────────────────────┘

Architecture Projet Symfony


🛠️ Technologies Utilisées

Backend

Technologie Version Utilisation
Symfony 7.4 LTS Framework PHP full-stack (doc)
PHP 8.3 Langage backend
Doctrine 2.4 ORM pour abstraction BDD (doc)
Composer 2.* Gestionnaire de dépendances PHP

Frontend

Technologie Utilisation
Twig Moteur de templates sécurisé (doc)
CSS3 Variables, Grid, Flexbox, Animations
JavaScript ES6+ DOM moderne, Async/Await, Modules
FontAwesome Bibliothèque d'icônes vectorielles

Base de Données

Technologie Justification
PostgreSQL SGBD relationnel assez robuste avec prise en charge des transactions ACID (doc)

📚 Méthodologie de Développement

Entities & Doctrine ORM

Les entités représentent les modèles de données mappés vers PostgreSQL.

Entités principales :

  • User : Utilisateurs de l'application
  • Wallet : Portefeuilles partagés
  • XUserWallet : Table de jonction avec rôles
  • Expense : Dépenses individuelles
#[ORM\Entity(repositoryClass: WalletRepository::class)]
class Wallet
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid')]
    private ?Uuid $uid = null;
    
    #[ORM\Column(length: 100)]
    private ?string $label = null;
    
    #[ORM\OneToMany(mappedBy: 'wallet', targetEntity: Expense::class)]
    private Collection $expenses;
}

📖 Documentation Doctrine

Services Métier

Les services encapsulent la logique métier réutilisable.

Services implémentés :

  • WalletService : Gestion des wallets
  • ExpenseService : Gestion des dépenses
  • BalanceService : Calcul des équilibres
  • UserService : Gestion utilisateurs
class WalletService
{
    public function __construct(
        private WalletRepository $repository,
        private EntityManagerInterface $em
    ) {}
    
    public function create(User $owner, string $label): Wallet
    {
        $wallet = new Wallet();
        $wallet->setLabel($label);
        $wallet->setOwner($owner);
        
        $this->em->persist($wallet);
        $this->em->flush();
        
        return $wallet;
    }
}

📖 Documentation Services

Form Types

Les Form Types gèrent les formulaires de manière objet.

class ExpenseType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', MoneyType::class)
            ->add('description', TextType::class)
            ->add('icon', ChoiceType::class, [
                'choices' => [
                    'Restaurant' => 'fa-utensils',
                    'Transport' => 'fa-car',
                    // ...
                ]
            ]);
    }
}

📖 Documentation Forms

Form Example

Templates Twig

Architecture modulaire avec héritage et composants.

{# Layout de base #}
{% extends '_layouts/base.html.twig' %}

{% block content %}
    <h1>{{ wallet.label }}</h1>
    
    {% include '_components/menu.html.twig' %}
    
    {% for expense in expenses %}
        {# ... #}
    {% endfor %}
{% endblock %}

📖 Documentation Twig

Fixtures de Test

Données de test cohérentes pour développement.

class UserFixtures extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        for ($i = 1; $i <= 10; $i++) {
            $user = new User();
            $user->setEmail("user$i@test.com");
            // ...
            $manager->persist($user);
        }
        $manager->flush();
    }
}
php bin/console doctrine:fixtures:load

📖 Documentation Fixtures

Sécurité
  • Authentification par session avec Security Component
  • Hachage bcrypt des mots de passe
  • CSRF Protection sur tous les formulaires
class WalletVoter extends Voter
{
    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
    {
        $user = $token->getUser();
        
        return match($attribute) {
            'view' => $this->canView($subject, $user),
            'edit' => $this->canEdit($subject, $user),
            default => false
        };
    }
}

📖 Documentation Security


✨ Fonctionnalités Détaillées

Authentification & Gestion Utilisateur

Voir les détails

Inscription

  • Formulaire avec validation email unique
  • Hachage automatique du mot de passe
  • Choix du genre et avatar par défaut

Connexion

  • Authentification par email/mot de passe
  • Système de sessions sécurisées
  • Redirection intelligente après login

Profil Utilisateur

  • Modification des informations
  • Changement d'avatar (12 avatars 3D disponibles)
  • Statistiques personnelles (wallets créés, dépenses, etc.)

Auth Pages Auth Pages


Gestion des Wallets

Voir les détails

Création de Wallet

  • Formulaire simple (nom du wallet)
  • Génération automatique d'un UUID unique
  • Utilisateur créateur = Owner automatiquement

Liste des Wallets

  • Vue d'ensemble avec cartes modernes
  • Affichage du solde total
  • Badge rôle (Admin/Member)
  • Animation au survol

Détails d'un Wallet

  • Solde total en tête de page
  • Liste paginée des dépenses
  • Accordéon pour équilibres à régler
  • Actions selon les droits (edit/delete/invite)

Wallet Pages Wallet Pages


Gestion des Dépenses

Voir les détails

Ajout de Dépense

  • Montant en euros (converti en centimes)
  • Description de la dépense
  • Choix de catégorie avec icône (28 catégories)
  • Enregistrement avec date automatique

Affichage des Dépenses

  • Liste chronologique inversée
  • Icône de catégorie colorée
  • Montant formaté (couleur verte si c'est vous)
  • Pagination (10 par page)

Actions sur Dépenses

  • 👁️ Voir détails : Modal avec infos complètes
  • 🗑️ Supprimer (admin seulement) : Confirmation requise

Expense Management Expense Management


Système de Rôles

Voir les détails

3 Niveaux de Rôles

Rôle Permissions
👑 Owner/Admin Tous les droits + suppression wallet
Admin Gestion membres, dépenses, paramètres
User Lecture seule + ajout dépenses

Gestion des Membres

  • Invitation (sélection utilisateur)
  • Attribution du rôle à l'invitation
  • Promotion/rétrogradation (admin → member)
  • Exclusion avec choix (garder/supprimer les dépenses)

Interface Membres

  • Modal listant tous les membres
  • Avatar + nom + email + rôle
  • Actions contextuelles selon droits

Roles System Roles System


Calcul Automatique des Équilibres

Voir les détails

Algorithme d'Équilibrage

L'application calcule automatiquement qui doit combien à qui pour équilibrer les comptes.

Principe :

  1. Calcul du total des dépenses
  2. Calcul de la part équitable par personne
  3. Détermination des débiteurs et créditeurs
  4. Optimisation du nombre de transactions

Exemple :

Alice a payé : 100€
Bob a payé : 50€
Charlie a payé : 0€

Total : 150€ → Part/personne : 50€

Résultat :
- Bob doit 0€ à Alice (déjà à l'équilibre relatif)
- Charlie doit 50€ à Alice

Affichage

  • Accordéon dépliable "Voir les équilibres"
  • Instructions claires : "X rembourse Y"
  • Montants colorés (vert = vous recevez, rouge = vous devez)
  • Bouton "Solder tous les comptes" (admin)

Balance Calculation


Interface Utilisateur Moderne

Voir les détails

Design System

  • Couleurs : Orange vibrant (#ff5722) + dégradés
  • Typographie : Poppins (Google Fonts)
  • Cards : Glassmorphism avec backdrop-filter
  • Animations : Transitions fluides 0.3s cubic-bezier

Composants Réutilisables

  • Header avec logo animé (spin-pause)
  • Menu FAB flottant (Floating Action Button)
  • Flash messages avec auto-dismiss (5s)
  • Modals avec fond blur
  • Boutons avec hover effects

Interactions

  • Smooth scroll sur ancres
  • Animations au scroll (Intersection Observer)
  • Compteurs animés (statistiques)
  • Floating cards avec parallax

Menu flottant moderne... UI Components

Interface utilisateur personnalisée... UI Components UI Components


🌙 Dark Mode / ☀️ Light mode

Voir les détails

Implémentation

  • Toggle via bouton flottant (bas droite)
  • Persistance dans localStorage
  • Variables CSS dynamiques
  • Transition fluide 0.3s

Activation

// Au chargement
const theme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', theme);

// Au clic
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');

CSS

:root {
    --bg-primary: #f0f2f5;
    --text-dark: #212020;
}

[data-theme="dark"] {
    --bg-primary: #0f172a;
    --text-dark: #e2e8f0;
}

Dark Mode


Responsive Design

Voir les détails

Breakpoints

Largeur Adaptations
≥ 1200px Layout complet desktop
768-1199px Tablette, colonnes réduites
480-767px Mobile, stack vertical
320-479px Très petit mobile, optimisé

Techniques

  • Flexbox pour layouts flexibles
  • CSS Grid pour grilles responsives
  • Media queries mobile-first
  • Touch-friendly (boutons 44px min)

Responsive Views


🚀 Installation & configurations.

Prérequis

  • PHP 8.2+
  • Composer 2.6+
  • PostgreSQL 15+
  • Symfony CLI (optionnel)

Installation

# 1. Cloner le projet

# 2. Installer les dépendances
composer install

# 3. Configurer la base de données
# Éditer .env.local
DATABASE_URL="postgresql://user:password@127.0.0.1:5432/pluscount?serverVersion=15&charset=utf8"

# 4. Créer la base et exécuter les migrations
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate

# 5. (Optionnel) Charger les fixtures
php bin/console doctrine:fixtures:load

# 6. Lancer le serveur
symfony serve
# ou
php -S localhost:8000 -t public/

Configuration Avancée

# config/packages/doctrine.yaml
doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
    orm:
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'

🔮 Perspectives d'Évolution

Court Terme

  • Notifications email (invitations, remboursements)
  • Export PDF des dépenses
  • Recherche et filtres avancés
  • Graphiques de répartition (Chart.js)

Moyen Terme

  • Application mobile (React Native / Flutter)
  • API REST publique
  • Intégration paiement (Stripe)
  • Multi-langues (i18n)

Long Terme

  • Suggestions IA basées sur historique
  • Synchronisation bancaire
  • Communauté et partage de templates
  • Budgets et objectifs d'épargne

Contribution

Les contributions sont les bienvenues !

  1. Fork le projet
  2. Créer une branche (git checkout -b feature/AmazingFeature)
  3. Commit les changements (git commit -m 'Add AmazingFeature')
  4. Push vers la branche (git push origin feature/AmazingFeature)
  5. Ouvrir une Pull Request

Licence

Ce projet est sous licence _.


🙏 Remerciements

  • Équipe pédagogique : Adrien Gras & Yoan Thirion
  • Communauté Symfony pour la documentation super exhaustive.
  • Unsplash pour les images libres de droits
  • FontAwesome pour les icônes vectorielles

Développé avec passion 🤩 par un aventurier surnommé Overlord 😉

⬆ Retour en haut

About

+Count, c'est l'application web qui simplifie la gestion de vos dépenses. Concue pour être ultra-légère, elle est propulsée par Symfony 7, Docker et une architecture Cloud Serverless.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages