Tous les projets

Application Web

CandiDash

CandiDash est une application full-stack de suivi de candidatures d'emploi, pensée comme un tracker dédié plutôt qu'un tableur ou un CRM surdimensionné. Le frontend Angular (signals, clean architecture domain/infra/application) offre un tableau de bord de KPIs, un CRUD de candidatures avec statuts et types de contrat, et un thème clair/sombre persistant. Le backend NestJS gère l'authentification multi-rôles (JWT + refresh rotation en cookie HttpOnly + 2FA TOTP), des relances automatiques par email via un CRON horaire, et le stockage des CV et lettres de motivation sur Cloudflare R2. L'ensemble est auto-hébergé, sans tracker tiers, avec une API documentée par Swagger.

stack
  • Angular
  • TypeScript
  • NestJS
  • TailwindCSS
  • PostgreSQL
  • JWT
  • Vitest
Aperçu du projet CandiDash

Choix techniques

Pourquoi chaque brique, et ce qu'elle apporte au projet.

  • Angular

    Tout l'état applicatif sur des signals (AuthState, ProfileState : signal privé + computed publics) avec `provideZoneChangeDetection`/eventCoalescing, sans NgRx. Sur un tableau de bord où KPIs et liste se recalculent à chaque mutation, les computed donnent une réactivité fine sans store global.

  • NestJS

    Découpage en modules (Auth, Users, JobTrack, Scheduler, Mail, Storage) qui cadre un backend mêlant CRUD, jobs planifiés et stockage objet. Guards, pipes et décorateurs Swagger fournissent auth, validation et doc OpenAPI sans plomberie maison.

  • Drizzle ORM + PostgreSQL

    Accès SQL typé proche de la base (pas d'ORM lourd à runtime), migrations versionnées et idempotentes rejouées au boot. Postgres apporte des enums natifs pour statuts et types de contrat, et le cascade des FK pour purger un compte supprimé.

Décisions d'architecture

Les arbitrages structurants, avec leur justification.

Clean architecture 3 couches stricte côté Angular
Chaque feature : domain (modèles `type`, gateways abstraites, use-cases) → infra (HTTP) → application (state signals + composants dumb). Le domain ne connaît pas Angular → use-cases testables sans TestBed, implémentation HTTP remplaçable par InMemory.
Stockage objet R2 plutôt que disque local
Le backend tourne en conteneur : tout fichier sur disque disparaît au redéploiement. Externaliser vers R2 garde le conteneur stateless (scalable, recréable sans perte), et la suppression d'un compte/candidature nettoie les objets liés.