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
- Créer un projet Gradle Spring Boot
seckshop-backend. - 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")
}
- 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
- Créer la classe
SeckShopApplicationavec : @SpringBootApplicationetscanBasePackagesincluantcom.dynors.db,com.dynors.security.@EntityScansurcom.dynors.db.tenant.model+com.client.seckshop.model.-
@EnableJpaRepositoriessurcom.dynors.db.tenant.repository+com.client.seckshop.repository. -
Créer
application.ymlavec : spring.datasource(PostgreSQL local)spring.jpa.hibernate.ddl-auto=validatedynors.db(multi‑tenant, strategy=schema, tier=TIER_2)dynors.securitybasique (JWT activé)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)
- Créer l’entité
Customerdanscom.client.seckshop.model: id(UUID),firstName,lastName,email,phone,createdAt,updatedAt.-
Pas de
tenant_idexplicite (on est enSCHEMA_DEDICATED). -
Créer
CustomerRepository:
@Repository
public interface CustomerRepository extends TenantAwareRepository<Customer, UUID> {
Optional<Customer> findByEmail(String email);
}
- Créer
CustomerService: - méthode
createCustomer,findById,findAll. -
validation simple (email unique dans le tenant).
-
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)
- Injecter
DynorsLoggerdansCustomerService. - Ajouter :
- un log
infoà la création de client, - un log
erroren 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)
- Suivre le guide dynors-security pour :
- définir une entité
Usersimple (username/password hashé), - écrire un
AuthController/api/auth/loginqui renvoie un JWT. - 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é
Orderet lier les commandes à unCustomer. - Ajouter une métrique de quota simple (ex : nombre max de customers par tenant, usage de
QuotaService). - Basculer
dynors.logging.providersursentrydans un environnement de test.