Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CristianRR94/springCommunity/llms.txt

Use this file to discover all available pages before exploring further.

Spring Community follows a Domain-Driven Design approach, organizing its persistence layer around five main JPA-managed entities: Usuario, Participante, Evento, Mensaje, and Token. Each entity maps to a PostgreSQL table, and relationships between them are expressed through standard JPA annotations — @OneToOne, @ManyToMany, and @ManyToOne. Controllers never expose raw entities to the outside world; instead, every HTTP response is shaped through a dedicated DTO layer mapped by MapStruct, keeping the domain model clean and the API surface intentional.

Entity Overview

Usuario

The authentication identity of a community member, stored in the usuarios table. It implements Spring Security’s UserDetails interface, so Spring Security can load and verify credentials directly from the database. Passwords must be at least 8 characters long and contain at least one digit.
FieldTypeConstraints
idLongPrimary key, auto-generated
nombreString6–20 chars, unique, not blank
passwordStringMin 8 chars, must contain a digit
emailStringValid email format, unique, not blank
rolStringDefault: "USUARIO"

Participante

The social profile that is created alongside every Usuario account, stored in the participantes table. While Usuario owns credentials, Participante owns everything social: joined events, administered events, friends, and a profile picture.
FieldTypeConstraints
idLongPrimary key, auto-generated
nombreParticipanteString6–20 chars, not blank
imagenParticipanteStringFilename; defaults to default.png
eventosSetM:M — events joined
eventosAdministradosSetM:M — events administered
amigosSetM:M self-referential — friends

Evento

The central community resource, stored in the eventos table. An event has a name, optional type and date, privacy flags, a participant cap, and separate sets for regular participants and administrators. The event creator is always inserted into both sets automatically via addCreadorComoAdmin().
FieldTypeConstraints
idLongPrimary key, auto-generated
nombreEventoStringRequired, max 255 chars
tipoEventoStringOptional, max 255 chars
fechaEventoLocalDateMust not be in the past
informacionStringFree-text description
imagenEventoStringFilename, set server-side
privadobooleanPrivacy flag
ocultobooleanVisibility flag
maxNumParticipantesint0–255
participantesEventoSetM:M via evento_participantes
administradoresSetM:M via evento_administradores

Mensaje

A single chat message posted in an event’s real-time chat room, stored in the mensajes table. Every message belongs to exactly one event and is authored by exactly one participant. Messages are persisted to PostgreSQL and retrievable via a REST endpoint after the fact.
FieldTypeConstraints
idLongPrimary key, auto-generated
textoStringRequired, max 1000 chars
eventoEventoM:1 — owning event
emisorParticipanteM:1 — message author

Token

A JWT token record used for revocation tracking, stored in the tokens table. Every issued access or refresh token is written to this table so the server can check whether a given token has been revoked or has expired independently of the JWT signature expiry time.
FieldTypeConstraints
idLongPrimary key, auto-generated
tokenStringJWT string, unique, max 1000 chars
tokenTypeEnumAlways BEARER
tipoUsoTipoTokenACCESS or REFRESH
revokedbooleanWhether the token has been explicitly revoked
expiredbooleanWhether the token is marked as expired
usuarioUsuarioM:1 — the owning user account

Relationship Diagram

The following list describes every association in the data model and the join tables that back the many-to-many relationships:
  • UsuarioParticipante — One-to-one. Each user account has exactly one social profile. The participantes table holds the foreign key (usuario_id).
  • ParticipanteEvento (participant role) — Many-to-many. Join table: evento_participantes (evento_id, participante_id).
  • ParticipanteEvento (admin role) — Many-to-many. Join table: evento_administradores (evento_id, participante_id).
  • ParticipanteParticipante (friends) — Many-to-many self-referential. Join table: participante_amigos (participante_id, amigo_id).
  • MensajeParticipante — Many-to-one. Each message has one author (emisor); the mensajes table holds participante_id.
  • MensajeEvento — Many-to-one. Each message belongs to one event; the mensajes table holds evento_id.
  • TokenUsuario — Many-to-one. A user can have many tokens (one per login session); the tokens table holds usuario_id.
Usuario ──────── Participante
  1:1                │       │
                  M:M │     M:M
               Evento   Participante
              (participant  (friends)
               & admin)

                M:1
               Mensaje

Usuario ─── Token (M:1)

Timestamps

Every entity except Token extends the abstract TimestampEntity class, which adds two audit columns to each table:
ColumnTypeDescription
created_atLocalDateTimeSet once on @PrePersist; never updated again
updated_atLocalDateTimeUpdated on every @PreUpdate
TimestampEntity is annotated with @MappedSuperclass and @EntityListeners(AuditingEntityListener.class), so Spring Data’s JPA auditing infrastructure populates both fields automatically.
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class TimestampEntity {

    @CreatedDate
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
}

API DTOs

Controllers never serialize entity objects directly. All responses pass through a dedicated DTO layer to avoid exposing internal associations, circular references, and sensitive fields. The following DTOs are in active use:

EventoDTO

Full event detail, used as both the request body when creating or updating an event and as the response body for single-event lookups. The participantesEvento and administradores fields are read-only in responses — they are populated by the service layer and ignored on write. The chat field is an optional free-text channel identifier stored alongside the event.
{
  "id": 1,
  "nombreEvento": "Spring Meetup 2025",
  "tipoEvento": "Meetup",
  "fechaEvento": "2025-09-15",
  "informacion": "Annual Spring Boot community gathering.",
  "chat": null,
  "imagenEvento": "meetup.png",
  "privado": false,
  "oculto": false,
  "maxNumParticipantes": 100,
  "participantesEvento": [1, 2, 3],
  "administradores": [1]
}

EventoPrincipalDTO

A lightweight summary used in listing endpoints (e.g., the dashboard feed). It omits participant lists, descriptions, and privacy flags to keep responses small.
{
  "id": 1,
  "nombreEvento": "Spring Meetup 2025",
  "tipoEvento": "Meetup",
  "fechaEvento": "2025-09-15",
  "imagenEvento": "meetup.png"
}

ParticipanteDTO

The standard participant projection. Event memberships are expressed as lists of IDs rather than nested objects to keep responses flat and avoid N+1 serialisation overhead.
{
  "id": 7,
  "nombreParticipante": "alice99",
  "eventosId": [1, 4],
  "eventosAdministradosId": [1],
  "usuarioId": 3,
  "imagenParticipante": "alice.png"
}

ParticipanteAmigoDTO

A trimmed friend profile returned when browsing a specific friend. Includes the friend’s own friend list (as IDs) so a client can implement mutual-friend detection without additional requests.
{
  "id": 12,
  "nombreParticipante": "bob_dev",
  "amigosId": [7, 15, 22],
  "usuarioId": 9
}

HistorialMensajesDTO

The persisted chat message projection. Returned both from the REST history endpoint and broadcast over WebSocket after each new message is saved.
{
  "id": 88,
  "texto": "See you all at the meetup!",
  "participanteId": 7,
  "nombreParticipante": "alice99",
  "fechaEnvio": "2025-08-20T18:45:00"
}

Build docs developers (and LLMs) love