중앙 모듈: 이벤트 및 참가자 관리
뛰는 심장 이벤트를 플레이하세요 이벤트 및 참가자 관리 모듈입니다. 플랫폼의 모든 기능 이벤트 생성부터 비용 분배까지 핵심을 중심으로 진행됩니다. 여행 계획부터 데이터 분석까지 모든 것은 행사와 행사에 참여하는 사람들로부터 시작됩니다 참가자.
이 기사에서는 도메인이 수명주기를 어떻게 형성하는지 자세히 살펴보겠습니다. 이벤트를 통해 상태 머신, 참가자들이 오면서 으로 관리하다 차별화된 역할 그리고 완벽한 회신 시스템, REST API가 이 모든 기능을 일관되고 안전하게 공개하는 방법을 알아보세요.
이 기사에서 찾을 수 있는 내용
- 상태 머신을 사용한 이벤트 수명 주기: DRAFT에서 COMPLETED까지
- 참가자의 역할: ORGANIZER, CO_ORGANIZER, ATTENDEE 및 VIP
- WAITING, ACCEPTED, DECLINED, MAYBE, CANCELED 및 EXPIRED 상태의 RSVP 시스템
- 공개 토큰과 QR 코드를 사용한 체크인 및 체크아웃 메커니즘
- 이벤트 가시성 및 링크를 통한 공유
- 수용인원 관리 및 참가자 실시간 집계
- 이벤트 및 참석자를 위한 기본 REST API
도메인 기반 디자인의 이벤트 집계
엔터티 이벤트 그것은집계 루트 메인 시스템의. DDD 원칙에 따라 이벤트 상태에 대한 모든 변경 사항과 참가자 중 이 루트를 통과하여 일관성을 보장합니다. 비즈니스 규칙.
집계는 제목, 설명, 시작 날짜 및 목적, 지리적 좌표가 포함된 위치, 통화가 포함된 예산, 지출 내역 유형, 최대 수용 인원과 총 참가자 수. 각 필드가 검증되었습니다. 도메인에 정의된 명시적인 비즈니스 규칙을 통해.
AGGREGATE ROOT: Evento
┌────────────────────────────────────────┐
│ Campi Principali │
│ - id (Long, auto-generated) │
│ - titolo (max 200 caratteri) │
│ - descrizione (TEXT, max 2000) │
│ - stato (StatoEvento enum) │
│ - organizzatoreId (FK utente) │
│ - dataInizio / dataFine (Instant) │
│ - budget (Money Value Object) │
│ - luogo + coordinate GPS │
│ - maxPartecipanti (opzionale) │
├────────────────────────────────────────┤
│ Token di Condivisione │
│ - tokenCondivisione (8 chars) │
│ - tokenCheckin (8 chars) │
│ - tokenCheckout (8 chars) │
├────────────────────────────────────────┤
│ Relazioni │
│ - partecipanti: Set<Partecipante> │
│ (1:N, lazy loading) │
└────────────────────────────────────────┘
패턴 팩토리 메소드 생성에 사용됩니다: 생성자
비공개이며 정적 메서드입니다. Evento.crea() 검증을 다룬다
그리고 초기화. 사건은 항상 상태에서 발생한다 초안,
일관된 출발점을 보장합니다.
이벤트 수명주기: 상태 머신
의 모든 이벤트 이벤트를 플레이하세요 유한 상태 기계로 모델링된 잘 정의된 수명 주기를 거칩니다. 각 전환은 단계를 방지하는 비즈니스 규칙으로 보호됩니다. 유효하지 않습니다.
┌───────────┐
│ DRAFT │ (Evento creato, in bozza)
└─────┬─────┘
│
pubblica()
│
▼
┌─────────────┐
│ PUBLISHED │ (Visibile, inviti aperti)
└──────┬──────┘
│
conferma()
│
▼
┌─────────────┐
│ CONFIRMED │ (Evento confermato)
└──────┬──────┘
│
avvia()
│
▼
┌───────────────┐
│ IN_PROGRESS │ (Evento in corso)
└───────┬───────┘
│
iniziaDivisioneSpese()
│
▼
┌───────────────────┐
│ EXPENSE_SPLITTING │ (Divisione spese attiva)
└─────────┬─────────┘
│
completa()
│
▼
┌─────────────┐
│ COMPLETED │ (Evento concluso)
└─────────────┘
NOTA: Da qualsiasi stato (tranne COMPLETED e CANCELLED)
si può passare a CANCELLED tramite annulla(motivo)
상태의 세부 사항
각 상태는 정확한 의미를 가지며 허용되는 작업을 결정합니다.
- 초안: 이벤트가 생성되었지만 아직 참가자에게 표시되지 않습니다. 날짜는 선택사항이며, 제목과 설명은 자유롭게 변경할 수 있습니다. 모든 이벤트의 초기 상태입니다.
- 출판: 이벤트가 게시되어 표시됩니다. 게시하려면 제목과 시작일이 필요합니다. 초대장을 보낼 수 있고 참가자가 응답할 수 있습니다.
- 확인됨: 해당 이벤트가 확정되어 진행됩니다. 주최자가 이벤트 개최를 확인하면 PUBLISHED에서 전환이 발생합니다.
- 진행 중: 이벤트가 진행 중입니다. 체크인이 가능하며 활동이 실시간으로 진행됩니다.
- 비용 분할: 이벤트가 종료되고 비용은 참가자들에게 나누어집니다. 이 단계는 필수적인 완료 전.
- 완전한: 모든 것이 마무리되었습니다. 비용을 나누고 잔액을 계산했습니다. 이벤트가 보관되었습니다.
- 취소: 이벤트가 취소되었습니다. 취소하려면 이유가 필요하며 모든 참가자에게 알림이 생성됩니다.
전환 규칙
상태 전환은 열거형의 메서드로 보호됩니다. StatoEvento 그
언제든지 허용되는 사항을 결정합니다.
canAcceptParticipants()
DRAFT, PUBLISHED, INVITATIONS_SENT, CONFIRMED → true
isModifiable()
DRAFT, PUBLISHED, INVITATIONS_SENT → true
isActive()
Tutti tranne CANCELLED e COMPLETED → true
canSplitExpenses()
IN_PROGRESS, EXPENSE_SPLITTING → true
canComplete()
Solo EXPENSE_SPLITTING → true
이 접근 방식을 사용하면 불법적인 수정 시도를 차단할 수 있습니다.
도메인 수준에서 예외 발생 IllegalStateException 와
데이터베이스에 도달하기 전에 설명 메시지를 보냅니다.
참가자의 역할
이벤트에 참여한 각 참가자는 이벤트를 플레이하세요 내에서 권한과 기능을 결정하는 특정 역할이 있습니다. 이벤트의. 시스템은 네 가지 역할을 정의합니다.
ORGANIZER ("Organizzatore")
└─ Ha creato l'evento
└─ Permessi completi di modifica
└─ Può aggiungere co-organizzatori
└─ Può promuovere/retrocedere partecipanti
└─ Non può essere rimosso dall'evento
└─ Plus-one consentito automaticamente
CO_ORGANIZER ("Co-Organizzatore")
└─ Può modificare l'evento
└─ Può invitare nuovi partecipanti
└─ NON può eliminare l'evento
└─ Plus-one consentito automaticamente
└─ Può essere retrocesso solo dal creatore
ATTENDEE ("Partecipante")
└─ Partecipante standard
└─ Accesso in sola lettura all'evento
└─ Può rispondere all'invito (RSVP)
└─ Può aggiungere restrizioni alimentari
└─ Può invitare altri partecipanti
VIP ("VIP")
└─ Partecipante con status speciale
└─ Stessi permessi di ATTENDEE
└─ Visibilità prioritaria nelle liste
승격 및 강등
집계 Evento 프로모션 관리를 위한 전용 방법을 공개합니다.
방법 promuoviACoorganizzatore() 참가자가 그렇지 않은지 확인합니다.
프로모션을 실행하기 전에 이미 주최자 또는 공동 주최자였습니다.
다음을 통해 강등됨 retroceidiCoorganizzatore() 공동주최자 보고
ATTENDEE 역할로 변경됩니다.
중요한 비즈니스 규칙: 참가자가 역할로 승격되는 경우 조직에서는 시스템이 자동으로 다음을 활성화합니다. 플러스원, allowing the organizer to bring a companion to the event.
RSVP 시스템
RSVP(Répondez s'il vous plaît) 시스템은 전체 흐름을 관리합니다. 초대에 대한 응답. 각 참석자에게는 시간이 지남에 따라 변화하는 회신 상태가 있습니다. 그의 행동을 바탕으로.
┌───────────────┐ accettaInvito() ┌─────────────┐
│ IN_ATTESA │ ───────────────────▶ │ ACCETTATO │
└───────┬───────┘ └─────────────┘
│
├── rifiutaInvito() ──▶ RIFIUTATO
│
├── rispondiForse() ──▶ FORSE
│
└── (scadenza) ─────▶ SCADUTO
Da ACCETTATO:
annullaPartecipazione() ──▶ ANNULLATO
NOTA: Gli organizzatori vengono impostati
automaticamente come ACCETTATO alla creazione.
초대 작동 방식
참가자가 이벤트에 추가되면 시스템은 다음을 수행합니다.
- 엔터티 만들기
Partecipante상태와 함께 보류 중 (주최자는 자동으로 수락됩니다) - 초대한 사람을 기록합니다(
invitatoDaUtenteId) 추적성을 위해 - 하나를 계산해 보세요 만료 날짜: 지정하지 않을 경우 기본값은 이벤트 전날 오후 11시 59분 59초입니다.
- 하나 보내기 인앱 알림 초대자 이름의 수신자에게
- 사용자의 이메일이 확인되면 이메일도 보냅니다. 이메일 알림
초대받은 사람은 다음 세 가지 옵션으로 응답할 수 있습니다. 나는 동의한다, 배제 o 아마도. 각 응답은 타임스탬프를 기록합니다. 그리고 선택적 메모입니다. 초대가 응답 없이 만료되면 예약된 작업에서 이를 표시합니다. 어떻게 만료됨.
지능형 계산
시스템은 참가자를 구별합니다. 확실한 e 잠재적인:
contaPartecipantiConfermati()승인된 사람만 계산됩니다.contaPartecipantiPotenziali()MAYBE라고 답한 사람도 포함됩니다.- 용량 제한(
maxPartecipanti)는 확인된 내용을 기반으로 합니다.
체크인 및 체크아웃: 실시간 출입 통제
체크인 및 체크아웃 시스템을 통해 정시에 이벤트에 대한 액세스를 관리할 수 있습니다.
실제로 분석을 위한 귀중한 데이터를 수집합니다. 둘 다 일을 통해
공개 토큰 8자리 영숫자 문자로 생성됨
SecureRandom 인증 없이 접근 가능합니다.
게스트 체크인
체크인은 참석자가 도착할 때 인구 통계 및 설문조사 데이터를 수집합니다.
주최자는 공개 링크를 생성하여 체크인을 활성화할 수 있습니다.
(예: /c/Ab3kL9xZ) QR 코드를 통해 공유 가능.
CheckinInvitato
├─ nome, cognome, età
├─ città e stato di provenienza
├─ orarioArrivo (Instant.now() automatico)
├─ frequenzaPartecipazione
│ (PRIMA_VOLTA, OCCASIONALE, REGOLARE, ABITUALE)
├─ fonteEvento
│ (SOCIAL_MEDIA, AMICI, SITO_WEB, EMAIL, PASSAPAROLA...)
├─ accompagnatori
│ (DA_SOLO, COPPIA, PICCOLO_GRUPPO, GRANDE_GRUPPO)
├─ iscrizioneNewsletter (boolean)
└─ email (opzionale, richiesta se newsletter)
이 데이터는 분석 모듈에 제공되며 다음과 같은 통계를 계산할 수 있습니다. 연령별 분포, 가장 효과적인 획득 소스, 그룹의 예상 인원수와 처음 참가자의 비율.
결제(이벤트 후 피드백)
체크아웃은 체크인을 보완하는 것입니다. 참가자로부터 피드백을 수집합니다.
이벤트 후. 별도의 링크를 통해 액세스 가능(예: /o/Xy7mN2pQ),
다음이 포함됩니다:
- 총평: 별 1~5개, 긍정적(4~5), 중립(3) 또는 부정적(1~2)으로 분류됨
- 긍정적인 측면과 개선이 필요한 부분: 사전 정의된 옵션(조직, 음식, 위치, 엔터테인먼트...) 간의 다중 선택
- 제안: 자유 텍스트 필드 최대 2000자
- 반품 의도: 예, 그럴 수도 있습니다. 아니오
- 순 추천 지수(NPS): 1에서 10까지의 점수, 추천자(9-10), 수동적(7-8) 또는 비추천자(1-6)로 분류됨
NPS 점수 계산은 표준 공식을 따릅니다. NPS = 추천 고객 % - 비추천 고객 %, 에 대한 주요 지표 제공 참가자들의 전반적인 만족도.
이벤트의 가시성 및 공유
플랫폼은 각각 자체 토큰이 있는 세 가지 공유 메커니즘을 지원합니다. 안전하게 생성된 8자:
1. LINK DI CONDIVISIONE (/e/{token})
└─ Permette di visualizzare i dettagli dell'evento
└─ Attivabile/disattivabile dall'organizzatore
└─ Token rigenerabile (invalida il link precedente)
└─ Flag: condivisioneAttiva (boolean)
2. LINK DI CHECK-IN (/c/{token})
└─ Form pubblico per check-in senza autenticazione
└─ Raccoglie dati demografici e sondaggio
└─ Ideale per QR code stampati all'ingresso
└─ Flag: checkinAttivo (boolean)
3. LINK DI CHECKOUT (/o/{token})
└─ Form pubblico per feedback post-evento
└─ Raccoglie valutazione, NPS, suggerimenti
└─ Condivisibile via email o QR code
└─ Flag: checkoutAttivo (boolean)
또한, 이벤트는 다음 페이지에서 볼 수 있습니다. 공개 지도
깃발을 통한 플랫폼의 visibileInMappa. 이 기능
지리적 좌표를 설정해야 하며 이벤트에 유용합니다.
해당 지역의 참가자를 끌어들이고 싶은 청중.
실시간 기능 및 관리
용량 관리는 전체적으로 직접 구현됩니다.
Evento. 분야 maxPartecipanti 선택 사항입니다. 그렇지 않은 경우
설정하면 이벤트에 무제한의 참가자가 허용됩니다.
// Verifica posti disponibili
public boolean haPostiDisponibili() {
if (this.maxPartecipanti == null) {
return true; // Nessun limite
}
return contaPartecipantiConfermati() < this.maxPartecipanti;
}
// Posti rimanenti
public Integer getPostiRimanenti() {
if (this.maxPartecipanti == null) {
return null; // Nessun limite
}
return this.maxPartecipanti - contaPartecipantiConfermati();
}
// Controllo all'aggiunta di un partecipante
public void aggiungiPartecipante(Long utenteId, RuoloPartecipante ruolo) {
// ... validazioni ...
if (this.maxPartecipanti != null &&
contaPartecipantiConfermati() >= this.maxPartecipanti) {
throw new IllegalStateException(
"Raggiunto il numero massimo di partecipanti"
);
}
Partecipante partecipante = Partecipante.crea(this.id, utenteId, ruolo);
this.partecipanti.add(partecipante);
}
계산은 회신 참석자만을 기준으로 합니다. 수락됨, MAYBE(아마도) 응답했거나 아직 응답하지 않은 사람은 포함되지 않습니다. 이는 다음을 보장합니다. 용량 제한은 실제 확인 사항을 반영합니다.
집계는 또한 다음을 구현합니다.낙관적 잠금 들판을 통해
@Version, 여러 주최자가 편집할 때 충돌 방지
동시에 이벤트를 진행합니다.
추가 참가자 정보
역할 및 RSVP 상태 외에도 각 참가자는 다음을 지정할 수 있습니다. additional information useful for the organization:
- 음식 제한사항: 알레르기, 과민증 또는 선호도에 대한 최대 500자의 텍스트 필드
- 플러스원: 이름이 표시된 동반자를 데려올 가능성이 있습니다. 플러스원은 주최자와 공동 주최자에게 자동으로 허용됩니다.
- 응답 참고: 회신 응답에 첨부된 무료 메시지
- 등록 상태: 깃발
registrato및 타임스탬프registratoIl행사장 실제 체크인을 위해
등록된 참석자의 물리적 체크인(공개 게스트 체크인 제외) 외부)은 규칙에 의해 보호됩니다. 초대를 수락한 사람만 볼 수 있습니다. 체크인하면 두 번 할 수 없습니다.
REST API
플랫폼 이벤트를 플레이하세요 이벤트 및 참석자 관리를 위한 완전한 RESTful API를 공개하며 다음과 같이 문서화되어 있습니다. OpenAPI/Swagger 및 JWT Bearer 인증을 통해 보호됩니다.
이벤트 엔드포인트
POST /api/v1/events Crea evento (stato DRAFT)
GET /api/v1/events/{id} Dettaglio evento
GET /api/v1/events?organizzatoreId={id} Lista eventi per organizzatore
GET /api/v1/events/all Tutti gli eventi dell'utente
?status=DRAFT&sortBy=date&sortDirection=desc
PUT /api/v1/events/{id} Aggiorna dettagli evento
DELETE /api/v1/events/{id} Elimina evento
GET /api/v1/events/statistiche Statistiche aggregate utente
--- Transizioni di Stato ---
POST /api/v1/events/{id}/publish DRAFT → PUBLISHED
POST /api/v1/events/{id}/confirm PUBLISHED → CONFIRMED
POST /api/v1/events/{id}/start CONFIRMED → IN_PROGRESS
POST /api/v1/events/{id}/start-expense-splitting
IN_PROGRESS → EXPENSE_SPLITTING
POST /api/v1/events/{id}/complete EXPENSE_SPLITTING → COMPLETED
POST /api/v1/events/{id}/cancel?motivo=... * → CANCELLED
--- Condivisione ---
POST /api/v1/events/{id}/share Genera link condivisione
GET /api/v1/events/{id}/share Stato condivisione
DELETE /api/v1/events/{id}/share Disattiva condivisione
POST /api/v1/events/{id}/share/regenerate Rigenera token
--- Check-in ---
POST /api/v1/events/{id}/checkin/enable Abilita check-in
DELETE /api/v1/events/{id}/checkin/disable Disabilita check-in
POST /api/v1/events/{id}/checkin/regenerate Rigenera token
GET /api/v1/events/{id}/checkin/status Stato check-in
GET /api/v1/events/{id}/checkin/list Lista check-in (paginata)
GET /api/v1/events/{id}/checkin/stats Statistiche check-in
--- Checkout (Feedback) ---
POST /api/v1/events/{id}/checkout/enable Abilita checkout
DELETE /api/v1/events/{id}/checkout/disable Disabilita checkout
POST /api/v1/events/{id}/checkout/regenerate Rigenera token
GET /api/v1/events/{id}/checkout/status Stato checkout
GET /api/v1/events/{id}/checkout/list Lista feedback (paginata)
GET /api/v1/events/{id}/checkout/stats Statistiche feedback
엔드포인트 참가자
GET /api/v1/events/{eventId}/participants
Lista partecipanti (arricchita con dati utente)
GET /api/v1/events/{eventId}/participants/{participantId}
Dettaglio singolo partecipante
POST /api/v1/events/{eventId}/participants
Aggiungi partecipante (con notifica e tracciamento invitante)
DELETE /api/v1/events/{eventId}/participants/{participantId}
Rimuovi partecipante (solo organizzatori)
PATCH /api/v1/events/{eventId}/participants/{participantId}/role
?nuovoRuolo=CO_ORGANIZER
Cambia ruolo partecipante
공개 엔드포인트(인증 없음)
--- Check-in Pubblico ---
GET /api/v1/public/checkin/{token}/info
Info evento per form check-in
POST /api/v1/public/checkin/{token}
Invia check-in (dati demografici + sondaggio)
--- Checkout Pubblico ---
GET /api/v1/public/checkout/{token}/info
Info evento per form feedback
POST /api/v1/public/checkout/{token}
Invia feedback (valutazione + NPS + suggerimenti)
--- Evento Pubblico ---
GET /api/v1/public/events/{token}
Visualizza dettagli evento condiviso
알림 및 커뮤니케이션
이벤트에 대한 모든 중요한 작업은 이중 채널을 통해 알림을 생성합니다.
- 인앱 알림: 엔터티로 생성됨
NotificaUtente이벤트, 알림 유형 및 직접 링크를 참조하여 - 이메일 알림: 각 이벤트 유형에 대한 특정 템플릿을 사용하여 이메일이 확인된 사용자에게만 전송됩니다.
알림 유형은 다음과 같습니다. 초대_이벤트 (초대받은 경우), EVENT_MODIFIED (세부 사항이 변경되는 경우) 이벤트_취소됨 (취소 사유 포함) e NEW_CO_ORGANIZER (승진할 때) 모든 경우에, 작업 작성자는 수신자 목록에서 제외됩니다.
검증 및 비즈니스 규칙
이벤트 집계는 다음과 같은 다양한 도메인 수준 유효성 검사를 구현합니다. 비즈니스 규칙이 컨트롤러가 아닌 모델에 존재한다는 DDD 원칙:
- 제목: 필수, 최대 200자
- 날짜: 종료 날짜는 시작 날짜보다 이전일 수 없습니다. 초안 날짜는 선택 사항입니다.
- 좌표: 제공된 경우 둘 다 있어야 합니다. 위도 -90~90, 경도 -180~180
- 예산: 양수여야 하며 수정 가능한 상태에서만 수정 가능해야 합니다.
- 출판: 제목과 시작일이 필요합니다.
- 참가자들: 이벤트-사용자 쌍의 고유성, 두 번째 ORGANIZER 추가 불가능
- 용량: 한계에 도달하면 자동 제어
이 모듈의 주요 패턴
- 집계 루트: 모든 변경 사항에 대한 단일 진입점으로서의 이벤트
- 공장 방법:
Evento.crea()ePartecipante.crea()통제된 생성을 위해 - 상태 머신: 유효성 검사를 통한 명시적 상태 전환
- 낙관적 잠금: 필드
@Version경쟁관리를 위해 - 값 개체:
Money예산을 위해,StatoEventoeRuoloPartecipante풍부한 열거형으로 - 토큰 기반 액세스: 암호화된 보안 토큰을 사용한 공유 및 체크인
시리즈의 다음 기사에서는 비용분할제도, 4가지 분할 모드와 다중 통화 관리 기능을 통해 행사참가자에게 발생한 비용을 균등하게 나누어 지급합니다.







