Skip to content

NoteService

Implements INoteService for group notepad entries, coordinating retrieval, filtering, adding, appending, editing, and deleting notes attached to groups (GroupNote/Notepad). It depends on IUnitOfWork for repository access and transactions, IValidationService for FluentValidation-based edit validation (via NoteEditValidator), IUserProfileService for current-user identity and role checks, and IWorkCalendarService to compute the "two work days ago" cutoff that gates edit/delete/append permissions. Its static constructor registers AutoMapper maps for GroupNote/Notepad→Note and reuses GroupsMappingHelper.CreateGroupMap().

Purpose

  • Retrieves a single note or all notes for a group (including notes on its parent group), filtering out confidential notes unless the current user is authorized to see them.
  • Filters an in-memory note collection by category, type, creator/updater, and date range (NoteFilterCriteria).
  • Adds a new note, enforcing edit authorization and validation, and stamping create/update audit fields.
  • Appends text to an existing note (only allowed once the note is older than two work days) or edits a note's text directly (only allowed within two work days of creation), enforcing optimistic-concurrency checks against UpdateDate.
  • Deletes a note, allowing unrestricted deletion for super-delete users and time-limited deletion (within two work days) for regular edit users.
  • Reports whether the current user can add notes or see confidential notes, and returns the available note categories.

Context

  • Namespace: SAIF.Services.Groups.Notes
  • Assembly/package: SAIF.Services (packaged inside the SAIF.SAIFCode.Core NuGet package)

Public members

Member Signature Purpose
NoteService(...) public NoteService(IUnitOfWork unitOfWork, IValidationService validationService, IUserProfileService userProfileService, IWorkCalendarService workCalendarService) Validates all four collaborators are non-null and stores them for use by every other member.
GetNote public Note GetNote(long noteId) Returns the mapped Note for noteId, or null if not found or the caller lacks confidential-note visibility.
GetNotes(groupAcronym, criteria) public IEnumerable<Note> GetNotes(string groupAcronym, NoteFilterCriteria criteria) Returns the group's notes (own and parent-group notes) narrowed by criteria.
GetNotes(groupAcronym) public IEnumerable<Note> GetNotes(string groupAcronym) Returns all visible notes for the group and its parent group, mapped to Note contracts.
Filter public IEnumerable<Note> Filter(IEnumerable<Note> notes, NoteFilterCriteria criteria) Narrows an in-memory note collection by category code, type code, create/update user substring, and creation-date range, skipping any criterion set to its "all" sentinel value.
AddNote public long? AddNote(NoteEdit noteEdit, IMessageContainer messages) Adds a new note for the current user if authorized and valid, committing within a transaction; returns the new note ID, or null (with messages populated) on authorization/validation failure.
AppendNote public bool AppendNote(long noteId, NoteEdit noteEdit, IMessageContainer messages) Appends new text (with an "Added by " prefix) to an existing note if the caller is authorized, the note is older than two work days, there is no intervening update, and the appended text validates; returns whether the append succeeded.
AppendPrefixTextLength public int AppendPrefixTextLength { get; } Returns the character length of the "Added by " prefix that will be inserted when appending.
DeleteNote public bool DeleteNote(long noteId, IMessageContainer messages) Deletes the note if found, and if the caller is a super-delete user or the note was created within the last two work days; returns whether the delete succeeded.
EditNote public bool EditNote(long noteId, NoteEdit noteEdit, IMessageContainer messages) Edits an existing note's group, confidentiality, type, and text (with an "Updated by " suffix) if the caller is authorized, there is no intervening update, the edit window (two work days since creation) has not passed when text changed, and validation succeeds; returns whether the edit succeeded.
EditSuffixTextLength public int EditSuffixTextLength { get; } Returns the character length of the "Updated by " suffix appended when a note's text is edited.
GetCategories public IEnumerable<Category> GetCategories() Returns the note categories scoped to the group-note context (NotepadContext.GroupNoteContextCode).
DeleteExpiredNotes public bool DeleteExpiredNotes() Always throws NotImplementedException; this capability is not implemented for group notes.
CanUserSeeConfidentialNotes public bool CanUserSeeConfidentialNotes { get; } Returns whether the current user holds the confidential-notes role.
GetAppendPrefixTextLength public int GetAppendPrefixTextLength() Always throws NotImplementedException; superseded by the AppendPrefixTextLength property.
CanUserAddNote public bool CanUserAddNote { get; } Returns whether the current user is authorized to add notes (same check used to gate AddNote/AppendNote/EditNote).

Behavioral notes

  • AddNote, AppendNote, EditNote, and DeleteNote each wrap their write in unitOfWork.Begin()/Commit(); none of them explicitly call Rollback() on failure paths, relying instead on returning early before Commit() is reached*.
  • Edit authorization (IsEditUser) is cached per-instance in the isUserAuthorizedToEditNotes nullable field after the first check, so subsequent calls on the same service instance reuse the cached result rather than re-querying the user profile*.
  • The optimistic-concurrency check compares noteEdit.UpdateDate to the stored Note.UpdateDate and rejects the write with "Error: Another user updated this note." on mismatch.
  • DeleteExpiredNotes and GetAppendPrefixTextLength are unimplemented (throw new NotImplementedException()), so callers must not invoke them in current builds.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • Services/SAIF.Services/Groups/Notes/NoteService.cs