R01. Domain bleibt frameworkfrei
Regel: Domain darf keine Spring, JDBC, AMQP oder Web-Klassen importieren.
Falsch:
import org.springframework.stereotype.Service;
@Service
public class Order { }
Richtig:
public final class Order {
public void markAccepted() {
// reine Fachlogik
}
}
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R02. Application kennt Ports, nicht Adapter
Regel: Use Cases verwenden Interfaces aus ports, keine JdbcTemplate oder RabbitTemplate Klassen.
Falsch:
public class AcceptOrderUseCase {
private final JdbcTemplate jdbc;
}
Richtig:
public class AcceptOrderUseCase {
private final OrderRepository orders;
private final PaymentGateway payments;
}
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R03. Adapter implementieren Ports
Regel: Infrastrukturcode sitzt im adapters-Modul und implementiert fachliche Vertrage.
Falsch:
public interface OrderRepository {
JdbcTemplate jdbc();
}
Richtig:
public final class JdbcOrderRepository implements OrderRepository {
private final JdbcTemplate jdbc;
}
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R04. Runtime ist Composition Root
Regel: Spring Boot verdrahtet, aber Domain wird nicht von Spring gesteuert.
Falsch:
@Autowired
private Order order;
Richtig:
@Bean
AcceptOrderUseCase useCase(OrderRepository repo) {
return new AcceptOrderUseCase(repo);
}
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R05. Outbox statt Dual Write
Regel: DB Update und Event-Erzeugung gehoeren in eine Transaktion.
Falsch:
orders.save(order);
rabbitTemplate.convertAndSend(event);
Richtig:
orders.save(order);
outbox.append(order.id(), "OrderAccepted", payload);
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R06. Security am Rand
Regel: JWT/Keycloak gehoeren in Runtime Security, nicht in Domain.
Falsch:
public void accept(Jwt jwt) {
if(jwt.hasClaim("role")) ...
}
Richtig:
@PreAuthorize("hasRole('ORDER_ADMIN')")
@PostMapping("/{id}/accept")
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R07. Konfiguration externalisieren
Regel: Credentials gehoeren nicht hart in Java-Code.
Falsch:
String password = "order_pass";
Richtig:
spring.datasource.password=${POSTGRES_PASSWORD}
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R08. Tests passend schichten
Regel: Nicht jeder Fachfall braucht Docker.
Falsch:
class QuantityRuleIT { PostgreSQLContainer<?> db; }
Richtig:
class QuantityRuleTest {
@Test void rejectsNegativeQuantity() {}
}
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R09. Observability ist Teil des Designs
Regel: Kritische Pfade brauchen Metriken und Health Checks.
Falsch:
catch(Exception e) { return; }
Richtig:
metrics.paymentFailed();
log.warn("payment failed", e);
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.
R10. Deployment ist nicht nur YAML
Regel: Manifeste brauchen Runbooks, Checks und Rollback-Idee.
Falsch:
kubectl apply -f all.yaml
Richtig:
kustomize build overlays/prod | kubeconform
kubectl rollout status deploy/order-runtime
Pruefen:
grep -R "org.springframework\|JdbcTemplate\|RabbitTemplate" maven-project/domain/src/main/java || true
mvn -q -DskipTests package
Lernwert: Diese Grenze verhindert, dass ein scheinbar kleines Infrastrukturdetail langfristig die Fachlogik schwer testbar und schwer migrierbar macht.