Skip to main content

Event Type Reference

This page documents all domain event types in Sciety. Each event represents an immutable record of something that happened in the system.
Event types are defined in src/domain-events/ and validated using io-ts codecs.

Common Fields

All events share these common fields:
FieldTypeDescription
idUUIDUnique event identifier
typestringEvent type identifier
dateDateTimestamp when the event occurred

User Events

Events related to user actions and account management.
Fired when a new user creates an account.
{
  id: string;
  type: 'UserCreatedAccount';
  date: Date;
  userId: string;
  handle: string;
  avatarUrl: string;
  displayName: string;
}
Source: src/domain-events/user-created-account-event.ts
Fired when a user updates their profile information.
{
  id: string;
  type: 'UserDetailsUpdated';
  date: Date;
  userId: string;
  // Updated fields (all optional)
  handle?: string;
  avatarUrl?: string;
  displayName?: string;
}
Source: src/domain-events/user-details-updated-event.ts
Fired when a user saves an article for later reading.
{
  id: string;
  type: 'UserSavedArticle';
  date: Date;
  userId: string;
  articleId: string; // DOI
}
Source: src/domain-events/user-saved-article-event.ts
Fired when a user removes an article from their saved list.
{
  id: string;
  type: 'UserUnsavedArticle';
  date: Date;
  userId: string;
  articleId: string;
}
Source: src/domain-events/user-unsaved-article-event.ts
Fired when a user follows an editorial community (group).
{
  id: string;
  type: 'UserFollowedEditorialCommunity';
  date: Date;
  userId: string;
  editorialCommunityId: string; // Group ID
}
Source: src/domain-events/user-followed-editorial-community-event.ts
Fired when a user unfollows an editorial community.
{
  id: string;
  type: 'UserUnfollowedEditorialCommunity';
  date: Date;
  userId: string;
  editorialCommunityId: string;
}
Source: src/domain-events/user-unfollowed-editorial-community-event.ts
Fired when a user marks a review as helpful.
{
  id: string;
  type: 'UserFoundReviewHelpful';
  date: Date;
  userId: string;
  evaluationLocator: {
    id: string;
    type: string;
  };
}
Source: src/domain-events/user-found-review-helpful-event.ts
Fired when a user marks a review as not helpful.
{
  id: string;
  type: 'UserFoundReviewNotHelpful';
  date: Date;
  userId: string;
  evaluationLocator: {
    id: string;
    type: string;
  };
}
Source: src/domain-events/user-found-review-not-helpful-event.ts
Fired when a user removes their “helpful” rating from a review.
{
  id: string;
  type: 'UserRevokedFindingReviewHelpful';
  date: Date;
  userId: string;
  evaluationLocator: {
    id: string;
    type: string;
  };
}
Source: src/domain-events/user-revoked-finding-review-helpful-event.ts
Fired when a user removes their “not helpful” rating from a review.
{
  id: string;
  type: 'UserRevokedFindingReviewNotHelpful';
  date: Date;
  userId: string;
  evaluationLocator: {
    id: string;
    type: string;
  };
}
Source: src/domain-events/user-revoked-finding-review-not-helpful-event.ts
Fired when a user is granted admin rights for a group.
{
  id: string;
  type: 'UserAssignedAsAdminOfGroup';
  date: Date;
  userId: string;
  groupId: string;
}
Source: src/domain-events/user-assigned-as-admin-of-group-event.ts

Evaluation Events

Events related to article evaluations, reviews, and curation statements.
Fired when a group publishes an evaluation of an article.
{
  id: string;
  type: 'EvaluationPublicationRecorded';
  date: Date;
  groupId: string;
  evaluationLocator: {
    id: string;
    type: string;
  };
  articleId: string; // DOI
  publishedAt: Date;
  authors: string[];
  evaluationType?: 'review' | 'curation-statement' | string;
}
Source: src/domain-events/evaluation-publication-recorded-event.ts
Fired when evaluation metadata is updated (e.g., type or authors changed).
{
  id: string;
  type: 'EvaluationUpdated';
  date: Date;
  evaluationLocator: {
    id: string;
    type: string;
  };
  evaluationType?: string;
  authors?: string[];
}
Source: src/domain-events/evaluation-updated-event.ts
Fired when an evaluation is removed or retracted.
{
  id: string;
  type: 'EvaluationRemovalRecorded';
  date: Date;
  evaluationLocator: {
    id: string;
    type: string;
  };
}
Source: src/domain-events/evaluation-removal-recorded-event.ts
Fired when an evaluation was recorded in error and needs to be erased from read models.
{
  id: string;
  type: 'IncorrectlyRecordedEvaluationErased';
  date: Date;
  evaluationLocator: {
    id: string;
    type: string;
  };
}
Source: src/domain-events/incorrectly-recorded-evaluation-erased-event.ts

Group Events

Events related to editorial communities and groups.
Fired when a new group joins Sciety.
{
  id: string;
  type: 'GroupJoined';
  date: Date;
  groupId: string;
  name: string;
  avatarPath: string;
  descriptionPath: string;
  shortDescription: string;
  homepage: string;
  slug: string;
  largeLogoPath?: string;
}
Source: src/domain-events/group-joined-event.ts
Fired when group profile information is updated.
{
  id: string;
  type: 'GroupDetailsUpdated';
  date: Date;
  groupId: string;
  // Any of these fields can be updated
  name?: string;
  avatarPath?: string;
  descriptionPath?: string;
  shortDescription?: string;
  homepage?: string;
  slug?: string;
  largeLogoPath?: string;
}
Source: src/domain-events/group-details-updated-event.ts
Fired when a group’s list of evaluated articles is configured or updated.
{
  id: string;
  type: 'EvaluatedArticlesListSpecified';
  date: Date;
  groupId: string;
  listId: string;
}
Source: src/domain-events/evaluated-articles-list-specified-event.ts

List Events

Events related to article lists (collections).
Fired when a new article list is created.
{
  id: string;
  type: 'ListCreated';
  date: Date;
  listId: string;
  name: string;
  description: string;
  ownerId: string; // User ID or Group ID
}
Source: src/domain-events/list-created-event.ts
Fired when a list is deleted.
{
  id: string;
  type: 'ListDeleted';
  date: Date;
  listId: string;
}
Source: src/domain-events/list-deleted-event.ts
Fired when a list is renamed.
{
  id: string;
  type: 'ListNameEdited';
  date: Date;
  listId: string;
  name: string;
}
Source: src/domain-events/list-name-edited-event.ts
Fired when a list’s description is updated.
{
  id: string;
  type: 'ListDescriptionEdited';
  date: Date;
  listId: string;
  description: string;
}
Source: src/domain-events/list-description-edited-event.ts
Fired when an article is added to a list.
{
  id: string;
  type: 'ArticleAddedToList';
  date: Date;
  articleId: string; // DOI
  listId: string;
}
Source: src/domain-events/article-added-to-list-event.ts
Fired when an article is removed from a list.
{
  id: string;
  type: 'ArticleRemovedFromList';
  date: Date;
  articleId: string;
  listId: string;
}
Source: src/domain-events/article-removed-from-list-event.ts
Fired when an annotation is added to an article in a list.
{
  id: string;
  type: 'ArticleInListAnnotated';
  date: Date;
  articleId: string;
  listId: string;
  annotation: string;
}
Source: src/domain-events/article-in-list-annotated-event.ts
Fired when a list is featured/promoted.
{
  id: string;
  type: 'ListPromotionCreated';
  date: Date;
  listId: string;
}
Source: src/domain-events/list-promotion-created-event.ts
Fired when a list is unfeatured.
{
  id: string;
  type: 'ListPromotionRemoved';
  date: Date;
  listId: string;
}
Source: src/domain-events/list-promotion-removed-event.ts

Paper Events

Events related to papers and their metadata.
Fired when paper metadata is captured (e.g., from Crossref).
{
  id: string;
  type: 'PaperSnapshotRecorded';
  date: Date;
  expressionDois: ReadonlySet<string>; // All DOI versions
}
Source: src/domain-events/paper-snapshot-recorded-event.ts
Fired when a subject area classification is added to a paper.
{
  id: string;
  type: 'SubjectAreaRecorded';
  date: Date;
  articleId: string;
  subjectArea: string;
}
Source: src/domain-events/subject-area-recorded-event.ts

System Events

System-level events.
Fired when a COAR notification is processed.
{
  id: string;
  type: 'CoarNotificationDelivered';
  date: Date;
  notificationId: string;
  payload: object; // COAR notification payload
}
Source: src/domain-events/coar-notification-delivered-event.ts

Type Utilities

Sciety provides utilities for working with domain events:

EventOfType

Narrow an event to a specific type:
import { EventOfType, isEventOfType } from 'src/domain-events';

const handleEvent = (event: DomainEvent) => {
  if (isEventOfType('UserSavedArticle')(event)) {
    // event is now typed as EventOfType<'UserSavedArticle'>
    console.log(event.userId, event.articleId);
  }
};

filterByName

Filter events by type:
import { filterByName } from 'src/domain-events';

const userEvents = events.filter(
  filterByName(['UserSavedArticle', 'UserUnsavedArticle'])
);

sort

Sort events by date:
import { sort } from 'src/domain-events';

const sortedEvents = sort(events); // Oldest first

Adding New Event Types

To add a new domain event:
1

Create event file

Create a new file in src/domain-events/:
// src/domain-events/my-new-event.ts
import * as t from 'io-ts';
import * as tt from 'io-ts-types';
import { EventIdFromString } from '../types/codecs/EventIdFromString';

export const myNewEventCodec = t.strict({
  id: EventIdFromString,
  type: t.literal('MyNewEvent'),
  date: tt.DateFromISOString,
  // Add event-specific fields
});
2

Register in domain-event.ts

Import and add to the union:
import { myNewEventCodec } from './my-new-event';

export const domainEventCodec = t.union([
  // ... existing events
  myNewEventCodec,
], 'type');
3

Add tests

Test event construction and validation.
4

Update documentation

Add the event to this page!
See the Contributing Guide for more details.

Next Steps

Domain Events Overview

Learn about event sourcing architecture

Contributing

Add new domain events to Sciety

API Reference

Query events via API

Build docs developers (and LLMs) love