Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
341 changes: 341 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,341 @@
# Umbraco CMS - Multi-Project Repository

Enterprise-grade CMS built on .NET 10.0. This repository contains 21 production projects organized in a layered architecture with clear separation of concerns.

**Repository**: https://github.com/umbraco/Umbraco-CMS
**License**: MIT
**Main Branch**: `main`

---

## 1. Overview

### What This Repository Contains

**21 Production Projects** organized in 3 main categories:

1. **Core Architecture** (Domain & Infrastructure)
- `Umbraco.Core` - Interface contracts, domain models, notifications
- `Umbraco.Infrastructure` - Service implementations, data access, caching

2. **Web & APIs** (Presentation Layer)
- `Umbraco.Web.UI` - Main ASP.NET Core web application
- `Umbraco.Web.Common` - Shared web functionality, controllers, middleware
- `Umbraco.Cms.Api.Management` - Backoffice Management API (REST)
- `Umbraco.Cms.Api.Delivery` - Content Delivery API (headless)
- `Umbraco.Cms.Api.Common` - Shared API infrastructure

3. **Specialized Features** (Pluggable Modules)
- Persistence: EF Core (modern), NPoco (legacy) for SQL Server & SQLite
- Caching: `PublishedCache.HybridCache` (in-memory + distributed)
- Search: `Examine.Lucene` (full-text search)
- Imaging: `Imaging.ImageSharp` v1 & v2 (image processing)
- Other: Static assets, targets, development tools

**6 Test Projects**:
- `Umbraco.Tests.Common` - Shared test utilities
- `Umbraco.Tests.UnitTests` - Unit tests
- `Umbraco.Tests.Integration` - Integration tests
- `Umbraco.Tests.Benchmarks` - Performance benchmarks
- `Umbraco.Tests.AcceptanceTest` - E2E tests
- `Umbraco.Tests.AcceptanceTest.UmbracoProject` - Test instance

### Key Technologies

- **.NET 10.0** - Target framework for all projects
- **ASP.NET Core** - Web framework
- **Entity Framework Core** - Modern ORM
- **OpenIddict** - OAuth 2.0/OpenID Connect authentication
- **Swashbuckle** - OpenAPI/Swagger documentation
- **Lucene.NET** - Full-text search via Examine
- **ImageSharp** - Image processing

---

## 2. Repository Structure

```
Umbraco-CMS/
├── src/ # 21 production projects
│ ├── Umbraco.Core/ # Domain contracts (interfaces only)
│ │ └── CLAUDE.md # ⭐ Core architecture guide
│ ├── Umbraco.Infrastructure/ # Service implementations
│ ├── Umbraco.Web.Common/ # Web utilities
│ ├── Umbraco.Web.UI/ # Main web application
│ ├── Umbraco.Cms.Api.Management/ # Management API
│ ├── Umbraco.Cms.Api.Delivery/ # Delivery API (headless)
│ ├── Umbraco.Cms.Api.Common/ # Shared API infrastructure
│ │ └── CLAUDE.md # ⭐ API patterns guide
│ ├── Umbraco.PublishedCache.HybridCache/ # Content caching
│ ├── Umbraco.Examine.Lucene/ # Search indexing
│ ├── Umbraco.Cms.Persistence.EFCore/ # EF Core data access
│ ├── Umbraco.Cms.Persistence.EFCore.Sqlite/
│ ├── Umbraco.Cms.Persistence.EFCore.SqlServer/
│ ├── Umbraco.Cms.Persistence.Sqlite/ # Legacy SQLite
│ ├── Umbraco.Cms.Persistence.SqlServer/ # Legacy SQL Server
│ ├── Umbraco.Cms.Imaging.ImageSharp/ # Image processing v1
│ ├── Umbraco.Cms.Imaging.ImageSharp2/ # Image processing v2
│ ├── Umbraco.Cms.StaticAssets/ # Embedded assets
│ ├── Umbraco.Cms.DevelopmentMode.Backoffice/
│ ├── Umbraco.Cms.Targets/ # NuGet targets
│ └── Umbraco.Cms/ # Meta-package
├── tests/ # 6 test projects
│ ├── Umbraco.Tests.Common/
│ ├── Umbraco.Tests.UnitTests/
│ ├── Umbraco.Tests.Integration/
│ ├── Umbraco.Tests.Benchmarks/
│ ├── Umbraco.Tests.AcceptanceTest/
│ └── Umbraco.Tests.AcceptanceTest.UmbracoProject/
├── templates/ # Project templates
│ └── Umbraco.Templates/
├── tools/ # Build tools
│ └── Umbraco.JsonSchema/
├── umbraco.sln # Main solution file
├── Directory.Build.props # Shared build configuration
├── Directory.Packages.props # Centralized package versions
├── .editorconfig # Code style
└── .globalconfig # Roslyn analyzers
```

### Architecture Layers

**Dependency Flow** (unidirectional, always flows inward):

```
Web.UI → Web.Common → Infrastructure → Core
Api.Management → Api.Common → Infrastructure → Core
Api.Delivery → Api.Common → Infrastructure → Core
```

**Key Principle**: Core has NO dependencies (pure contracts). Infrastructure implements Core. Web/APIs depend on Infrastructure.

### Project Dependencies

**Core Layer**:
- `Umbraco.Core` → No dependencies (only Microsoft.Extensions.*)

**Infrastructure Layer**:
- `Umbraco.Infrastructure` → `Umbraco.Core`
- `Umbraco.PublishedCache.*` → `Umbraco.Infrastructure`
- `Umbraco.Examine.Lucene` → `Umbraco.Infrastructure`
- `Umbraco.Cms.Persistence.*` → `Umbraco.Infrastructure`

**Web Layer**:
- `Umbraco.Web.Common` → `Umbraco.Infrastructure` + caching + search
- `Umbraco.Web.UI` → `Umbraco.Web.Common` + all features

**API Layer**:
- `Umbraco.Cms.Api.Common` → `Umbraco.Web.Common`
- `Umbraco.Cms.Api.Management` → `Umbraco.Cms.Api.Common`
- `Umbraco.Cms.Api.Delivery` → `Umbraco.Cms.Api.Common`

---

## 3. Teamwork & Collaboration

### Branching Strategy

- **Main branch**: `main` (protected)
- **Branch naming**:
- See `.github/CONTRIBUTING.md` for full guidelines

### Pull Request Process

- **PR Template**: `.github/pull_request_template.md`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this exist in the repo somewhere?

- **Required CI Checks**:
- All tests pass
- Code formatting (dotnet format)
- No build warnings
- **Merge Strategy**: Squash and merge (via GitHub UI)
- **Reviews**: Required from code owners

### Commit Messages

Follow Conventional Commits format:
```
<type>(<scope>): <description>

Types: feat, fix, docs, style, refactor, test, chore
Scope: project name (core, web, api, etc.)

Examples:
feat(core): add IContentService.GetByIds method
fix(api): resolve null reference in schema handler
docs(web): update routing documentation
```

### Code Owners

Project ownership is distributed across teams. Check individual project directories for ownership.

---

## 4. Architecture Patterns

### Core Architectural Decisions

1. **Layered Architecture with Dependency Inversion**
- Core defines contracts (interfaces)
- Infrastructure implements contracts
- Web/APIs consume implementations via DI

2. **Interface-First Design**
- All services defined as interfaces in Core
- Enables testing, polymorphism, extensibility

3. **Notification Pattern** (not C# events)
- `*SavingNotification` (before, cancellable)
- `*SavedNotification` (after, for reactions)
- Registered via Composers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Registered via Composers
- Handlers registered by extention method `AddNotificationHandler`


4. **Composer Pattern** (DI registration)
- Automatic discovery via reflection
- Ordered execution with `[ComposeBefore]`, `[ComposeAfter]`, `[Weight]`

5. **Scoping Pattern** (Unit of Work)
- `ICoreScopeProvider.CreateCoreScope()`
- Must call `scope.Complete()` to commit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Must call `scope.Complete()` to commit
- Must call `scope.Complete()` to commit or set the parameter autocomplete to true when calling `ICoreScopeProvider.CreateCoreScope()`, this will complete the scope upon disposal

- Manages transactions and cache lifetime

6. **Attempt Pattern** (operation results)
- `Attempt<TResult, TStatus>` instead of exceptions
- Strongly-typed operation status enums

### Key Design Patterns Used

- **Repository Pattern** - Data access abstraction
- **Unit of Work** - Scoping for transactions
- **Builder Pattern** - `ProblemDetailsBuilder` for API errors
- **Strategy Pattern** - OpenAPI handlers (schema ID, operation ID)
- **Options Pattern** - All configuration via `IOptions<T>`
- **Factory Pattern** - Content type factories
- **Mediator Pattern** - Notification aggregator

---

## 5. Project-Specific Notes

### Centralized Package Management

**All NuGet package versions** are centralized in `Directory.Packages.props`. Individual projects do NOT specify versions.

```xml
<!-- Individual projects reference WITHOUT version -->
<PackageReference Include="Swashbuckle.AspNetCore" />

<!-- Versions defined in Directory.Packages.props -->
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
```

### Build Configuration

- `Directory.Build.props` - Shared properties (target framework, company, copyright)
- `.editorconfig` - Code style rules
- `.globalconfig` - Roslyn analyzer rules

### Persistence Layer - NPoco and EF Core

The repository contains BOTH (actively supported):
- **Current**: NPoco-based persistence (`Umbraco.Cms.Persistence.Sqlite`, `Umbraco.Cms.Persistence.SqlServer`) - widely used and fully supported
- **Future**: EF Core-based persistence (`Umbraco.Cms.Persistence.EFCore.*`) - migration in progress

**Note**: The codebase is actively migrating to EF Core, but NPoco remains the primary persistence layer and is not deprecated. Both are fully supported.

### Authentication: OpenIddict

All APIs use **OpenIddict** (OAuth 2.0/OpenID Connect):
- Reference tokens (not JWT) for better security
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More to say on this now - see #20820

- **Secure cookie-based token storage** (v17+) - tokens stored in HTTP-only cookies with `__Host-` prefix
- Tokens are redacted from client-side responses and passed via secure cookies only
- ASP.NET Core Data Protection for token encryption
- Configured in `Umbraco.Cms.Api.Common`
- API requests must include credentials (`credentials: include` for fetch)

**Load Balancing Requirement**: All servers must share the same Data Protection key ring.

### Content Caching Strategy

**HybridCache** (`Umbraco.PublishedCache.HybridCache`):
- In-memory cache + distributed cache support
- Published content only (not draft)
- Invalidated via notifications and cache refreshers

### API Versioning

APIs use `Asp.Versioning.Mvc`:
- Management API: `/umbraco/management/api/v{version}/*`
- Delivery API: `/umbraco/delivery/api/v{version}/*`
- OpenAPI/Swagger docs per version

### Known Limitations

1. **Circular Dependencies**: Avoided via `Lazy<T>` or event notifications
2. **Multi-Server**: Requires shared Data Protection key ring and synchronized clocks (NTP)
3. **Database Support**: SQL Server, SQLite

---

## Quick Reference

### Essential Commands

```bash
# Build solution
dotnet build

# Run all tests
dotnet test

# Run specific test category
dotnet test --filter "Category=Integration"

# Format code
dotnet format

# Pack all projects
dotnet pack -c Release
```

### Key Projects

| Project | Type | Description |
|---------|------|-------------|
| **Umbraco.Core** | Library | Interface contracts and domain models |
| **Umbraco.Infrastructure** | Library | Service implementations and data access |
| **Umbraco.Web.UI** | Application | Main web application (Razor/MVC) |
| **Umbraco.Cms.Api.Management** | Library | Management API (backoffice) |
| **Umbraco.Cms.Api.Delivery** | Library | Delivery API (headless CMS) |
| **Umbraco.Cms.Api.Common** | Library | Shared API infrastructure |
| **Umbraco.PublishedCache.HybridCache** | Library | Published content caching |
| **Umbraco.Examine.Lucene** | Library | Full-text search indexing |

### Important Files

- **Solution**: `umbraco.sln`
- **Build Config**: `Directory.Build.props`, `Directory.Packages.props`
- **Code Style**: `.editorconfig`, `.globalconfig`
- **Documentation**: `/CLAUDE.md`, `/src/Umbraco.Core/CLAUDE.md`, `/src/Umbraco.Cms.Api.Common/CLAUDE.md`

### Project-Specific Documentation

For detailed information about individual projects, see their CLAUDE.md files:
- **Core Architecture**: `/src/Umbraco.Core/CLAUDE.md` - Service contracts, notification patterns
- **API Infrastructure**: `/src/Umbraco.Cms.Api.Common/CLAUDE.md` - OpenAPI, authentication, serialization

### Getting Help

- **Official Docs**: https://docs.umbraco.com/
- **Contributing Guide**: `.github/CONTRIBUTING.md`
- **Issues**: https://github.com/umbraco/Umbraco-CMS/issues
- **Community**: https://forum.umbraco.com/
- **Releases**: https://releases.umbraco.com/

---

**This repository follows a layered architecture with strict dependency rules. The Core defines contracts, Infrastructure implements them, and Web/APIs consume them. Each layer can be understood independently, but dependencies always flow inward toward Core.**
Loading
Loading