// Path: remainder-service/src/main/java/com/apssouza/entities/ToDo.java
// @Entity
// @CheckIsValid
// @EntityListeners(ToDoEntityListener.class)
// public class ToDo implements ValidEntity, Cloneable {
//     
//     public enum TodoStatus { DONE, PENDING }
// 
//     @Id
//     @GeneratedValue
//     private long id;
// 
//     @NotNull
//     @Size(min = 2, max = 256)
//     private String caption;
//     
//     @Column(nullable = false)
//     private String userEmail;
//             
//     private String description;
//     
//     @Generated(GenerationTime.INSERT) //ALWAYS, UPDATE
//     @Temporal(TemporalType.TIMESTAMP)
//     private Date createdat;
//     
//     private int priority;
//     
//     private TodoStatus status = TodoStatus.PENDING;
// 
//     @Version
//     private long version;
// 
//     @OneToMany(
//             cascade = CascadeType.ALL, 
//             mappedBy = "todo", 
//             orphanRemoval = true,
//             fetch = FetchType.EAGER
//     )
//     private Set<Attachment> files = new HashSet<>();
// 
//     //We shouldn’t default to CascadeType.ALL because the CascadeType.REMOVE might 
//     //end-up deleting more than we’re expecting even if the relation be related to other register. 
//     @ManyToMany(
//             cascade = {CascadeType.PERSIST, CascadeType.MERGE},
//             fetch = FetchType.EAGER
//     )
//     @JoinTable(
//             name = "todo_category",
//             joinColumns = {
//                 @JoinColumn(
//                         name = "todo_id",
//                         referencedColumnName = "id"
//                 )
//             },
//             inverseJoinColumns = {
//                 @JoinColumn(
//                         name = "category_id",
//                         referencedColumnName = "id"
//                 )
//             }
//     )
//     private List<Category> categories = new ArrayList<>();;
// 
//     public ToDo() {
//     }
//     
//     public ToDo(String email, String caption, String description, int priority) {
//         this.caption = caption;
//         this.description = description;
//         this.priority = priority;
//         this.userEmail = email;
//     }
// 
//     public ToDo(ToDo todo, List<Category> categories, Set<Attachment> files, TodoStatus status) {
//         this(todo.getUserEmail(), todo.getCaption(), todo.getDescription(), todo.getPriority());
//         this.categories = Collections.unmodifiableList(categories);
//         this.files = Collections.unmodifiableSet(files);
//         this.status = status;
//     }
// 
//     public String getUserEmail() {
//         return userEmail;
//     }
// 
//     public void setUserEmail(String userEmail) {
//         this.userEmail = userEmail;
//     }
//     
//     
//     public void setCategories(List<Category> categories){
//         this.categories = Collections.unmodifiableList(categories);
//     }
//     
//     public void setAttachments(Set<Attachment> files){
//         this.files = Collections.unmodifiableSet(files);
//     }
// 
//     public void setId(long id) {
//         this.id = id;
//     }
// 
//     public void setCaption(String caption) {
//         this.caption = caption;
//     }
// 
//     public void setDescription(String description) {
//         this.description = description;
//     }
// 
//     public void setPriority(int priority) {
//         this.priority = priority;
//     }
// 
//     public void setFiles(Set<Attachment> files) {
//         this.files = files;
//     }
// 
//     public void setVersion(long version) {
//         this.version = version;
//     }
//     
//     
//     public void setStatus(TodoStatus status){
//         this.status = status;
//     }
// 
//     public TodoStatus getStatus(){
//         return status;
//     }
//     
//     public Long getId() {
//         return id;
//     }
//     
//     public void setId(Long id) {
//         this.id = id;
//     }
//     
//     public String getCaption() {
//         return caption;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// 
//     public int getPriority() {
//         return priority;
//     }
//     
//     @JsonIgnore
//     public Set<Attachment> getAttachments() {
//         return new HashSet<>(files);
//     }
//     
//     @JsonIgnore
//     public List<Category> getCategories() {
//         return new ArrayList<>(categories);
//     }
// 
//     public long getVersion() {
//         return version;
//     }
// 
//     public Date getCreatedat() {
//         return createdat;
//     }
// 
//     public void setCreatedat(Date createdat) {
//         this.createdat = createdat;
//     }
//     
//     @Override
//     public boolean isValid() {
//         if (this.priority <= 10) {
//             return true;
//         }
//         return (this.description != null && !this.description.isEmpty());
//     }
// 
//     @Override
//     public String toString() {
//         return "ToDo{" + "id=" + id + ", caption=" + caption + ", description=" + description + ", priority=" + priority + ", done=" + status + ", version=" + version + '}';
//     }
// 
// }
// 
// Path: todo-infra/src/main/java/com/apssouza/infra/AbstractDomainEvent.java
// public abstract class AbstractDomainEvent implements AppEvent {
// 
//     protected  String uuid;
//     
//     protected Instant when = Instant.now();
// 
//     @Override
//     public String uuid() {
//         return uuid;
//     }
// 
//     @Override
//     public Instant when() {
//         return when;
//     }
// }


import com.apssouza.annotations.ChangeEvent;
import com.apssouza.entities.ToDo;
import com.apssouza.infra.AbstractDomainEvent;
package com.apssouza.events;


/**
 * To Do created event
 *
 * @author apssouza
 */
@ChangeEvent(ChangeEvent.Type.CREATION)
public class TodoCreatedEvent extends AbstractDomainEvent implements TodoChangedEvent {

    private ToDo todo;

// Path: remainder-service/src/main/java/com/apssouza/entities/ToDo.java
// @Entity
// @CheckIsValid
// @EntityListeners(ToDoEntityListener.class)
// public class ToDo implements ValidEntity, Cloneable {
//     
//     public enum TodoStatus { DONE, PENDING }
// 
//     @Id
//     @GeneratedValue
//     private long id;
// 
//     @NotNull
//     @Size(min = 2, max = 256)
//     private String caption;
//     
//     @Column(nullable = false)
//     private String userEmail;
//             
//     private String description;
//     
//     @Generated(GenerationTime.INSERT) //ALWAYS, UPDATE
//     @Temporal(TemporalType.TIMESTAMP)
//     private Date createdat;
//     
//     private int priority;
//     
//     private TodoStatus status = TodoStatus.PENDING;
// 
//     @Version
//     private long version;
// 
//     @OneToMany(
//             cascade = CascadeType.ALL, 
//             mappedBy = "todo", 
//             orphanRemoval = true,
//             fetch = FetchType.EAGER
//     )
//     private Set<Attachment> files = new HashSet<>();
// 
//     //We shouldn’t default to CascadeType.ALL because the CascadeType.REMOVE might 
//     //end-up deleting more than we’re expecting even if the relation be related to other register. 
//     @ManyToMany(
//             cascade = {CascadeType.PERSIST, CascadeType.MERGE},
//             fetch = FetchType.EAGER
//     )
//     @JoinTable(
//             name = "todo_category",
//             joinColumns = {
//                 @JoinColumn(
//                         name = "todo_id",
//                         referencedColumnName = "id"
//                 )
//             },
//             inverseJoinColumns = {
//                 @JoinColumn(
//                         name = "category_id",
//                         referencedColumnName = "id"
//                 )
//             }
//     )
//     private List<Category> categories = new ArrayList<>();;
// 
//     public ToDo() {
//     }
//     
//     public ToDo(String email, String caption, String description, int priority) {
//         this.caption = caption;
//         this.description = description;
//         this.priority = priority;
//         this.userEmail = email;
//     }
// 
//     public ToDo(ToDo todo, List<Category> categories, Set<Attachment> files, TodoStatus status) {
//         this(todo.getUserEmail(), todo.getCaption(), todo.getDescription(), todo.getPriority());
//         this.categories = Collections.unmodifiableList(categories);
//         this.files = Collections.unmodifiableSet(files);
//         this.status = status;
//     }
// 
//     public String getUserEmail() {
//         return userEmail;
//     }
// 
//     public void setUserEmail(String userEmail) {
//         this.userEmail = userEmail;
//     }
//     
//     
//     public void setCategories(List<Category> categories){
//         this.categories = Collections.unmodifiableList(categories);
//     }
//     
//     public void setAttachments(Set<Attachment> files){
//         this.files = Collections.unmodifiableSet(files);
//     }
// 
//     public void setId(long id) {
//         this.id = id;
//     }
// 
//     public void setCaption(String caption) {
//         this.caption = caption;
//     }
// 
//     public void setDescription(String description) {
//         this.description = description;
//     }
// 
//     public void setPriority(int priority) {
//         this.priority = priority;
//     }
// 
//     public void setFiles(Set<Attachment> files) {
//         this.files = files;
//     }
// 
//     public void setVersion(long version) {
//         this.version = version;
//     }
//     
//     
//     public void setStatus(TodoStatus status){
//         this.status = status;
//     }
// 
//     public TodoStatus getStatus(){
//         return status;
//     }
//     
//     public Long getId() {
//         return id;
//     }
//     
//     public void setId(Long id) {
//         this.id = id;
//     }
//     
//     public String getCaption() {
//         return caption;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// 
//     public int getPriority() {
//         return priority;
//     }
//     
//     @JsonIgnore
//     public Set<Attachment> getAttachments() {
//         return new HashSet<>(files);
//     }
//     
//     @JsonIgnore
//     public List<Category> getCategories() {
//         return new ArrayList<>(categories);
//     }
// 
//     public long getVersion() {
//         return version;
//     }
// 
//     public Date getCreatedat() {
//         return createdat;
//     }
// 
//     public void setCreatedat(Date createdat) {
//         this.createdat = createdat;
//     }
//     
//     @Override
//     public boolean isValid() {
//         if (this.priority <= 10) {
//             return true;
//         }
//         return (this.description != null && !this.description.isEmpty());
//     }
// 
//     @Override
//     public String toString() {
//         return "ToDo{" + "id=" + id + ", caption=" + caption + ", description=" + description + ", priority=" + priority + ", done=" + status + ", version=" + version + '}';
//     }
// 
// }
// 
// Path: todo-infra/src/main/java/com/apssouza/infra/AbstractDomainEvent.java
// public abstract class AbstractDomainEvent implements AppEvent {
// 
//     protected  String uuid;
//     
//     protected Instant when = Instant.now();
// 
//     @Override
//     public String uuid() {
//         return uuid;
//     }
// 
//     @Override
//     public Instant when() {
//         return when;
//     }
// }


// Path: remainder-service/src/main/java/com/apssouza/events/TodoCreatedEvent.java
import com.apssouza.annotations.ChangeEvent;
import com.apssouza.entities.ToDo;
import com.apssouza.infra.AbstractDomainEvent;

package com.apssouza.events;


/**
 * To Do created event
 *
 * @author apssouza
 */
@ChangeEvent(ChangeEvent.Type.CREATION)
public class TodoCreatedEvent extends AbstractDomainEvent implements TodoChangedEvent {

    private ToDo todo;

    public TodoCreatedEvent(ToDo todo) {