From b72db599575b7f9ccf701c1a754bbbcd9a597a33 Mon Sep 17 00:00:00 2001 From: yv01p Date: Sun, 21 Dec 2025 00:28:16 +0000 Subject: [PATCH] feat(core): add IContentCrudService interface for Phase 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defines the contract for content CRUD operations: - Create: 6 overloads for creating documents - Read: GetById, GetByIds, GetRootContent, GetParent - Read (Tree Traversal): GetAncestors, GetPagedChildren, GetPagedDescendants - Save: Single and batch save operations - Delete: Permanent deletion with cascade 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../Services/IContentCrudService.cs | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 src/Umbraco.Core/Services/IContentCrudService.cs diff --git a/src/Umbraco.Core/Services/IContentCrudService.cs b/src/Umbraco.Core/Services/IContentCrudService.cs new file mode 100644 index 0000000000..86d993a2da --- /dev/null +++ b/src/Umbraco.Core/Services/IContentCrudService.cs @@ -0,0 +1,251 @@ +// src/Umbraco.Core/Services/IContentCrudService.cs +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Persistence.Querying; + +namespace Umbraco.Cms.Core.Services; + +/// +/// Service for content CRUD (Create, Read, Update, Delete) operations. +/// +/// +/// +/// Implementation Note: Do not implement this interface directly. +/// Instead, inherit from which provides required +/// infrastructure (scoping, repository access, auditing). Direct implementation +/// without this base class will result in missing functionality. +/// +/// +/// This interface is part of the ContentService refactoring initiative. +/// It extracts core CRUD operations into a focused, testable service. +/// +/// +/// Versioning Policy: This interface follows additive-only changes. +/// New methods may be added with default implementations. Existing methods will not +/// be removed or have signatures changed without a 2 major version deprecation period. +/// +/// +/// Version History: +/// +/// v1.0 (Phase 1): Initial interface with Create, Read, Save, Delete operations +/// +/// +/// +/// 1.0 +public interface IContentCrudService : IService +{ + #region Create + + /// + /// Creates a document without persisting it. + /// + /// Name of the document. + /// Id of the parent, or -1 for root. + /// Alias of the content type. + /// Optional id of the user creating the content. + /// The new document. + IContent Create(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId); + + /// + /// Creates a document without persisting it. + /// + /// Name of the document. + /// Guid key of the parent. + /// Alias of the content type. + /// Optional id of the user creating the content. + /// The new document. + IContent Create(string name, Guid parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId); + + /// + /// Creates a document without persisting it. + /// + /// Name of the document. + /// Id of the parent, or -1 for root. + /// The content type. + /// Optional id of the user creating the content. + /// The new document. + IContent Create(string name, int parentId, IContentType contentType, int userId = Constants.Security.SuperUserId); + + /// + /// Creates a document without persisting it. + /// + /// Name of the document. + /// The parent document. + /// Alias of the content type. + /// Optional id of the user creating the content. + /// The new document. + IContent Create(string name, IContent? parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId); + + /// + /// Creates and persists a document. + /// + /// Name of the document. + /// Id of the parent, or -1 for root. + /// Alias of the content type. + /// Optional id of the user creating the content. + /// The persisted document. + IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId); + + /// + /// Creates and persists a document. + /// + /// Name of the document. + /// The parent document. + /// Alias of the content type. + /// Optional id of the user creating the content. + /// The persisted document. + IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId); + + #endregion + + #region Read + + /// + /// Gets a document by id. + /// + /// The document id. + /// The document, or null if not found. + IContent? GetById(int id); + + /// + /// Gets a document by key. + /// + /// The document key. + /// The document, or null if not found. + IContent? GetById(Guid key); + + /// + /// Gets documents by ids. + /// + /// The document ids. + /// The documents. + IEnumerable GetByIds(IEnumerable ids); + + /// + /// Gets documents by keys. + /// + /// The document keys. + /// The documents. + IEnumerable GetByIds(IEnumerable ids); + + /// + /// Gets root-level documents. + /// + /// The root documents. + IEnumerable GetRootContent(); + + /// + /// Gets the parent of a document. + /// + /// Id of the document. + /// The parent document, or null if at root. + IContent? GetParent(int id); + + /// + /// Gets the parent of a document. + /// + /// The document. + /// The parent document, or null if at root. + IContent? GetParent(IContent? content); + + #endregion + + #region Read (Tree Traversal) + + /// + /// Gets ancestors of a document. + /// + /// Id of the document. + /// The ancestor documents, from root to parent (closest to root first). + IEnumerable GetAncestors(int id); + + /// + /// Gets ancestors of a document. + /// + /// The document. + /// The ancestor documents, from root to parent (closest to root first). + IEnumerable GetAncestors(IContent content); + + /// + /// Gets paged children of a document. + /// + /// Id of the parent document. + /// Zero-based page index. + /// Page size. + /// Total number of children. + /// Optional filter query. + /// Optional ordering. + /// The child documents. + IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren, IQuery? filter = null, Ordering? ordering = null); + + /// + /// Gets paged descendants of a document. + /// + /// Id of the ancestor document. + /// Zero-based page index. + /// Page size. + /// Total number of descendants. + /// Optional filter query. + /// Optional ordering. + /// The descendant documents. + IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, IQuery? filter = null, Ordering? ordering = null); + + /// + /// Checks whether a document has children. + /// + /// The document id. + /// True if the document has children; otherwise false. + bool HasChildren(int id); + + /// + /// Checks whether a document with the specified id exists. + /// + /// The document id. + /// True if the document exists; otherwise false. + bool Exists(int id); + + /// + /// Checks whether a document with the specified key exists. + /// + /// The document key. + /// True if the document exists; otherwise false. + bool Exists(Guid key); + + #endregion + + #region Save + + /// + /// Saves a document. + /// + /// The document to save. + /// Optional id of the user saving the content. + /// Optional content schedule. + /// The operation result. + OperationResult Save(IContent content, int? userId = null, ContentScheduleCollection? contentSchedule = null); + + /// + /// Saves multiple documents. + /// + /// The documents to save. + /// Optional id of the user saving the content. + /// The operation result. + /// + /// This method does not support content schedules. To save content with schedules, + /// use the single-item overload. + /// + OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId); + + #endregion + + #region Delete + + /// + /// Permanently deletes a document and all its descendants. + /// + /// The document to delete. + /// Optional id of the user deleting the content. + /// The operation result. + OperationResult Delete(IContent content, int userId = Constants.Security.SuperUserId); + + #endregion +}