refactor: split team/player/message into impl/ and exception/ subpackages

Each domain now has:
- Top-level package: contracts (interfaces, entities, enums, values, events).
- exception/ subpackage: exception hierarchy.
- impl/ subpackage: implementations CR-Core ships by default, swappable by
  a game plugin if needed.

Moved (FQN changes for consumers):
- fr.luc.crcore.team.TeamException (+ AlreadyExists, NotFound, Access)
    → fr.luc.crcore.team.exception.*
- fr.luc.crcore.team.TeamServiceImpl, BukkitEventFiringTeamServiceImpl,
  InMemoryTeamRepository, SqliteTeamRepository
    → fr.luc.crcore.team.impl.*
- fr.luc.crcore.player.PlayerException, PlayerProfileNotFoundException
    → fr.luc.crcore.player.exception.*
- fr.luc.crcore.player.PlayerProfileServiceImpl,
  BukkitEventFiringPlayerProfileServiceImpl,
  InMemoryPlayerProfileRepository, SqlitePlayerProfileRepository
    → fr.luc.crcore.player.impl.*
- fr.luc.crcore.message.YamlMessagesService
    → fr.luc.crcore.message.impl.YamlMessagesService

Unchanged top-level packages: database/, command/, common/ (already small
and well-organized). Events stay where they were (already in event/
subpackages).

setup.md tree updated to reflect the new layout. decisions.md logs the
rationale (consumer-facing FQNs, separation between contract and impl).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Antone Barbaud
2026-06-10 10:54:35 +02:00
parent 4651ccbe69
commit 923f48ffc7
20 changed files with 183 additions and 68 deletions
+34
View File
@@ -367,6 +367,40 @@ Format léger : une décision = un titre + contexte + choix + raison.
bases existantes, ALTER TABLE manuel ou suppression du fichier bases existantes, ALTER TABLE manuel ou suppression du fichier
(les bases d'event sont jetables). (les bases d'event sont jetables).
## 2026-06-09 — Réorganisation packages : `impl/` et `exception/` séparés
- **Choix** : pour chaque domaine (`team`, `player`, `message`), les
implémentations passent dans un sous-package `impl/` et les exceptions dans
un sous-package `exception/`. Le top-level du package ne contient plus que
les contrats publics (interfaces, entités, enums, values).
- **Conséquences sur les FQN publics** (importer côté plugin de jeu si on les
utilise) :
- `fr.luc.crcore.team.TeamException``fr.luc.crcore.team.exception.TeamException`
(et ses 3 sous-classes)
- `fr.luc.crcore.team.TeamServiceImpl``fr.luc.crcore.team.impl.TeamServiceImpl`
(idem `BukkitEventFiring*`, `InMemory*Repository`, `Sqlite*Repository`)
- `fr.luc.crcore.player.PlayerException``fr.luc.crcore.player.exception.PlayerException`
(et `PlayerProfileNotFoundException`)
- `fr.luc.crcore.player.*Impl` / `*Repository` impl → `fr.luc.crcore.player.impl.*`
- `fr.luc.crcore.message.YamlMessagesService``fr.luc.crcore.message.impl.YamlMessagesService`
- **Inchangés** : tous les enums, entités, interfaces de service et de repo,
ranking records, events (qui étaient déjà dans un sous-package
{@code event/}).
- **Raison** : lisibilité. Un dev qui ouvre `fr.luc.crcore.team/` voit
immédiatement les contrats (Team, TeamService, TeamRepository, enums,
events) sans se faire noyer par les impls. Pour overrider, il sait où
chercher (`impl/`). Pour catch une exception, il sait où chercher
(`exception/`).
- **Convention top-level vs impl/** :
- **Top-level** = ce qu'un consommateur doit connaître pour utiliser ou
étendre l'API : interfaces, entités, enums, values, events.
- **impl/** = ce que CR-Core fournit par défaut, qu'un game plugin peut
swap. C'est aussi là que vivent les sous-classes utilisées en interne
par le bootstrap (BukkitEventFiring*ServiceImpl, Sqlite*Repository).
- **Pas appliqué à `database/`, `command/` et `common/`** : ces packages
sont déjà petits et bien lisibles ; ajouter `impl/` à 3 fichiers serait
cosmétique.
## 2026-06-09 — `MessagesService` : YAML externalisable, un seul fichier par plugin ## 2026-06-09 — `MessagesService` : YAML externalisable, un seul fichier par plugin
- **Choix** : nouveau module `fr.luc.crcore.message` avec une interface - **Choix** : nouveau module `fr.luc.crcore.message` avec une interface
+52 -44
View File
@@ -211,50 +211,58 @@ CitesPlugin/ # dossier IntelliJ (renommer plus t
│ ├── TeamScoreSubCommand.java # /core team score (admin) │ ├── TeamScoreSubCommand.java # /core team score (admin)
│ ├── TeamTopSubCommand.java # /core team top │ ├── TeamTopSubCommand.java # /core team top
│ └── TeamSetSpawnSubCommand.java # /core team setspawn │ └── TeamSetSpawnSubCommand.java # /core team setspawn
├── team/ ├── message/ # service de messages YAML
│ ├── Team.java │ ├── MessagesService.java # interface (contrat public)
── TeamMember.java ── impl/
├── TeamRole.java └── YamlMessagesService.java # impl par défaut
├── TeamColor.java ├── team/ # contrats + entités au top
│ ├── TeamVisibility.java │ ├── Team.java # entité
│ ├── TeamRanking.java # record │ ├── TeamMember.java # entité
│ ├── TeamRepository.java │ ├── TeamRole.java # enum
│ ├── InMemoryTeamRepository.java │ ├── TeamColor.java # enum
│ ├── SqliteTeamRepository.java │ ├── TeamVisibility.java # enum
│ ├── TeamService.java │ ├── TeamRanking.java # value
│ ├── TeamServiceImpl.java │ ├── TeamService.java # interface
│ ├── BukkitEventFiringTeamServiceImpl.java # impl par défaut │ ├── TeamRepository.java # interface
│ ├── TeamException.java │ ├── event/ # Bukkit events team
│ ├── TeamAlreadyExistsException.java ├── TeamEvent.java # base
│ ├── TeamNotFoundException.java ├── TeamCreateEvent.java
│ ├── TeamAccessException.java ├── TeamDissolveEvent.java
└── event/ # Bukkit events team │ ├── TeamMemberAddEvent.java
├── TeamEvent.java # base ├── TeamMemberRemoveEvent.java
├── TeamCreateEvent.java ├── PlayerJoinTeamEvent.java
├── TeamDissolveEvent.java ├── TeamLeadershipTransferEvent.java
├── TeamMemberAddEvent.java ├── TeamVisibilityChangeEvent.java
├── TeamMemberRemoveEvent.java ├── TeamScoreChangeEvent.java
── PlayerJoinTeamEvent.java ── TeamSpawnPointChangeEvent.java
├── TeamLeadershipTransferEvent.java ├── exception/ # hiérarchie d'exceptions team
├── TeamVisibilityChangeEvent.java ├── TeamException.java # base
├── TeamScoreChangeEvent.java ├── TeamAlreadyExistsException.java
── TeamSpawnPointChangeEvent.java ── TeamNotFoundException.java
└── player/ │ │ └── TeamAccessException.java
── PlayerProfile.java ── impl/ # implémentations swappables
├── PlayerRanking.java ├── TeamServiceImpl.java # service de base
├── PlayerProfileRepository.java ├── BukkitEventFiringTeamServiceImpl.java # impl par défaut
├── InMemoryPlayerProfileRepository.java ├── InMemoryTeamRepository.java # repo en mémoire
── SqlitePlayerProfileRepository.java ── SqliteTeamRepository.java # repo SQLite write-through
── PlayerProfileService.java ── player/ # contrats + entités au top
├── PlayerProfileServiceImpl.java ├── PlayerProfile.java # entité
├── BukkitEventFiringPlayerProfileServiceImpl.java ├── PlayerRanking.java # value
├── PlayerException.java ├── PlayerProfileService.java # interface
├── PlayerProfileNotFoundException.java ├── PlayerProfileRepository.java # interface
── event/ # Bukkit events player ── event/ # Bukkit events player
├── PlayerProfileEvent.java ├── PlayerProfileEvent.java
├── PlayerProfileCreateEvent.java ├── PlayerProfileCreateEvent.java
├── PlayerProfileDeleteEvent.java ├── PlayerProfileDeleteEvent.java
└── PlayerScoreChangeEvent.java └── PlayerScoreChangeEvent.java
├── exception/
│ ├── PlayerException.java
│ └── PlayerProfileNotFoundException.java
└── impl/
├── PlayerProfileServiceImpl.java
├── BukkitEventFiringPlayerProfileServiceImpl.java
├── InMemoryPlayerProfileRepository.java
└── SqlitePlayerProfileRepository.java
``` ```
## Fichier messages ## Fichier messages
+7 -7
View File
@@ -3,15 +3,15 @@ package fr.luc.crcore;
import fr.luc.crcore.command.builtin.CoreCommand; import fr.luc.crcore.command.builtin.CoreCommand;
import fr.luc.crcore.database.Database; import fr.luc.crcore.database.Database;
import fr.luc.crcore.message.MessagesService; import fr.luc.crcore.message.MessagesService;
import fr.luc.crcore.message.YamlMessagesService; import fr.luc.crcore.message.impl.YamlMessagesService;
import fr.luc.crcore.player.BukkitEventFiringPlayerProfileServiceImpl; import fr.luc.crcore.player.impl.BukkitEventFiringPlayerProfileServiceImpl;
import fr.luc.crcore.player.InMemoryPlayerProfileRepository; import fr.luc.crcore.player.impl.InMemoryPlayerProfileRepository;
import fr.luc.crcore.player.PlayerProfileRepository; import fr.luc.crcore.player.PlayerProfileRepository;
import fr.luc.crcore.player.PlayerProfileService; import fr.luc.crcore.player.PlayerProfileService;
import fr.luc.crcore.player.SqlitePlayerProfileRepository; import fr.luc.crcore.player.impl.SqlitePlayerProfileRepository;
import fr.luc.crcore.team.BukkitEventFiringTeamServiceImpl; import fr.luc.crcore.team.impl.BukkitEventFiringTeamServiceImpl;
import fr.luc.crcore.team.InMemoryTeamRepository; import fr.luc.crcore.team.impl.InMemoryTeamRepository;
import fr.luc.crcore.team.SqliteTeamRepository; import fr.luc.crcore.team.impl.SqliteTeamRepository;
import fr.luc.crcore.team.TeamRepository; import fr.luc.crcore.team.TeamRepository;
import fr.luc.crcore.team.TeamService; import fr.luc.crcore.team.TeamService;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -7,7 +7,7 @@ import fr.luc.crcore.command.SubCommand;
import fr.luc.crcore.message.MessagesService; import fr.luc.crcore.message.MessagesService;
import fr.luc.crcore.team.Team; import fr.luc.crcore.team.Team;
import fr.luc.crcore.team.TeamColor; import fr.luc.crcore.team.TeamColor;
import fr.luc.crcore.team.TeamException; import fr.luc.crcore.team.exception.TeamException;
import fr.luc.crcore.team.TeamService; import fr.luc.crcore.team.TeamService;
import fr.luc.crcore.team.TeamVisibility; import fr.luc.crcore.team.TeamVisibility;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -5,7 +5,7 @@ import fr.luc.crcore.command.CommandResult;
import fr.luc.crcore.command.SubCommand; import fr.luc.crcore.command.SubCommand;
import fr.luc.crcore.message.MessagesService; import fr.luc.crcore.message.MessagesService;
import fr.luc.crcore.team.Team; import fr.luc.crcore.team.Team;
import fr.luc.crcore.team.TeamException; import fr.luc.crcore.team.exception.TeamException;
import fr.luc.crcore.team.TeamService; import fr.luc.crcore.team.TeamService;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -1,4 +1,5 @@
package fr.luc.crcore.message; package fr.luc.crcore.message.impl;
import fr.luc.crcore.message.MessagesService;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@@ -1,4 +1,4 @@
package fr.luc.crcore.player; package fr.luc.crcore.player.exception;
public class PlayerException extends RuntimeException { public class PlayerException extends RuntimeException {
@@ -1,4 +1,4 @@
package fr.luc.crcore.player; package fr.luc.crcore.player.exception;
public class PlayerProfileNotFoundException extends PlayerException { public class PlayerProfileNotFoundException extends PlayerException {
@@ -1,4 +1,10 @@
package fr.luc.crcore.player; package fr.luc.crcore.player.impl;
import fr.luc.crcore.player.exception.PlayerProfileNotFoundException;
import fr.luc.crcore.player.exception.PlayerException;
import fr.luc.crcore.player.PlayerProfileRepository;
import fr.luc.crcore.player.PlayerProfileService;
import fr.luc.crcore.player.PlayerRanking;
import fr.luc.crcore.player.PlayerProfile;
import fr.luc.crcore.player.event.PlayerProfileCreateEvent; import fr.luc.crcore.player.event.PlayerProfileCreateEvent;
import fr.luc.crcore.player.event.PlayerProfileDeleteEvent; import fr.luc.crcore.player.event.PlayerProfileDeleteEvent;
@@ -1,4 +1,10 @@
package fr.luc.crcore.player; package fr.luc.crcore.player.impl;
import fr.luc.crcore.player.exception.PlayerProfileNotFoundException;
import fr.luc.crcore.player.exception.PlayerException;
import fr.luc.crcore.player.PlayerProfileRepository;
import fr.luc.crcore.player.PlayerProfileService;
import fr.luc.crcore.player.PlayerRanking;
import fr.luc.crcore.player.PlayerProfile;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -1,4 +1,10 @@
package fr.luc.crcore.player; package fr.luc.crcore.player.impl;
import fr.luc.crcore.player.exception.PlayerProfileNotFoundException;
import fr.luc.crcore.player.exception.PlayerException;
import fr.luc.crcore.player.PlayerProfileRepository;
import fr.luc.crcore.player.PlayerProfileService;
import fr.luc.crcore.player.PlayerRanking;
import fr.luc.crcore.player.PlayerProfile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -1,4 +1,10 @@
package fr.luc.crcore.player; package fr.luc.crcore.player.impl;
import fr.luc.crcore.player.exception.PlayerProfileNotFoundException;
import fr.luc.crcore.player.exception.PlayerException;
import fr.luc.crcore.player.PlayerProfileRepository;
import fr.luc.crcore.player.PlayerProfileService;
import fr.luc.crcore.player.PlayerRanking;
import fr.luc.crcore.player.PlayerProfile;
import fr.luc.crcore.database.ColumnType; import fr.luc.crcore.database.ColumnType;
import fr.luc.crcore.database.Database; import fr.luc.crcore.database.Database;
@@ -1,4 +1,4 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.exception;
public class TeamAccessException extends TeamException { public class TeamAccessException extends TeamException {
@@ -1,4 +1,4 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.exception;
public class TeamAlreadyExistsException extends TeamException { public class TeamAlreadyExistsException extends TeamException {
@@ -1,4 +1,4 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.exception;
public class TeamException extends RuntimeException { public class TeamException extends RuntimeException {
@@ -1,4 +1,4 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.exception;
public class TeamNotFoundException extends TeamException { public class TeamNotFoundException extends TeamException {
@@ -1,4 +1,16 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.impl;
import fr.luc.crcore.team.exception.TeamAccessException;
import fr.luc.crcore.team.exception.TeamNotFoundException;
import fr.luc.crcore.team.exception.TeamAlreadyExistsException;
import fr.luc.crcore.team.exception.TeamException;
import fr.luc.crcore.team.TeamRepository;
import fr.luc.crcore.team.TeamService;
import fr.luc.crcore.team.TeamRanking;
import fr.luc.crcore.team.TeamVisibility;
import fr.luc.crcore.team.TeamColor;
import fr.luc.crcore.team.TeamRole;
import fr.luc.crcore.team.TeamMember;
import fr.luc.crcore.team.Team;
import fr.luc.crcore.team.event.PlayerJoinTeamEvent; import fr.luc.crcore.team.event.PlayerJoinTeamEvent;
import fr.luc.crcore.team.event.TeamCreateEvent; import fr.luc.crcore.team.event.TeamCreateEvent;
@@ -1,4 +1,16 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.impl;
import fr.luc.crcore.team.exception.TeamAccessException;
import fr.luc.crcore.team.exception.TeamNotFoundException;
import fr.luc.crcore.team.exception.TeamAlreadyExistsException;
import fr.luc.crcore.team.exception.TeamException;
import fr.luc.crcore.team.TeamRepository;
import fr.luc.crcore.team.TeamService;
import fr.luc.crcore.team.TeamRanking;
import fr.luc.crcore.team.TeamVisibility;
import fr.luc.crcore.team.TeamColor;
import fr.luc.crcore.team.TeamRole;
import fr.luc.crcore.team.TeamMember;
import fr.luc.crcore.team.Team;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -1,4 +1,16 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.impl;
import fr.luc.crcore.team.exception.TeamAccessException;
import fr.luc.crcore.team.exception.TeamNotFoundException;
import fr.luc.crcore.team.exception.TeamAlreadyExistsException;
import fr.luc.crcore.team.exception.TeamException;
import fr.luc.crcore.team.TeamRepository;
import fr.luc.crcore.team.TeamService;
import fr.luc.crcore.team.TeamRanking;
import fr.luc.crcore.team.TeamVisibility;
import fr.luc.crcore.team.TeamColor;
import fr.luc.crcore.team.TeamRole;
import fr.luc.crcore.team.TeamMember;
import fr.luc.crcore.team.Team;
import fr.luc.crcore.database.ColumnType; import fr.luc.crcore.database.ColumnType;
import fr.luc.crcore.database.Database; import fr.luc.crcore.database.Database;
@@ -1,4 +1,16 @@
package fr.luc.crcore.team; package fr.luc.crcore.team.impl;
import fr.luc.crcore.team.exception.TeamAccessException;
import fr.luc.crcore.team.exception.TeamNotFoundException;
import fr.luc.crcore.team.exception.TeamAlreadyExistsException;
import fr.luc.crcore.team.exception.TeamException;
import fr.luc.crcore.team.TeamRepository;
import fr.luc.crcore.team.TeamService;
import fr.luc.crcore.team.TeamRanking;
import fr.luc.crcore.team.TeamVisibility;
import fr.luc.crcore.team.TeamColor;
import fr.luc.crcore.team.TeamRole;
import fr.luc.crcore.team.TeamMember;
import fr.luc.crcore.team.Team;
import org.bukkit.Location; import org.bukkit.Location;