민첩한 실시간 협업: 개발팀처럼 이벤트 구성
여러 사람이 참여하는 이벤트를 조직하는 것은 복잡한 프로젝트입니다. 해야 할 일이 있습니다. 할당, 충족해야 할 마감일, 변경되는 우선순위 및 내려야 할 결정 함께. ~ 안에 이벤트를 플레이하세요 우리는 민첩한 프로젝트 관리 도구와 실시간 커뮤니케이션을 통합했습니다. 플랫폼에 직접 삽입되므로 다음과 같은 외부 도구가 필요하지 않습니다. Trello, Jira 또는 WhatsApp 그룹.
이 기사에서 찾을 수 있는 내용
- 상태(PLANned, ACTIVE, COMPLETED, CANCELLED)를 통한 스프린트 관리
- 하위 작업, 우선 순위, 종속성 및 피보나치 스토리 포인트가 있는 작업
- 다중 보기: 끌어서 놓기 Kanban 보드, Gantt 타임라인 및 그룹화된 목록
- 실시간 업데이트를 위한 STOMP 프로토콜을 사용하는 WebSocket
- 도메인 이벤트: CommentTaskAddedEvent, StatusTaskChangedEvent 및 기타
- 다중 채널 알림 시스템(인앱 + 이메일)
- 대시보드 및 감사 추적에 대한 활동 추적
- 협업 스토리포인트 투표를 위한 포커 기획
스프린트 관리: 조직을 위한 반복
스프린트는 소프트웨어 개발팀만을 위한 것이 아닙니다. 결혼식을 계획할 때, 축제 또는 기업 행사, 작업을 목표에 따라 반복으로 나눕니다. 명확성은 기본입니다. ~ 안에 이벤트를 플레이하세요 각 스프린트에는 이름, 설명, 특정 목표 및 간격이 있습니다. 잘 정의된 날짜.
스프린트의 수명주기는 제어된 전환을 따릅니다. 상태에서 시작됩니다. 계획됨는 다음으로 전환하여 시작됩니다. 활동적인, 마지막에는 다음과 같이 표시될 수 있습니다. 완전한 o 취소. 전환은 도메인 측에서 검증됩니다. 이미 완료된 스프린트를 시작하거나 스프린트를 취소할 수 있습니다. 최종 상태.
public enum StatoSprint {
PIANIFICATO("Pianificato", "Planned"),
ATTIVO("Attivo", "Active"),
COMPLETATO("Completato", "Completed"),
ANNULLATO("Annullato", "Cancelled");
public boolean canTransitionTo(StatoSprint nuovoStato) {
return switch (this) {
case PIANIFICATO -> nuovoStato == ATTIVO || nuovoStato == ANNULLATO;
case ATTIVO -> nuovoStato == COMPLETATO || nuovoStato == ANNULLATO;
case COMPLETATO, ANNULLATO -> false; // Stati terminali
};
}
}
엔터티 스프린트 DDD 컨텍스트의 집계 루트입니다. 이벤트와 여행 모두와 연관될 수 있습니다(상호 배타적). COMPANY 및 ASSOCIATION 유형 계정에서 사용할 수 있습니다. 시스템 덕분에 생성 날짜와 마지막 업데이트를 자동으로 추적합니다. @생성일 e @LastModifiedDate 의 Spring Data JPA를 사용하며 @버전 관리하다 동시 액세스 시나리오의 낙관적 잠금.
@Entity
public class Sprint {
private Long id;
private Long eventoId; // Associazione a evento
private Long viaggioId; // Associazione a viaggio (mutualmente esclusivo)
private String nome; // Max 100 caratteri
private String descrizione;
private String obiettivo; // Max 500 caratteri
private LocalDate dataInizio;
private LocalDate dataFine;
private StatoSprint stato; // PIANIFICATO, ATTIVO, COMPLETATO, ANNULLATO
private Integer ordine;
private Long creatoDaUserId;
// Factory methods per creazione controllata
public static Sprint creaPerEvento(Long eventoId, String nome, ...) { ... }
public static Sprint creaPerViaggio(Long viaggioId, String nome, ...) { ... }
// Business methods con validazione
public void avvia() { ... } // PIANIFICATO -> ATTIVO
public void completa() { ... } // ATTIVO -> COMPLETATO
public void annulla() { ... } // -> ANNULLATO (da PIANIFICATO o ATTIVO)
}
업무 관리: 조직의 핵심
모든 작업 이벤트를 플레이하세요 그것은 여러 속성을 지닌 풍부한 실체입니다. 제목과 설명이 있고, 특정 사용자에게 할당할 수 있으며 우선순위가 있습니다(중요도 1~10), 시작 및 종료 날짜, 다음을 수행할 수 있는 종속성 시스템 서로의 작업을 차단합니다.
워크플로의 4가지 상태
작업의 수명 주기는 전통적인 Agile 워크플로를 매핑하는 네 가지 상태를 따릅니다.
- TODO (할 일) - 작업이 생성되었지만 아직 시작되지 않았습니다.
- IN_PROGRESS (진행 중) - 누군가가 적극적으로 작업을 수행하고 있습니다.
- 검토 (검토중) - 작업이 완료되어 검토를 기다리는 중입니다.
- 완료 (Completed) - 작업이 완료되고 확인되었습니다.
전환은 유연합니다. 작업은 REVIEW에서 REVIEW로 돌아갈 수 있습니다. 확인에 실패하면 IN_PROGRESS이고, 확인이 나타나면 DONE에 의해 다시 열립니다. 문제. 이러한 접근 방식은 이벤트 조직의 현실을 반영합니다. 상황이 끊임없이 변화하는 곳.
public enum StatoTask {
TODO("Da fare"),
IN_PROGRESS("In corso"),
REVIEW("In revisione"),
DONE("Completato");
// Transizioni flessibili in entrambe le direzioni
public boolean canTransitionTo(StatoTask nuovoStato) {
return true; // TODO <-> IN_PROGRESS <-> REVIEW <-> DONE
}
public int getOrdineProgressione() {
return switch (this) {
case TODO -> 0;
case IN_PROGRESS -> 1;
case REVIEW -> 2;
case DONE -> 3;
};
}
}
하위 작업 및 종속성
작업에는 하위 작업이 있을 수 있습니다(다음을 통해). 상위 작업 ID), 생성 복잡한 활동을 여러 단위로 나눌 수 있는 계층 구조 더 작고 관리하기 쉽습니다. 예를 들어 "위치 준비" 작업은 다음과 같습니다. "방 예약", "케이터링 정리", "장식 설정"과 같은 하위 작업이 있습니다.
종속성 시스템(블록태스크 ID) 선언할 수 있습니다. 한 작업이 다른 작업을 차단합니다. "손님 목록 확인"이 완료될 때까지 완료되면 "자리 표시자 인쇄"가 차단된 상태로 유지됩니다. 자동 차단 외에도 종속성을 통해 다음을 설정할 수 있습니다. 수동 기술 블록 이유가 있는 "확인을 기다리는 중"과 같은 외부 장애를 보고하는 데 유용합니다. 공급자에 의해."
@Entity
public class TaskEvento {
private Long id;
private Long eventoId;
private String titolo; // Max 255 caratteri
private String descrizione;
private Long assegnatoAUserId;
private Long creatoDaUserId;
private Integer importanza; // 1-10 (8+ = alta priorità)
private StatoTask statoTask; // TODO, IN_PROGRESS, REVIEW, DONE
private Instant dataInizio;
private Instant dataFine;
private Long bloccaTaskId; // Dipendenza: questo task blocca un altro
private Boolean bloccatoManualmente;
private String motivoBloccoTecnico;
private Integer ordine;
private Long sprintId; // Associazione a sprint (opzionale)
private Integer storyPoints; // Fibonacci: 1, 2, 3, 5, 8, 13, 21
private Long parentTaskId; // Riferimento al task padre (sottotask)
// Valori Fibonacci validi per story points
private static final Set<Integer> FIBONACCI_VALIDI = Set.of(1, 2, 3, 5, 8, 13, 21);
// Query methods
public boolean isScaduto() { ... } // Data fine passata e non completato
public boolean isUrgente() { ... } // Scade entro 24 ore
public boolean isAltaPriorita() { return importanza >= 8; }
public boolean isSubtask() { return parentTaskId != null; }
}
다중 보기: Kanban, Gantt 및 목록
주최자마다 작업을 보는 방식이 다릅니다. 이를 위해 플랫폼은 동일한 데이터를 공유하는 세 가지 보완적인 보기를 제공합니다. 그러나 그들은 그것들을 다른 방식으로 제시합니다.
드래그 앤 드롭 기능이 있는 칸반 보드
Kanban 보기는 작업을 상태(TODO, TODO, IN_PROGRESS, 검토 및 완료. 드래그 앤 드롭을 사용하면 작업을 이동할 수 있습니다 간단한 드래그만으로 한 열에서 다른 열로 자동 업데이트 PATCH API를 통해 백엔드의 상태. 카드에는 직함, 양수인, 작업에 대한 우선순위(색상 배지 포함), 스토리 포인트 및 시각적 표시기 만료되었거나 긴급하거나 차단되었습니다.
간트 타임라인
Gantt 보기는 시간 타임라인에 작업을 표시하여 명확하게 보여줍니다. 작업과 중요한 기간 간의 중복, 종속성. 컬러 막대 연결 선이 강조 표시되어 각 작업의 기간을 나타냅니다. 관계를 차단하세요. 이 보기는 특히 다음과 같은 경우에 유용합니다. 마감일에 대한 개요를 알아야 하는 주최자.
그룹화된 목록
목록 보기는 고급 필터링 옵션이 포함된 자세한 작업 목록을 제공합니다. 상태별, 담당자별, 스프린트별 또는 우선순위별. 작업은 다음과 같습니다. 중요도, 만료 날짜 또는 사용자 정의 순서를 기준으로 정렬됩니다. API는 서버 측에서 이러한 필터를 직접 지원합니다.
GET /api/v1/events/{eventId}/tasks
?stato=IN_PROGRESS
&assegnatoA=42
&ordinaPer=importanza
&direzione=DESC
GET /api/v1/events/{eventId}/sprints/{sprintId}/tasks
GET /api/v1/events/{eventId}/sprints/backlog // Task non in alcuno sprint
스토리 포인트와 협업 투표(플래닝 포커)
작업의 복잡성을 추정하는 것은 쉽지 않습니다. 특히 다음과 같은 경우에는 더욱 그렇습니다. 더 많은 사람들이 다른 관점을 가지고 있습니다. 시스템 플래닝포커 통합하면 모든 참가자가 피보나치 수열을 사용하여 작업의 복잡성을 평가합니다. (1, 2, 3, 5, 8, 13, 21).
각 사용자는 독립적으로 투표합니다. 일단 다들 투표하면 시스템이 평균을 계산하고 피보나치 값을 제안합니다. 더 가까이서 투표 분포를 보여주고 거기에 있는지 확인하세요. 동의 (모두가 같은 가치에 투표했습니다). 거기에 없으면 합의가 이루어지면 팀은 다시 토론하고 투표할 수 있습니다.
@Entity
@Table(uniqueConstraints = @UniqueConstraint(
columnNames = {"task_id", "utente_id"} // Un voto per utente per task
))
public class VotoStoryPoints {
public static final Set<Integer> VALORI_VALIDI = Set.of(1, 2, 3, 5, 8, 13, 21);
private Long id;
private Long taskId;
private Long utenteId;
private Integer valore; // Valore Fibonacci
private Instant votatoIl;
private Instant aggiornatoIl;
public static VotoStoryPoints crea(Long taskId, Long utenteId, Integer valore) {
if (!VALORI_VALIDI.contains(valore)) {
throw new IllegalArgumentException("Valore non valido: " + valore);
}
// ...
}
public void aggiornaValore(Integer nuovoValore) { ... }
}
GET /api/v1/events/{eventId}/tasks/{taskId}/votes
Response:
{
"taskId": 42,
"totaleVoti": 5,
"mediaVoti": 4.6,
"valoreSuggerito": 5, // Fibonacci più vicino alla media
"distribuzione": {
"3": 2,
"5": 2,
"8": 1
},
"consenso": false,
"votoCorrente": 5 // Voto dell'utente corrente
}
POST /api/v1/events/{eventId}/tasks/{taskId}/votes
Body: { "valore": 5 }
WebSocket 및 실시간 통신
실시간 협업은 핵심 요소 중 하나입니다. 이벤트를 플레이하세요. WebSocket 아키텍처는 프로토콜을 사용합니다. 스톰프 (Simple Text Oriented Messaging Protocol), WebSocket을 통한 양말JS 호환되지 않는 브라우저에 대한 대체 수단으로 사용됩니다.
구성은 세 가지 기본 접두사를 정의합니다. /주제 브로드캐스트 구독의 경우(모든 클라이언트가 메시지를 수신함) /대기줄 지점 간 대기열의 경우 e /사용자 특정 사용자를 위한 비공개 메시지의 경우. 클라이언트가 메시지를 보냅니다. 접두사를 사용하여 서버에 /앱.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// Prefisso per subscription (broadcast e code)
registry.enableSimpleBroker("/topic", "/queue");
// Prefisso per messaggi client -> server
registry.setApplicationDestinationPrefixes("/app");
// Prefisso per messaggi privati a utenti specifici
registry.setUserDestinationPrefix("/user");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// Endpoint con SockJS fallback
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("*")
.withSockJS();
// Endpoint WebSocket nativo
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("*");
}
}
평면도 협업
WebSocket을 사용하는 구체적인 예는 협업 편집기입니다. 계획의. 여러 사용자가 동시에 작업 가능 위치 레이아웃: 테이블 이동, 요소 추가, 크기 조정 지역. 시스템은 다음을 관리합니다.
- 실시간 커서 - 각 사용자는 서로 다른 색상으로 커서를 봅니다.
- 항목 잠금 - 사용자가 항목을 선택하면 다른 사람이 동시에 편집할 수 없습니다.
- 사용자 존재 - 가입/탈퇴 알림을 받은 활성 사용자 목록
- 변경 사항 동기화 - 모든 변경 사항은 연결된 모든 클라이언트에 즉시 전파됩니다.
@Controller
public class PlanimetriaWebSocketController {
// Utenti attivi per evento (ConcurrentHashMap per thread-safety)
private final Map<Long, Set<UtenteAttivoDTO>> utentiPerEvento = new ConcurrentHashMap<>();
// Lock sugli elementi: "evento:eventoId:elementoId" -> utenteId
private final Map<String, Long> lockElementi = new ConcurrentHashMap<>();
// Colori predefiniti: Blu, Verde, Arancione, Rosso, Viola, Rosa, Ciano, Lime
private static final String[] COLORI_UTENTI = {
"#3B82F6", "#10B981", "#F59E0B", "#EF4444",
"#8B5CF6", "#EC4899", "#06B6D4", "#84CC16"
};
@MessageMapping("/planimetria/evento/{eventoId}/join")
@SendTo("/topic/planimetria/evento/{eventoId}")
public PlanimetriaMessageDTO utenteJoinEvento(...) { ... }
@MessageMapping("/planimetria/evento/{eventoId}/cursor")
@SendTo("/topic/planimetria/evento/{eventoId}/cursori")
public PlanimetriaMessageDTO aggiornaCursoreEvento(...) { ... }
@MessageMapping("/planimetria/evento/{eventoId}/lock")
@SendTo("/topic/planimetria/evento/{eventoId}")
public PlanimetriaMessageDTO gestisciLockEvento(...) {
// Tentativo di acquisire lock
Long currentLock = lockElementi.get(lockKey);
if (currentLock == null) {
lockElementi.put(lockKey, utenteId); // Lock acquisito
return PlanimetriaMessageDTO.lockAcquired(...);
}
return null; // Lock già preso da altro utente
}
}
도메인 이벤트: 바인딩된 컨텍스트 간의 통신
시스템은 다음과 같은 패턴으로 도메인 중심 설계 원칙을 따릅니다. 도메인 이벤트 잘 정의되어 있습니다. 중요한 일이 생겼을 때 도메인에서는 다른 구성 요소가 수신할 수 있는 이벤트가 게시됩니다. 그에 따라 반응하여 모듈 간의 느슨한 결합을 유지합니다.
모든 도메인 이벤트는 인터페이스를 구현합니다. 도메인이벤트 이벤트 타임스탬프와 유형 이름을 노출합니다. 이 계약 공통은 시스템 전반에 걸쳐 일관성과 추적성을 보장합니다.
public interface DomainEvent {
LocalDateTime occurredOn();
default String eventType() {
return this.getClass().getSimpleName();
}
}
주요 시스템 이벤트
시스템은 중요한 순간을 다루는 여러 도메인 이벤트를 정의합니다. 조직의:
- 이벤트생성된이벤트 - 새 이벤트가 생성되면 게시됩니다(eventId, title,organiserId, startdata).
- 이벤트게시된이벤트 - 이벤트가 게시되어 초대가 가능한 경우
- 참가자초대이벤트 - 참가자 초대 시 (eventId, userId, eventtitle)
- StatusTaskChanged이벤트 - 이전 상태와 새 상태로 작업 상태 변경
- CommentTaskAddedEvent - 텍스트가 200자로 잘린 작업에 설명 추가
// Evento: cambio stato di un task
public class StatoTaskCambiatoEvent implements DomainEvent {
private final Long taskId;
private final Long eventoId;
private final Long utenteIdCheCambia;
private final String titoloTask;
private final StatoTask vecchioStato;
private final StatoTask nuovoStato;
private final LocalDateTime occurredOn;
}
// Evento: nuovo commento su un task
public class CommentoTaskAggiuntoEvent implements DomainEvent {
private final Long taskId;
private final Long eventoId;
private final Long commentoId;
private final Long autoreUserId;
private final String titoloTask;
private final String testoCommento; // Troncato a 200 caratteri
private final LocalDateTime occurredOn;
}
실시간 알림: 다중 채널 및 지능형
도메인 이벤트가 게시되면 TaskNotifyEventHandler 행동에 나선다. 이 구성요소는 다음을 사용하여 이벤트를 수신합니다. @TransactionalEventListener 위상 포함 AFTER_COMMIT, 알림을 보내기 전에 데이터가 실제로 지속되었는지 확인합니다. 처리는 비동기식으로 발생합니다(@비동기) 하나로 별도의 거래(REQUIRES_NEW) 영향을 미치지 않도록 주요 작업의 성능.
각 이벤트에 대해 시스템은 다음을 식별합니다. 협력자 작업의 (수상자, 창작자, 기타 교류한 이벤트 참가자) 작업) 알림을 피하기 위해 작업을 생성한 사용자를 제외합니다. 방금 수술을 마친 사람입니다.
@Component
public class TaskNotificaEventHandler {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Async
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void gestisciStatoTaskCambiato(StatoTaskCambiatoEvent event) {
// 1. Trova collaboratori (escluso chi ha cambiato lo stato)
List<User> collaboratori = collaboratoriTaskService
.trovaCollaboratori(event.getTaskId(), event.getEventoId(),
event.getUtenteIdCheCambia());
// 2. Per ogni collaboratore: notifica in-app + email
for (User destinatario : collaboratori) {
// Notifica in-app (persistita nel database)
NotificaUtente notifica = NotificaUtente.creaConRiferimento(
destinatario,
TipoNotifica.STATO_TASK_CAMBIATO,
"Task aggiornato",
nomeUtente + " ha cambiato lo stato da ... a ...",
event.getTaskId(), "TASK", link
);
// Email (solo se email verificata)
if (destinatario.getEmailVerificata()) {
emailService.inviaNotificaStatoTaskCambiato(...);
}
}
}
}
통지 유형
시스템은 상황별로 그룹화된 17가지 알림 유형을 지원합니다. 모든 유형 프런트엔드에서 렌더링하기 위한 관련 아이콘(Lucide 라이브러리의)이 있습니다. 그리고 기본 설명입니다.
public enum TipoNotifica {
// Notifiche eventi
INVITO_EVENTO("user-plus", "Sei stato invitato a un evento"),
EVENTO_MODIFICATO("edit", "Un evento è stato modificato"),
EVENTO_ANNULLATO("calendar-x", "Un evento è stato annullato"),
EVENTO_IMMINENTE("bell", "Un evento sta per iniziare"),
// Notifiche task
COMMENTO_TASK("message-circle", "Nuovo commento su un task"),
STATO_TASK_CAMBIATO("refresh-cw", "Lo stato di un task è cambiato"),
TASK_ASSEGNATO("user-check", "Ti è stato assegnato un task"),
// Notifiche spese
NUOVA_SPESA("wallet", "È stata aggiunta una nuova spesa"),
SPESA_ASSEGNATA("credit-card", "Ti è stata assegnata una spesa"),
PROMEMORIA_PAGAMENTO("alert-circle", "Promemoria pagamento"),
// Notifiche collegamenti
RICHIESTA_COLLEGAMENTO("user-plus", "Richiesta di collegamento"),
COLLEGAMENTO_ACCETTATO("user-check", "Collegamento accettato"),
// Sistema
MESSAGGIO_SISTEMA("info", "Messaggio di sistema");
}
인앱 알림: 완전한 구조
- 받는 사람 - 알림을 받는 사용자(ManyToOne 관계)
- 유형 - 아이콘과 설명이 포함된 알림 유형 열거형
- 제목 - 최대 200자, 동적으로 생성됨
- 메시지 - 최대 500자(액션 세부정보 포함)
- 읽기 상태 - 읽기 타임스탬프가 포함된 읽기/읽지 않음 플래그
- 엔터티 참조 - 탐색을 위한 엔터티Id + 엔터티 유형
- 모래밭 - 관련 엔터티로 직접 이동하는 URL
- 메타데이터 - 유연한 추가 데이터를 위한 JSON 필드
활동 추적: 대시보드 및 감사 추적
모든 중요한 사용자 작업이 시스템에 기록됩니다. 활동 추적. 엔터티 사용자 활동 활동 유형, 읽을 수 있는 설명, 타임스탬프, 선택적으로 관련 엔터티 및 JSON 메타데이터에 대한 참조 추가.
이 시스템은 두 가지 목적을 제공합니다. 활동 피드 사용자의 개인 대시보드에서 감사 추적 누가 언제 무엇을 했는지 알고 싶어하는 주최자에게 적합합니다.
public enum TipoAttivita {
// Attività evento
EVENTO_CREATO("calendar", "Evento creato"),
EVENTO_MODIFICATO("edit", "Evento modificato"),
EVENTO_PUBBLICATO("send", "Evento pubblicato"),
EVENTO_CONCLUSO("check-circle", "Evento concluso"),
// Attività partecipanti
PARTECIPANTE_AGGIUNTO("user-plus", "Partecipante aggiunto"),
PARTECIPANTE_CONFERMATO("user-check", "Partecipante confermato"),
// Attività task
TASK_CREATO("plus-square", "Task creato"),
TASK_MODIFICATO("edit", "Task modificato"),
TASK_COMPLETATO("check-square", "Task completato"),
TASK_ELIMINATO("trash-2", "Task eliminato"),
// Attività spese
SPESA_AGGIUNTA("wallet", "Spesa aggiunta"),
SPESA_MODIFICATA("edit-3", "Spesa modificata"),
// Attività inventario
MATERIALE_INVENTARIO_AGGIUNTO("package-plus", "Materiale aggiunto"),
MATERIALE_EVENTO_AGGIUNTO("box", "Materiale assegnato all'evento"),
// Attività sondaggi
SONDAGGIO_CREATO("vote", "Sondaggio creato"),
VOTO_REGISTRATO("check-square", "Voto registrato"),
// ... 40+ tipi totali con icona Lucide e descrizione
}
L'사용자 활동 UUID를 식별자로 사용하고 지원합니다. 팩토리 메소드를 통한 세 가지 생성 모드: 단순 생성, 엔터티(entityId + 엔터티 유형)를 참조하여 생성 및 생성 사용자 정의 JSON 메타데이터를 사용합니다. 이 유연한 디자인으로 적응이 가능합니다. 데이터베이스 스키마를 변경하지 않고 향후 컨텍스트를 추적합니다.
@Entity
public class AttivitaUtente {
private UUID id;
private User utente; // Relazione ManyToOne
private TipoAttivita tipoAttivita;
private String descrizione; // Max 500 caratteri
private LocalDateTime timestamp;
private UUID entityId; // Riferimento opzionale
private String entityType; // "EVENTO", "TASK", "SPESA"...
private String metadata; // JSON aggiuntivo
// Tre factory methods per diversi scenari
public static AttivitaUtente crea(User u, TipoAttivita tipo, String desc) { ... }
public static AttivitaUtente creaConRiferimento(User u, TipoAttivita tipo,
String desc, UUID entityId, String entityType) { ... }
public static AttivitaUtente creaConMetadata(User u, TipoAttivita tipo,
String desc, String metadata) { ... }
}
작업에 대한 의견: 상황별 의사소통
각 작업에는 내장된 주석 스레드가 있습니다. 이벤트 참가자는 설명(최대 2000자)을 추가하면 시스템이 자동으로 도메인 이벤트를 통해 공동작업자에게 알림 CommentTaskAddedEvent. 댓글 작성자만 또는 이벤트 주최자는 댓글을 삭제하여 통제력을 확보할 수 있습니다. 그리고 투명성.
@Entity
public class CommentoTask {
private Long id;
private Long taskId;
private Long autoreUserId;
private String testo; // Max 2000 caratteri, obbligatorio
private Instant creatoIl; // Audit automatico
public static CommentoTask crea(Long taskId, Long autoreUserId, String testo) {
// Validazione: taskId, autoreUserId e testo obbligatori
// Testo max 2000 caratteri
return new CommentoTask(taskId, autoreUserId, testo);
}
public boolean isAutore(Long userId) {
return this.autoreUserId.equals(userId);
}
}
스프린트 API: 통계가 포함된 전체 CRUD
Sprints용 REST API는 모든 CRUD 작업에 대한 엔드포인트를 공개합니다. 고급 기능. 각 스프린트의 응답에는 통계가 포함됩니다. 실시간으로 계산: 총 작업, 완료된 작업, 총 스토리 포인트, 완료된 스토리 포인트 및 진행률.
// CRUD Sprint
GET /api/v1/events/{eventId}/sprints // Lista con filtro stato
GET /api/v1/events/{eventId}/sprints/{id} // Dettaglio singolo
POST /api/v1/events/{eventId}/sprints // Creazione
PUT /api/v1/events/{eventId}/sprints/{id} // Aggiornamento
DELETE /api/v1/events/{eventId}/sprints/{id} // Eliminazione
PATCH /api/v1/events/{eventId}/sprints/{id}/status // Cambio stato
// Gestione task in sprint
GET /api/v1/events/{eventId}/sprints/{id}/tasks // Task nello sprint
POST /api/v1/events/{eventId}/sprints/{id}/tasks/{t} // Aggiungi task
DELETE /api/v1/events/{eventId}/sprints/{id}/tasks/{t} // Rimuovi task
GET /api/v1/events/{eventId}/sprints/backlog // Task senza sprint
// SprintResponse include statistiche calcolate
{
"id": 1,
"nome": "Sprint 1 - Preparazione Location",
"stato": "ATTIVO",
"totaleTask": 12,
"taskCompletati": 7,
"totaleStoryPoints": 42,
"storyPointsCompletati": 28,
"progressoTask": 58.3,
"progressoStoryPoints": 66.7,
"scaduto": false,
"durataGiorni": 14
}
이벤트 조직에 왜 Agile이 필요한가요?
결혼식이나 축제와 같은 복잡한 행사에는 수백 가지 작업이 있습니다. 상호 의존적이고 엄격한 기한이 있으며 많은 사람들이 참여합니다. 접근 방식 짧은 스프린트(1~2주)로 민첩하게 체크포인트를 자주 수행할 수 있습니다. 변화에 적응하고 항상 상태에 대한 가시성을 확보합니다. 조직의. 혜택을 받기 위해 개발자가 될 필요는 없습니다. 칸반 보드 및 스토리 포인트: "무엇을 해야 할지"에 대해 생각해 보세요. "누가 하는가" 그리고 "얼마나 복잡한가".
통합 채팅: 안녕 WhatsApp 그룹
이벤트 조직에서 가장 일반적인 문제 중 하나는 의사소통의 단편화: 그룹 내에서 중요한 메시지가 손실됨 혼란스러운 WhatsApp, 이메일과 채팅의 중복된 정보, 의사결정 추적되지 않은 채널에서. 플랫폼은 통신 시스템을 통합합니다. 각 대화는 이벤트와 연결되어 있습니다. 올바른 맥락.
작업, 인앱 알림 및 메시징 시스템에 대한 의견 내부적으로는 모든 커뮤니케이션을 체계적으로 유지하고 검색 가능. 각 메시지에는 명확한 컨텍스트가 있습니다. 작업, 비용, 참가자 또는 이벤트 전체. 공동 평면 계획에 이미 사용 중인 WebSocket 인프라 실시간 메시징을 위한 기술적 기반을 제공합니다.
핵심 사항
- 4가지 상태와 검증된 전환을 사용한 스프린트(DDD 상태 머신)
- 하위 작업, 4가지 상태, 우선순위 1-10, 종속성 및 수동 잠금이 있는 작업
- 스토리 포인트 피보나치와 협업 플래닝 포커(미디어, 유통, 합의)
- 고급 서버 측 필터가 포함된 Kanban, Gantt 및 목록 보기
- SockJS 폴백, 요소 잠금 및 실시간 커서를 갖춘 WebSocket STOMP
- 제한된 컨텍스트 간의 비동기 통신을 위한 5개의 도메인 이벤트
- 17가지 유형과 빛나는 아이콘을 갖춘 다중 채널 알림(인앱 + 이메일)
- 40개 이상의 활동 유형과 유연한 JSON 메타데이터를 사용한 활동 추적
- 실시간으로 계산된 스프린트 통계를 갖춘 완전한 REST API
프로젝트의 소스 코드는 다음에서 확인할 수 있습니다. GitHub. 완벽한 민첩한 관리 및 실시간 협업 시스템을 사용해 보려면 다음을 방문하세요. www.playtheevent.com.







