Aller au contenu

TP SeckShop – Backend (Spring Boot + dynors-core)

Objectif : prendre un nouveau développeur et lui faire construire un mini backend SeckShop qui utilise correctement dynors-core (DB multi‑tenant, sécurité, logging).

Durée cible : 1 journée (ou 2 demi‑journées) avec accompagnement.


Étape 0 – Pré‑requis

  • Avoir lu :
  • Niveau 1 : Vision globale (repos, tenants, RAGNAR/TAKKU).
  • Niveau 2 : "Projets clients & dynors-core".
  • Disposer d’un PostgreSQL local.
  • Disposer des accès au GitLab Maven Registry DYNORS (token lecture).

Étape 1 – Créer le squelette projet

  1. Créer un projet Gradle Spring Boot seckshop-backend.
  2. Ajouter les dépendances DYNORS (extrait) :
dependencies {
    implementation(platform("com.dynors:dynors-core-bom:1.0.0"))
    implementation("com.dynors:dynors-commons")
    implementation("com.dynors:dynors-security")
    implementation("com.dynors:dynors-db")
    implementation("com.dynors:dynors-logging:1.0.0-SNAPSHOT")

    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.postgresql:postgresql")
}
  1. Configurer le repository GitLab Maven Registry (copier depuis CONFIGURATION_CLIENT_PROJETS.md).

Objectif de fin d’étape : ./gradlew build compile.


Étape 2 – Configurer l’application SeckShop

  1. Créer la classe SeckShopApplication avec :
  2. @SpringBootApplication et scanBasePackages incluant com.dynors.db, com.dynors.security.
  3. @EntityScan sur com.dynors.db.tenant.model + com.client.seckshop.model.
  4. @EnableJpaRepositories sur com.dynors.db.tenant.repository + com.client.seckshop.repository.

  5. Créer application.yml avec :

  6. spring.datasource (PostgreSQL local)
  7. spring.jpa.hibernate.ddl-auto=validate
  8. dynors.db (multi‑tenant, strategy=schema, tier=TIER_2)
  9. dynors.security basique (JWT activé)
  10. dynors.logging.provider=console.

Objectif de fin d’étape : l’application démarre, même si elle ne fait encore rien.


Étape 3 – Modèle métier minimal (Customers)

  1. Créer l’entité Customer dans com.client.seckshop.model :
  2. id (UUID), firstName, lastName, email, phone, createdAt, updatedAt.
  3. Pas de tenant_id explicite (on est en SCHEMA_DEDICATED).

  4. Créer CustomerRepository :

@Repository
public interface CustomerRepository extends TenantAwareRepository<Customer, UUID> {
    Optional<Customer> findByEmail(String email);
}
  1. Créer CustomerService :
  2. méthode createCustomer, findById, findAll.
  3. validation simple (email unique dans le tenant).

  4. Créer CustomerController (/api/customers).

Objectif de fin d’étape : - POST /api/customers crée un client. - GET /api/customers liste les clients du tenant courant.


Étape 4 – Intégrer dynors-logging (DynorsLogger)

  1. Injecter DynorsLogger dans CustomerService.
  2. Ajouter :
  3. un log info à la création de client,
  4. un log error en cas d’exception.

Exemple :

@Autowired
private DynorsLogger logger;

@Autowired
private TenantContextService tenantContextService;

public Customer createCustomer(Customer customer) {
    String tenant = tenantContextService.getCurrentTenant();
    try {
        // ... logique ...
        Customer created = customerRepository.save(customer);
        logger.info("Customer créé", Map.of(
            "tenant", tenant,
            "service", "CustomerService",
            "action", "createCustomer",
            "customerId", created.getId()
        ));
        return created;
    } catch (Exception e) {
        logger.error("Erreur création customer", e, Map.of(
            "tenant", tenant,
            "service", "CustomerService",
            "action", "createCustomer"
        ));
        throw e;
    }
}

Objectif de fin d’étape : voir les logs dans la console avec les métadonnées DYNORS.


Étape 5 – Authentification basique (JWT)

  1. Suivre le guide dynors-security pour :
  2. définir une entité User simple (username/password hashé),
  3. écrire un AuthController /api/auth/login qui renvoie un JWT.
  4. Protéger les endpoints /api/customers/** derrière JWT (Spring Security + filtre dynors-security).

Objectif de fin d’étape : - impossible d’appeler /api/customers sans JWT valide.


Étape 6 – Tests & validation

  • Écrire au moins :
  • un test d’intégration pour CustomerService (création + lecture),
  • un test pour vérifier que le contexte tenant est bien respecté (deux tenants différents → données isolées).
  • Vérifier :
  • que les logs apparaissent bien en provider=console.
  • que l’appli démarre avec un tenant défini.

Étape 7 – Aller plus loin (optionnel)

  • Ajouter une entité Order et lier les commandes à un Customer.
  • Ajouter une métrique de quota simple (ex : nombre max de customers par tenant, usage de QuotaService).
  • Basculer dynors.logging.provider sur sentry dans un environnement de test.