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 theSAIF.SAIFCode.CoreNuGet 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 |
| AppendPrefixTextLength | public int AppendPrefixTextLength { get; } |
Returns the character length of the "Added |
| 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 |
| EditSuffixTextLength | public int EditSuffixTextLength { get; } |
Returns the character length of the "Updated |
| 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, andDeleteNoteeach wrap their write inunitOfWork.Begin()/Commit(); none of them explicitly callRollback()on failure paths, relying instead on returning early beforeCommit()is reached*.- Edit authorization (
IsEditUser) is cached per-instance in theisUserAuthorizedToEditNotesnullable 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.UpdateDateto the storedNote.UpdateDateand rejects the write with "Error: Another user updated this note." on mismatch. DeleteExpiredNotesandGetAppendPrefixTextLengthare 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