NoteService¶
Implements INoteService for agency notepad entries, coordinating retrieval, filtering, adding, appending, editing, and deleting notes attached to agencies (AgencyNote/Notepad), returning outcomes and errors through a caller-supplied IMessageContainer rather than throwing. It depends on IUnitOfWork for repository access and transactions, IValidationService for FluentValidation-based edit validation, 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 AgencyNote/Notepad→Note and reuses AgenciesMappingHelper.CreateAgencyMap().
Purpose¶
- Retrieves a single note or all notes for an agency, filtering out confidential notes unless the current user is authorized to see them.
- Adds a new note (as the current user or, via
AddNoteBySystem, attributed to"SYSTEM"), enforcing edit authorization (for the user-attributed path) and validation. - 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 and optional producer association.
- 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.Agencies.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. |
| CanUserAddNote | public bool CanUserAddNote { get; } |
Returns whether the current user is authorized to add notes (same check used to gate AddNote/AppendNote/EditNote). |
| CanUserSeeConfidentialNotes | public bool CanUserSeeConfidentialNotes { get; } |
Returns whether the current user holds the confidential-notes role. |
| GetNotes(agencyId, criteria) | public IEnumerable<Note> GetNotes(long agencyId, NoteFilterCriteria criteria) |
Returns the agency's notes narrowed by criteria via the shared Filter extension. |
| GetNotes(agencyId) | public IEnumerable<Note> GetNotes(long agencyId) |
Returns all visible notes for the agency, mapped to Note contracts, each flagged IsProducerNote when a producer is associated. |
| GetNote | public Note GetNote(long noteId) |
Returns the mapped Note for noteId, or null if not found or the caller lacks confidential-note visibility. |
| GetCategories | public IEnumerable<Category> GetCategories() |
Returns the note categories scoped to the agency-note context (NotepadContext.AgencyNoteContextCode). |
| AddNote | public long? AddNote(NoteEdit noteEdit, IMessageContainer messages) |
Adds a new note attributed to 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. |
| AddNoteBySystem | public long? AddNoteBySystem(NoteEdit noteEdit, IMessageContainer messages) |
Adds a new note attributed to "SYSTEM" without the edit-authorization check (validation still applies), committing within a transaction; returns the new note ID, or null (with messages populated) on validation failure. |
| DeleteExpiredNotes | public bool DeleteExpiredNotes() |
Always throws NotImplementedException; this capability is not implemented for agency notes. |
| DeleteNote | public bool DeleteNote(long noteId, IMessageContainer messages) |
Deletes the note without considering concurrency 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 agency/producer, confidentiality, type, and text (with an "Updated |
| 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 |
| EditSuffixTextLength | public int EditSuffixTextLength { get; } |
Returns the character length of the "Updated |
Behavioral notes¶
AddNote,AddNoteBySystem,AppendNote,EditNote, andDeleteNoteeach wrap their write inunitOfWork.Begin()/Commit(); none 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*. - The optimistic-concurrency check compares
noteEdit.UpdateDateto the storedNote.UpdateDateand rejects the write with "Error: Another user updated this note." on mismatch. EditNote/AppendNote/AddNoteall route note text through.ReplaceUnicodeCharactersWithAscii()before persisting, normalizing non-ASCII characters.DeleteExpiredNotesis unimplemented (throw new NotImplementedException()), so callers must not invoke it in current builds.- A sibling type,
MoreReadableNoteService, implements the same agency-note operations using thrownNoteServiceExceptions instead of anIMessageContainerresult pattern*.
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/Agencies/Notes/NoteService.cs