Generar el proyecto

En este primer paso generaras el proyecto Task Manager a partir del arquetipo y verificaras que compila y arranca correctamente.

Generar el proyecto

Ejecuta el siguiente comando, proporcionando los parametros del dominio Task Manager:

mvn archetype:generate \
  -DarchetypeGroupId=io.zutun.templates \
  -DarchetypeArtifactId=template-spring-microservice-multitenant \
  -DarchetypeVersion=<version> \
  -DgroupId=io.zutun.tutorial \
  -DartifactId=task-manager \
  -Dpackage=io.zutun.tutorial \
  -DapplicationName=TaskManagerService \
  -DapplicationDesc=Task\ Manager\ Service \
  -DapiBasePath=/tasks \
  -DopenApiTag=Tasks \
  -DaggregateRoot=Task \
  -DdomainName=task \
  -DtableName=tasks

Maven generara el directorio task-manager/ con la siguiente estructura:

task-manager/
├── pom.xml
├── wizard.sh
├── .env
├── Dockerfile
├── lombok.config
├── CLAUDE.md
├── AGENTS.md
└── src/
    ├── main/
    │   ├── java/io/zutun/tutorial/
    │   │   ├── TaskManagerServiceApplication.java
    │   │   ├── task/
    │   │   │   ├── domain/
    │   │   │   │   └── Task.java                        # Aggregate root
    │   │   │   ├── port/
    │   │   │   │   ├── in/                              # Input ports (vacios)
    │   │   │   │   └── out/
    │   │   │   │       ├── TaskPersistencePort.java      # Output port (write)
    │   │   │   │       └── TaskRetrievalPort.java        # Output port (read)
    │   │   │   ├── service/                              # Servicios (vacio)
    │   │   │   ├── adapter/
    │   │   │   │   ├── in/
    │   │   │   │   │   ├── web/                          # Controllers (vacio)
    │   │   │   │   │   └── listener/
    │   │   │   │   │       └── TaskEventHandler.java     # Event listener
    │   │   │   │   └── out/
    │   │   │   │       └── persistence/
    │   │   │   │           ├── TaskPersistenceAdapter.java
    │   │   │   │           └── TaskRepository.java       # JPA repository
    │   │   │   └── exception/
    │   │   │       └── TaskError.java                    # Error codes
    │   │   ├── events/task/
    │   │   │   └── TaskCreatedEvent.java                 # Domain event
    │   │   └── commons/                                  # Infraestructura compartida
    │   └── resources/
    │       ├── application.yaml
    │       ├── application-local.yaml
    │       └── db/changelog/                             # Migraciones Liquibase
    │           ├── db.changelog-master.yaml
    │           ├── v0.0.1__domain_events_and_shedlock_tables.yaml
    │           ├── v0.0.2__create_aggregate_tables.yaml
    │           └── v0.0.3_create_command_tables.yaml
    └── test/
        ├── java/io/zutun/tutorial/
        │   └── it/
        │       ├── ApiSteps.java                         # BDD steps (API)
        │       └── ApiClient.java                        # Cliente HTTP
        └── resources/
            └── api/
                └── 000_application_health.feature         # Health check

Que incluye el proyecto generado

El arquetipo genera la estructura base del microservicio con:

  • Un aggregate root Task que extiende AbstractAuditable y publica un TaskCreatedEvent al ser creado.

  • Dos output ports separados: TaskPersistencePort (escritura) y TaskRetrievalPort (lectura).

  • Un adaptador de persistencia TaskPersistenceAdapter con su repositorio JPA.

  • Un listener de eventos TaskEventHandler para procesar eventos de dominio.

  • Migraciones Liquibase que crean la tabla tasks con columnas de auditoria, las tablas outbox_events/inbox_events para el patron outbox y la tabla shedlock para bloqueos distribuidos.

  • Configuracion multi-tenant con tres tenants preconfigurados en el perfil local: public, tenant1 y tenant2, cada uno con su propio esquema de base de datos.

  • Tests BDD end-to-end con un escenario de health check como punto de partida.

Los paquetes port/in, service y adapter/in/web se generan vacios — los iras completando a lo largo del tutorial.

Inicializar y ejecutar

Ingresa al directorio generado e inicializa el entorno local:

cd task-manager
./wizard.sh init-all

Esto ejecuta dos acciones:

  1. init-idea — genera las run configurations de IntelliJ IDEA.

  2. init-h2 — crea la base de datos H2 local y ejecuta las migraciones Liquibase para cada tenant.

Arranca el servicio:

./wizard.sh run

Verificar

Una vez iniciado, verifica que el servicio responde:

curl http://localhost:8080/actuator/health

La documentacion OpenAPI estara disponible en http://localhost:8080/swagger-ui.html.

Siguiente paso

Con el proyecto generado y funcionando, en el siguiente paso vas a crear tu primer caso de uso.