アジャイルでリアルタイムのコラボレーション: 開発チームのようにイベントを組織する
複数の人でイベントを企画するのは複雑なプロジェクトです。やるべきタスクがあります 割り当て、守るべき期限、変更される優先順位、下すべき決定 一緒に。で イベントをプレイする アジャイルなプロジェクト管理ツールとリアルタイム通信を統合しました プラットフォームに直接組み込まれるため、次のような外部ツールが不要になります。 Trello、Jira、または WhatsApp グループ。
この記事でわかること
- ステータスによるスプリント管理 (PLANned、ACTIVE、COMPLETED、CANCELLED)
- サブタスク、優先順位、依存関係、およびフィボナッチ ストーリー ポイントを含むタスク
- 複数のビュー: ドラッグ ドロップのカンバン ボード、ガント タイムライン、およびグループ化されたリスト
- ライブアップデート用の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 タイプのアカウントで利用できます。システム おかげで作成日と最終更新が自動的に追跡されます @CreatedDate 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 つの状態
タスクのライフサイクルは、古典的なアジャイル ワークフローをマップする 4 つの状態に従います。
- TODO (To Do) - タスクは作成されましたが、まだ開始されていません
- 進行中 (進行中) - 誰かがそのタスクに積極的に取り組んでいます
- レビュー (レビュー中) - 作業は完了し、レビューを待っています
- 終わり (完了) - タスクが完了し、検証されました。
移行は柔軟です。タスクは 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; }
}
複数のビュー: カンバン、ガント、リスト
主催者ごとに作品の見方が異なります。このために プラットフォームは、同じデータを共有する 3 つの補完的なビューを提供します しかし、彼らはそれらをさまざまな方法で提示します。
ドラッグ&ドロップによるかんばんボード
カンバン ビューでは、タスクが状態に対応する列に整理されます: TODO、 進行中、レビュー、完了。ドラッグ&ドロップでタスクを移動できます 簡単なドラッグである列から別の列に移動し、自動的に更新します PATCH API を介してバックエンドのステータスを確認します。カードにはタイトル、譲受人、 優先順位 (色付きバッジ付き)、ストーリー ポイント、およびタスクの視覚的なインジケーター 期限切れ、緊急、またはブロックされています。
ガント タイムライン
ガント ビューでは、タイムライン上にタスクが表示され、明確に示されます。 重複、タスクと臨界期間の依存関係。色付きのバー 各タスクの所要時間を表し、接続線が強調表示されます。 ブロック関係。このビューは特に次の場合に役立ちます。 締め切りの概要を把握する必要がある主催者。
グループ化されたリスト
リスト ビューには、高度なフィルター オプションを備えたタスクの詳細なリストが表示されます。 ステータス別、担当者別、スプリント別、または優先度別。タスクは次のことができます 重要性、有効期限、またはカスタムオーダーで並べ替えることができます。 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 アーキテクチャでは、次のプロトコルが使用されます。 ストンプ (簡易テキスト指向メッセージング プロトコル) WebSocket 経由、 SockJS 互換性のないブラウザのフォールバックとして。
この構成では、次の 3 つの基本的なプレフィックスを定義します。 /トピック ブロードキャスト サブスクリプションの場合 (すべてのクライアントがメッセージを受信します)、 /列 ポイントツーポイント キューの場合、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
}
}
ドメインイベント: 境界のあるコンテキスト間の通信
このシステムは、次のパターンを持つドメイン駆動設計の原則に従います。 ドメインイベント 明確に定義されています。何か重大なことが起こったとき ドメインでは、他のコンポーネントがリッスンできるイベントが発行されます。 そしてそれに応じて反応し、モジュール間の疎結合を維持します。
すべてのドメイン イベントはインターフェイスを実装します ドメインイベント これにより、イベントのタイムスタンプとタイプ名が公開されます。この契約書 common は、システム全体の一貫性とトレーサビリティを保証します。
public interface DomainEvent {
LocalDateTime occurredOn();
default String eventType() {
return this.getClass().getSimpleName();
}
}
主要なシステムイベント
システムは、重要な瞬間をカバーするいくつかのドメイン イベントを定義します。 組織の:
- イベント作成イベント - 新しいイベントの作成時に公開されます (eventId、title、organiserId、startdata)
- イベント公開イベント - イベントが公開され、招待できるようになったとき
- 参加者招待イベント - 参加者が招待された場合 (eventId、userId、eventtitle)
- ステータスタスク変更イベント - 古い状態と新しい状態を持つタスクの状態の変更
- コメントタスク追加イベント - テキストが 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、 通知を送信する前に、データが実際に保持されていることを確認します。 処理は非同期で行われます (@非同期) 1つで 別のトランザクション (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 文字
- 読み取りステータス - 読み取りタイムスタンプ付きの既読/未読フラグ
- エンティティ参照 - ナビゲーション用のentityId +entityType
- リンク - 関連エンティティに直接移動するための URL
- メタデータ - 柔軟な追加データ用の JSON フィールド
アクティビティ追跡: ダッシュボードと監査証跡
重要なユーザーアクションはすべてシステムに記録されます アクティビティ追跡。実体 ユーザーアクティビティ アクティビティのタイプ、判読可能な説明、タイムスタンプをキャプチャします。 必要に応じて、関連するエンティティと JSON メタデータへの参照 追加。
このシステムは 2 つの目的を果たします。 アクティビティフィード ユーザーの個人ダッシュボードで、 監査証跡 誰がいつ何をしたかを知りたい主催者向けの情報です。
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を識別子として使用し、サポートします ファクトリメソッドによる 3 つの作成モード: 単純な作成、 エンティティ(entityId+entityType)を参照した作成と作成 カスタム 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 文字) を追加すると、システムが自動的に送信します。 ドメインイベントを介したコラボレーターへの通知 コメントタスク追加イベント。コメントの作成者のみ、または イベント主催者はコメントを削除できるため、コントロールを確実に行うことができます そして透明感。
@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);
}
}
Sprint API: 統計を含む完全な CRUD
スプリント用 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
}
イベント組織でなぜアジャイルなのか?
結婚式やお祭りなどの複雑なイベントには何百ものタスクがあります 相互に依存しており、期限が厳しく、多くの人が関わっています。アプローチ 短いスプリント (1 ~ 2 週間) でのアジャイルでは、頻繁なチェックポイントが可能になります。 変化に適応し、常にステータスを把握できる 組織の。メリットを享受するには開発者である必要はありません カンバンボードとストーリーポイント:「何をするか」という観点から考えるだけで、 「誰がそれを行うのか」そして「それはどれほど複雑なのか」。
統合チャット: WhatsApp グループに別れを告げる
イベント運営において最も一般的な問題の 1 つは次のとおりです。 コミュニケーションの断片化: 重要なメッセージがグループ内で失われる 混沌とした WhatsApp、メールやチャット上の重複情報、下された意思決定 追跡されていないチャネルで。プラットフォームには通信システムが統合されています イベントのコンテキストに合わせて、各会話がイベントに関連付けられます。 正しいコンテキスト。
タスク、アプリ内通知、メッセージング システムに関するコメント 社内ですべてのコミュニケーションを整理し、 検索可能。各メッセージには明確なコンテキストがあり、メッセージは タスク、経費、参加者、またはイベント全体。 WebSocket インフラストラクチャは共同フロアプランニングにすでに使用されています リアルタイム メッセージングの技術的基盤を提供します。
重要なポイント
- 4 つの状態と検証された遷移を含むスプリント (DDD ステート マシン)
- サブタスクを含むタスク、4 つの状態、優先度 1 ~ 10、依存関係、および手動ロック
- ストーリー ポイント フィボナッチと協力的なプランニング ポーカー (メディア、配信、コンセンサス)
- 高度なサーバー側フィルターを備えたカンバン、ガント、リスト ビュー
- SockJS フォールバック、要素ロック、リアルタイム カーソルを備えた WebSocket STOMP
- 境界のあるコンテキスト間の非同期通信のための 5 つのドメイン イベント
- 17種類と光るアイコンによるマルチチャネル通知(アプリ内+メール)
- 40 以上のアクティビティ タイプと柔軟な JSON メタデータによるアクティビティ追跡
- リアルタイムで計算されたスプリント統計を備えた完全な REST API
プロジェクトのソースコードは次の場所から入手できます。 GitHub。 完全なアジャイル管理とリアルタイム コラボレーション システムを試すには、次のサイトにアクセスしてください。 www.playtheevent.com.







