Compare commits
175
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
246bb4c33d | ||
|
|
fcccd7da54 | ||
|
|
7170b45aec | ||
|
|
8f642f24fe | ||
|
|
11fa8a45c8 | ||
|
|
bc477c94a9 | ||
|
|
fbc8b605a9 | ||
|
|
c56dcfd345 | ||
|
|
1ff33e897c | ||
|
|
cbfbeb4272 | ||
|
|
ac811c2624 | ||
|
|
0f4d0a6e67 | ||
|
|
95bcd8fc14 | ||
|
|
2b4dc2db9a | ||
|
|
3c50dc7f7b | ||
|
|
277bd8de62 | ||
|
|
f9a70b799b | ||
|
|
e04cdc2030 | ||
|
|
273f564571 | ||
|
|
08c65ef61f | ||
|
|
68ec8223bd | ||
|
|
6ac48ef10f | ||
|
|
2f2722258c | ||
|
|
199beedaac | ||
|
|
81c99c0ac8 | ||
|
|
f822b89e98 | ||
|
|
48e9e6a814 | ||
|
|
c900a5346b | ||
|
|
6a0411fa40 | ||
|
|
b7d3236f92 | ||
|
|
acc99f420f | ||
|
|
d64579f8e3 | ||
|
|
f98c2fd3d2 | ||
|
|
3bf5de2559 | ||
|
|
f2ff1e850e | ||
|
|
17cee849d3 | ||
|
|
7fc5a88c95 | ||
|
|
f165a9cf3e | ||
|
|
3e119cb57f | ||
|
|
427a7b264e | ||
|
|
52653f780a | ||
|
|
408a8805c1 | ||
|
|
1db3f2c8cc | ||
|
|
02b75c37e7 | ||
|
|
27ffb2671c | ||
|
|
02d9b50437 | ||
|
|
98e2eba3fe | ||
|
|
a6fe4e6015 | ||
|
|
9bfa56afae | ||
|
|
005d65a49f | ||
|
|
ed93b184fc | ||
|
|
5cc7d53ed2 | ||
|
|
87be4cfc03 | ||
|
|
23f4b06cc8 | ||
|
|
b6b9bc8bf2 | ||
|
|
06a1e82488 | ||
|
|
ea3b0d4d59 | ||
|
|
532d10d102 | ||
|
|
4441d6d843 | ||
|
|
8d25312a1a | ||
|
|
e5de587721 | ||
|
|
f3863162c8 | ||
|
|
54b6c22e84 | ||
|
|
4edfbf44e9 | ||
|
|
abc6287008 | ||
|
|
20b4529196 | ||
|
|
a616e8dc48 | ||
|
|
681a510a08 | ||
|
|
88335f871d | ||
|
|
f0919792a1 | ||
|
|
3b7d2b9fa9 | ||
|
|
b3d2cabd59 | ||
|
|
bb95d74ba8 | ||
|
|
1c92cacb83 | ||
|
|
4396c3fe4b | ||
|
|
ac54cfd467 | ||
|
|
2f4d2351d0 | ||
|
|
3541b89380 | ||
|
|
530c861c2b | ||
|
|
ff60c8c1a8 | ||
|
|
c3f959f536 | ||
|
|
426eaf1ba9 | ||
|
|
3b69a2fffa | ||
|
|
bfa3c3234b | ||
|
|
80f864f298 | ||
|
|
cd541b66f4 | ||
|
|
5127b97e2c | ||
|
|
9c309f6030 | ||
|
|
564068f61b | ||
|
|
2a44169e0b | ||
|
|
20a8749b0c | ||
|
|
f8ba5db5aa | ||
|
|
96766a80db | ||
|
|
3dc61fea80 | ||
|
|
4f6a5b1c2d | ||
|
|
7a5ed5ad00 | ||
|
|
63fff17759 | ||
|
|
1b15f51798 | ||
|
|
43ccd7a171 | ||
|
|
3b0972cd56 | ||
|
|
021163f100 | ||
|
|
33bf627602 | ||
|
|
81ef90dd27 | ||
|
|
2e23ca5599 | ||
|
|
c19e424cdd | ||
|
|
b79639cb23 | ||
|
|
934834b6f5 | ||
|
|
0bf0634d4f | ||
|
|
c765ce6066 | ||
|
|
71d9e34f20 | ||
|
|
dbb492b6e8 | ||
|
|
753976bdcc | ||
|
|
6b9bd4c787 | ||
|
|
581c3ec64d | ||
|
|
1cde598ded | ||
|
|
400fd5b0e0 | ||
|
|
a69ce5df2f | ||
|
|
dd7fb87534 | ||
|
|
4940b28cc3 | ||
|
|
0c294fb8bc | ||
|
|
a03fb9b0e3 | ||
|
|
867414629b | ||
|
|
b292535cf9 | ||
|
|
3238f2306a | ||
|
|
bb44bed058 | ||
|
|
5f684eaa10 | ||
|
|
2f7f8cf905 | ||
|
|
29f267338c | ||
|
|
cef63cb07d | ||
|
|
276d12d963 | ||
|
|
88d8a5acb3 | ||
|
|
b57aacc176 | ||
|
|
23123adeaa | ||
|
|
851d96c2b8 | ||
|
|
70be022109 | ||
|
|
124c01cd6e | ||
|
|
282e3af6b8 | ||
|
|
186498ef39 | ||
|
|
2859cb808a | ||
|
|
51b7fbf5ee | ||
|
|
3119b3a8ef | ||
|
|
d428cf2d5b | ||
|
|
dc8941fefe | ||
|
|
eb33dcebdf | ||
|
|
112250da90 | ||
|
|
597300863a | ||
|
|
4c8cf2146c | ||
|
|
e28de80212 | ||
|
|
3611a28966 | ||
|
|
21bde287bb | ||
|
|
d0072a572e | ||
|
|
a986268d28 | ||
|
|
d76493fa76 | ||
|
|
b7f8a62f0d | ||
|
|
21c988309a | ||
|
|
f27e5a1917 | ||
|
|
0e6ce7d691 | ||
|
|
67008d349c | ||
|
|
634b1eed88 | ||
|
|
cfa74db61a | ||
|
|
7945bd408c | ||
|
|
7363183ef6 | ||
|
|
7f9570c671 | ||
|
|
f56bad8989 | ||
|
|
8ae64d26fd | ||
|
|
862e8a6e0a | ||
|
|
155c0c1d64 | ||
|
|
104d5986a1 | ||
|
|
35c6b46fdd | ||
|
|
6444a2d2d7 | ||
|
|
6447e63170 | ||
|
|
37994a87db | ||
|
|
5aa3ccd88c | ||
|
|
36e672ce8d | ||
|
|
b14dfcf92c |
@@ -0,0 +1,251 @@
|
||||
---
|
||||
name: umb-review
|
||||
description: Automated PR code review for Umbraco CMS. Analyzes changed files for intent, impact on consumers, breaking changes, architecture compliance, and code quality. Non-interactive — outputs a full structured review. Use this skill whenever the user asks to review a branch, review a PR, check their changes for issues, analyze a diff, or validate breaking change patterns — even if they don't say "review" explicitly. Does NOT apply to writing new code, fixing bugs, refactoring, explaining architecture, writing tests, or reviewing documentation content.
|
||||
argument-hint: <target-branch>
|
||||
---
|
||||
|
||||
# PR Review - Umbraco CMS
|
||||
|
||||
Automated, non-interactive PR code review. Analyzes changed files for intent, impact on consumers, breaking changes, architecture compliance, and code quality.
|
||||
|
||||
**Do NOT use AskUserQuestion at any point. This skill runs fully autonomously.**
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$ARGUMENTS` - Optional: target branch to diff against (auto-detected from PR, falls back to `origin/main`)
|
||||
|
||||
## Instructions
|
||||
|
||||
### 0. Verify GH CLI is Available
|
||||
|
||||
Run `gh auth status`. If it fails, read `references/gh-cli-setup.md` and present the setup instructions to the user. Do not proceed with the review.
|
||||
|
||||
### 1. Resolve Target Branch
|
||||
|
||||
Determine the target branch for comparison using this priority order:
|
||||
|
||||
1. **Explicit argument**: If `$ARGUMENTS` is provided and non-empty, use it as the target branch
|
||||
2. **PR target branch**: If no argument, run `gh pr view --json baseRefName --jq '.baseRefName'` to detect the target branch of the current branch's open PR. If a PR exists, use `origin/{baseRefName}` as the target branch.
|
||||
3. **Fallback**: If no argument and no PR found (command fails or returns empty), default to `origin/main`
|
||||
|
||||
Store the resolved target branch for use in subsequent steps. Log which resolution method was used (e.g., "Target branch: `origin/v18/dev` (from PR #1234)").
|
||||
|
||||
### 2. Load Review Standards
|
||||
|
||||
#### 2a. Load coding preferences
|
||||
|
||||
Read the coding preferences and code review scoring criteria from:
|
||||
|
||||
- `references/coding-preferences.md` (relative to this skill file)
|
||||
|
||||
Parse and internalize all rules, conventions, scoring categories, and severity definitions. These are your review criteria.
|
||||
|
||||
#### 2b. Load area-specific documentation
|
||||
|
||||
Once the changed file list is known (after step 3a), determine which areas of the codebase are touched and load the relevant documentation. Execute this sub-step between 3a and 3b. This documentation takes precedence over sibling comparison for architectural and pattern validation.
|
||||
|
||||
**Resolution order for each changed file:**
|
||||
|
||||
1. **Find the nearest `CLAUDE.md`** — walk up from the changed file's directory toward the repository root. The first `CLAUDE.md` found is the area guide for that file. Read it.
|
||||
2. **Read referenced docs** — if the `CLAUDE.md` references documentation files (e.g., a `docs/` directory), use the descriptions in the `CLAUDE.md` to determine which docs are relevant to the type of code being changed, and read those. If unsure, read all referenced docs — the cost of reading is low, the cost of missing a convention is high.
|
||||
3. **Follow cross-references in loaded docs** — if a loaded doc references another doc as covering a complementary or related concern, and the changed files touch that concern, read the referenced doc too. Repeat until no new relevant cross-references remain.
|
||||
4. **Check for applicable skills** — review the available skills list. If a skill exists for the type of code being changed, read the skill file to understand the expected patterns, structure, and conventions it enforces. Do NOT invoke the skill — just use it as a reference for what the correct implementation should look like.
|
||||
|
||||
**Store all loaded documentation** for use in step 4. These docs define the authoritative patterns and conventions that the review evaluates against.
|
||||
|
||||
### 3. Gather Changed Files
|
||||
|
||||
#### 3a. Collect file list, stats, and diff
|
||||
|
||||
Run these git commands (where `{target}` is the resolved target branch):
|
||||
|
||||
```bash
|
||||
git diff {target}...HEAD --name-only --diff-filter=d # changed files (excluding deleted)
|
||||
git diff {target}...HEAD --stat # line counts per file
|
||||
git log {target}...HEAD --oneline # commit history
|
||||
git diff {target}...HEAD # full diff (primary review source)
|
||||
```
|
||||
|
||||
**If no changes found**: Output "No changes found between current branch and `{target}`. Nothing to review." and stop.
|
||||
|
||||
#### 3b. Filter out noise files
|
||||
|
||||
From the changed file list, classify each file as **noise** or **reviewable**.
|
||||
|
||||
**Noise files** (skip entirely — do not read, do not review):
|
||||
|
||||
| Pattern | Reason |
|
||||
| ---------------------------------------------------- | ------------------------------- |
|
||||
| `*.gen.ts`, `*.gen.cs` | Auto-generated API client code |
|
||||
| `*.generated.cs`, `*.Designer.cs` (in `Migrations/`) | Auto-generated models/snapshots |
|
||||
| `*/assets/lang/*.ts` (except `en.ts`) | Non-English translation files |
|
||||
| `*/mocks/data/*.ts` | Test fixture data |
|
||||
| `*/dist-cms/*`, `*/storybook-static/*` | Build output |
|
||||
| `*/TEMP/InMemoryAuto/*` | Runtime-generated models |
|
||||
| `package-lock.json` | Dependency lock file |
|
||||
| `appsettings-schema.*.json` | Generated JSON schema |
|
||||
|
||||
Log the skip list: "Skipped {N} noise files: {comma-separated list of filenames}"
|
||||
|
||||
#### 3c. Read reviewable changed files
|
||||
|
||||
Read the full file for every reviewable changed file.
|
||||
|
||||
#### 3d. Track file counts
|
||||
|
||||
Keep track of these numbers for the review output in step 7: total changed files, noise files skipped, and reviewable files read. Also record: distinct production layers touched, distinct project directories, and total lines changed — these feed step 3e.
|
||||
|
||||
#### 3e. Assess PR complexity
|
||||
|
||||
Follow the procedure in `references/complexity-assessment.md`. Store the triggered dimensions and suggestions for step 7.
|
||||
|
||||
#### 3f. Classify PR scope
|
||||
|
||||
Classify the PR to determine which review steps are relevant:
|
||||
|
||||
| Classification | Condition | Effect |
|
||||
| --------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| **Gen-only** | All reviewable files are `gen.ts` | Skip steps 5 and 6; step 4 reviews impact on other code only |
|
||||
| **Docs-only** | All reviewable files are `.md` | Skip steps 5 and 6; step 4 reviews intent and readability only |
|
||||
| **Test-only** | All reviewable files are in `tests/` | Skip steps 5 and 6; step 4 reviews intent, code quality, and test coverage only |
|
||||
| **Config-only** | All reviewable files are `.csproj`, `.props`, `.json` config, or CI/build files | Skip step 5; step 6 checks dependency version changes only |
|
||||
| **Standard** | Anything else | No skips — run all steps |
|
||||
|
||||
### 4. Raw Code Review
|
||||
|
||||
Review each changed file holistically. Think like a senior developer reading a colleague's PR. Note all findings without worrying about format or severity yet.
|
||||
|
||||
#### 4a. Read and reason about each file
|
||||
|
||||
For each changed file, reason about: What does this code do? Is it correct? What's missing — validation, error handling, notifications, cleanup, edge cases? Could this break anything for consumers?
|
||||
|
||||
#### 4b. Validate against documentation and patterns
|
||||
|
||||
Use a **docs-first** approach: classify the code by what it does, check it against documented conventions, and only fall back to sibling comparison when docs don't cover the pattern.
|
||||
|
||||
**Step 1 — Determine the correct approach from documentation, then check whether the PR matches**
|
||||
|
||||
A PR is a proposed solution, not the source of truth. This step has two parts that must happen in order — do not start part B until part A is complete.
|
||||
|
||||
**Part A — Before validating/judging the implementation**, determine what the correct approach is for each new class or file based on what it does. Use the documentation loaded in step 2b to identify the expected base classes, patterns, and conventions. Write down the expected approach. Classify based on what the code does, not based on what neighboring files look like.
|
||||
|
||||
**Part B — Now compare the PR's implementation** against the expected approach from Part A. If it deviates from the documented approach, flag it. If the documentation specifies reference examples, read those examples to verify the implementation matches.
|
||||
|
||||
**Pattern match is the leading finding.** If the documentation defines a pattern that fits what the code does, the first and most important finding is whether the code follows that pattern.
|
||||
|
||||
**Step 2 — Fall back to sibling comparison**
|
||||
|
||||
If the documentation does not cover the specific pattern, or for cross-cutting concerns not addressed in docs, fall back to sibling comparison:
|
||||
|
||||
1. **New method on existing class/interface**: Grep for the most similar existing method on the same class using `-A 80` to capture the full method body (e.g., `UpdateCurrentUserAsync` → grep for `UpdateAsync` in the same file with `-A 80`). Compare line by line for missing cross-cutting concerns: notifications/events, validation, scoping, authorization, error handling, audit logging.
|
||||
2. **New TS class**: Grep for siblings by base class (`extends {BaseClass}`) or by interface (`implements {Interface}`) or by name suffix (e.g., `CurrentUserController` → grep for `UserController`). Compare for missing concerns.
|
||||
3. **New CS class**: Grep for siblings by base class (`class {ClassName} : {BaseClass}`) or by interface (`class {ClassName} : {Interface}`) or by name suffix (e.g., `ManagementApiComposer` → grep for `ApiComposer`). Compare for missing concerns.
|
||||
|
||||
**Important:** Sibling comparison validates cross-cutting concerns, but it must not override documented conventions. If a sibling deviates from documented patterns, that sibling is wrong — do not copy its deviation.
|
||||
|
||||
Store your raw findings — they feed into step 7.
|
||||
|
||||
### 5. Impact Analysis
|
||||
|
||||
**Skip this step if PR scope is docs-only, test-only, or config-only.**
|
||||
|
||||
Follow the procedure in `references/impact-analysis.md`.
|
||||
|
||||
### 6. Breaking Changes Check
|
||||
|
||||
**Skip this step if PR scope is docs-only or test-only. If config-only, only check for dependency version changes that could break consumers.**
|
||||
|
||||
Follow the procedure in `references/breaking-changes.md`.
|
||||
|
||||
### 7. Consolidate and Output Review
|
||||
|
||||
Merge findings from step 4 (raw review), step 5 (impact analysis), and step 6 (breaking changes). For each finding, assign severity (Critical/Important/Suggestion) and verify it relates to changed code — not pre-existing issues. Before outputting, drop any finding about whitespace, blank lines, formatting, or comment wording. Then present the review in this exact format:
|
||||
|
||||
```markdown
|
||||
## PR Review
|
||||
|
||||
**Target:** `{target_branch}` · **Based on commit:** `{head_sha}`
|
||||
[If any skipped files, append: · **Skipped:** {skipped} files out of {total} total]
|
||||
[If step 3f classification is not "Standard", append: · **Classified as:** {classification}]
|
||||
|
||||
[1–2 sentences: what this PR accomplishes , keep it as short as possible, only highlight the primary essence.]
|
||||
|
||||
- **Modified public API:** {changed existing interfaces/types/classes/methods}
|
||||
[Omit bullet if none]
|
||||
- **Affected implementations (outside this PR):** {interfaces/types/classes/methods using modified public API}
|
||||
[Omit bullet if none]
|
||||
- **Breaking changes:** {violations with specifics}
|
||||
[Omit bullet if none]
|
||||
- **Other changes:** {changes not listed above that an Umbraco user, plugin developer, or API consumer would notice — e.g., behavior changes, default value changes, error message changes, new configuration options, removed functionality. Exclude internal renames, formatting, and private implementation details.}
|
||||
[Omit bullet if none]
|
||||
|
||||
[If step 3e triggered any dimensions, insert this block. Omit entirely if nothing triggered:]
|
||||
|
||||
> [!NOTE]
|
||||
> **Complexity advisory** — This PR may benefit from splitting.
|
||||
>
|
||||
> - **{Dimension}:** {Explanation and concrete split suggestion from step 3e}
|
||||
> [one bullet per triggered dimension]
|
||||
>
|
||||
> _This is an observation, not a blocker. The full review follows below._
|
||||
|
||||
---
|
||||
|
||||
### Critical
|
||||
|
||||
[Must fix before merge — security vulnerabilities, data loss, broken functionality, breaking changes without proper patterns]
|
||||
|
||||
- **`{file}:{line}`**: {problem} → {fix}
|
||||
|
||||
[Omit section if none]
|
||||
|
||||
### Important
|
||||
|
||||
[Should fix — performance issues, missing tests, architectural violations, pattern misuse]
|
||||
|
||||
- **`{file}:{line}`**: {observation} → {suggestion}
|
||||
|
||||
[Omit section if none]
|
||||
|
||||
### Suggestions
|
||||
|
||||
[Nice to have — readability, minor refactoring, alternative approaches]
|
||||
|
||||
- **`{file}:{line}`**: {detail}
|
||||
|
||||
[Omit section if none]
|
||||
|
||||
---
|
||||
|
||||
[One of:]
|
||||
|
||||
## Approved
|
||||
|
||||
This looks good to be merged as-is, but please do a manual sanity check and testing before merging.
|
||||
|
||||
## Approved with Suggestions for improvement
|
||||
|
||||
Good to go, but please carefully consider the importance of the suggestions.
|
||||
|
||||
## Request Changes
|
||||
|
||||
Critical and important issues must be addressed first.
|
||||
|
||||
## Needs re-work
|
||||
|
||||
This is in such a bad state that the feedback of this review is not sufficient to guide improvements, the PR cannot be approved.
|
||||
```
|
||||
|
||||
**Guidelines for the review output:**
|
||||
|
||||
— When reporting information, be extremely concise and sacrifice grammar for sake of concision.
|
||||
|
||||
- Only review code that was changed in the diff — pre-existing issues are out of scope. Focus on what compilers and linters cannot catch: behavioral side-effects (e.g., a changed default alters runtime behavior for consumers), architectural violations (e.g., a new dependency breaks layering), breaking changes for external consumers of the public API, and security implications. Leave type errors, missing imports, and broken references to CI.
|
||||
- Be specific — always reference file and line number
|
||||
- Explain WHY something is an issue, not just WHAT, but avoid stating the obvious.
|
||||
- For complex matters, provide concrete fix suggestions, including code snippets when helpful
|
||||
- Keep it constructive — the goal is to help, not gatekeep
|
||||
- Don't repeat the same finding for every occurrence — mention it once and note "same pattern in {other files}"
|
||||
- Focus on substantive issues only. Do NOT flag purely cosmetic or stylistic concerns. Specifically, never flag: code formatting or whitespace, comment grammar or wording, redundant-but-harmless syntax (e.g., optional chaining after a truthiness check), code duplication that doesn't cause bugs, or HTML template cosmetics. The only exception is when a stylistic issue has a concrete impact on performance or rendering. Note: missing JSDoc/documentation on public or exported APIs is a substantive finding (per coding preferences), not a cosmetic one — flag it as a Suggestion.
|
||||
- For breaking changes, reference the specific pattern from the CLAUDE.md that should be applied
|
||||
- Do not suggest changes that would themselves introduce breaking changes. If a suggestion would alter public API surface (e.g., changing return types, renaming public members), it is not appropriate for a PR targeting `main` within a major version. Only suggest non-breaking alternatives.
|
||||
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"skill_name": "umb-review",
|
||||
"evals": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "pr-22214-large-frontend-refactor",
|
||||
"prompt": "Review the changes in PR #22214 (branch origin/pr/22214 targeting main). This is a large frontend refactor migrating create entity actions to use entityCreateOptionAction extensions, with deprecations.",
|
||||
"expected_output": "A structured review that identifies frontend deprecation patterns, flags the large PR complexity, handles 75+ files correctly, checks for breaking changes in exported components, and produces the correct output format.",
|
||||
"pr_number": 22214,
|
||||
"pr_branch": "origin/pr/22214",
|
||||
"base_branch": "origin/main",
|
||||
"files": [],
|
||||
"assertions": [
|
||||
{"id": "deprecation-patterns-noted", "text": "Review identifies deprecation patterns (@deprecated, UmbDeprecation)"},
|
||||
{"id": "frontend-breaking-change-awareness", "text": "Checks frontend-specific breaking changes (exports, custom elements) not just backend"},
|
||||
{"id": "file-references-present", "text": "Findings reference specific files with line numbers"},
|
||||
{"id": "no-false-critical-on-deprecations", "text": "Properly deprecated code is NOT flagged as Critical breaking change"},
|
||||
{"id": "no-stylistic-nitpicks", "text": "Review does not flag purely cosmetic/stylistic issues (formatting, whitespace, naming conventions, comment grammar, code style preferences) unless they affect performance or rendering. Missing JSDoc on new public APIs is NOT a stylistic issue — it is a legitimate finding."},
|
||||
{"id": "manifest-alias-rename-detected", "text": "Alias renames (CreateOptions → Create) flagged as Critical breaking change"},
|
||||
{"id": "non-exported-deletions-dismissed", "text": "Deleted action classes NOT flagged as breaking (verified against package.json exports)"},
|
||||
{"id": "noise-files-filtered", "text": "Does not review noise files (generated files, lock files, etc.)"},
|
||||
{"id": "complexity-advisory-triggers", "text": "Review includes a complexity/split advisory for the large 75+ file scope"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "pr-21672-small-frontend-bugfix",
|
||||
"prompt": "Review the changes in PR #21672 (branch origin/pr/21672 targeting main). This is a small 4-file frontend bugfix implementing tab validation badges in the block editor.",
|
||||
"expected_output": "A clean review that correctly identifies this as a small focused bugfix, avoids false positives, and either approves or approves with minor suggestions.",
|
||||
"pr_number": 21672,
|
||||
"pr_branch": "origin/pr/21672",
|
||||
"base_branch": "origin/main",
|
||||
"files": [],
|
||||
"assertions": [
|
||||
{"id": "complexity-advisory-absent", "text": "Review does NOT include a complexity/split advisory"},
|
||||
{"id": "no-false-breaking-changes", "text": "Review does not flag breaking changes"},
|
||||
{"id": "proportionate-verdict", "text": "Verdict is 'Request Changes'"},
|
||||
{"id": "concise-review", "text": "Review output is under 200 lines"},
|
||||
{"id": "no-stylistic-nitpicks", "text": "Review does not flag purely cosmetic/stylistic issues (formatting, whitespace, naming conventions, comment grammar, code style preferences) unless they affect performance or rendering. Missing JSDoc on new public APIs is NOT a stylistic issue — it is a legitimate finding."}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "pr-22217-small-backend-webhook",
|
||||
"prompt": "Review the changes in PR #22217 (branch origin/pr/22217 targeting v18/dev). This is a tiny 3-file backend change to the default webhook payload type.",
|
||||
"expected_output": "A concise review that correctly resolves v18/dev as target branch, handles the small change proportionately, and considers the behavioral impact of changing a default value.",
|
||||
"pr_number": 22217,
|
||||
"pr_branch": "origin/pr/22217",
|
||||
"base_branch": "origin/v18/dev",
|
||||
"files": [],
|
||||
"assertions": [
|
||||
{"id": "correct-target-branch", "text": "Review references 'v18/dev' as the target branch (not 'main')"},
|
||||
{"id": "default-value-change-noted", "text": "Review discusses the behavioral impact of changing the default payload type"},
|
||||
{"id": "proportionate-review", "text": "Review output is under 150 lines"},
|
||||
{"id": "no-stylistic-nitpicks", "text": "Review does not flag purely cosmetic/stylistic issues (formatting, whitespace, naming conventions, comment grammar, code style preferences) unless they affect performance or rendering. Missing JSDoc on new public APIs is NOT a stylistic issue — it is a legitimate finding."},
|
||||
{"id": "ignores-preexisting-issues", "text": "Does NOT flag the ~30 builder extension methods with Legacy defaults (pre-existing, not changed in the PR)"},
|
||||
{"id": "side-effect-detection", "text": "Flags stale WebhookSettings.cs docs as a side-effect of the constant value change"},
|
||||
{"id": "consumer-identification", "text": "Identifies affected consumers outside the PR (WebhookSettings, UmbracoBuilder, or WebhookEventCollectionBuilderExtensions)"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "pr-22268-frontend-feature-workspace-modal",
|
||||
"prompt": "Review the changes in PR #22268 (branch origin/pr/22268 targeting main). This is a 29-file frontend feature adding a current user workspace modal.",
|
||||
"expected_output": "A review of a medium-sized new feature PR. Should assess the new code for architectural compliance, check for breaking changes (new exports, custom elements), and evaluate code quality without flagging pre-existing issues.",
|
||||
"pr_number": 22268,
|
||||
"pr_branch": "origin/pr/22268",
|
||||
"base_branch": "origin/main",
|
||||
"files": [],
|
||||
"assertions": [
|
||||
{"id": "complexity-advisory-triggers", "text": "Review includes a complexity/split advisory (3 layers: Core, API, Frontend across 27+ files)"},
|
||||
{"id": "breaking-changes-on-interface-additions", "text": "Flags new interface methods without default implementations as breaking changes (Pattern 3)"},
|
||||
{"id": "no-stylistic-nitpicks", "text": "Review does not flag purely cosmetic/stylistic issues unless they affect performance or rendering. Missing JSDoc on new public APIs is NOT a stylistic issue — it is a legitimate finding."},
|
||||
{"id": "diff-scoped", "text": "All findings reference code that was changed in the diff, not pre-existing issues"},
|
||||
{"id": "new-feature-assessed", "text": "Review assesses the new feature's architecture, patterns, or integration approach — not just absence of bugs"},
|
||||
{"id": "no-false-notification-finding", "text": "Review does NOT flag UpdateCurrentUserAsync as missing UserSavingNotification/UserSavedNotification — the sibling UpdateAsync also does not publish these notifications, so flagging their absence would be a false positive"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "pr-22215-frontend-architecture-violation",
|
||||
"prompt": "Review the changes in PR #22215 (branch origin/pr/22215 targeting main). This is a 2-file frontend feature adding user management to the user group workspace.",
|
||||
"expected_output": "A review that catches the architecture violation: the workspace context directly imports and calls UserService and UserGroupService (generated API clients) instead of going through a repository. In the Umbraco backoffice, workspace contexts access data via repositories, not by calling API services directly. The review should flag this as a significant architecture issue and request changes.",
|
||||
"pr_number": 22215,
|
||||
"pr_branch": "origin/pr/22215",
|
||||
"base_branch": "origin/main",
|
||||
"files": [],
|
||||
"assertions": [
|
||||
{"id": "service-bypass-detected", "text": "Review flags that the workspace context directly imports/calls UserService or UserGroupService instead of using a repository"},
|
||||
{"id": "repository-pattern-recommended", "text": "Review recommends using the repository pattern (going through a repository/data-source layer) rather than calling API services directly from the workspace context"},
|
||||
{"id": "verdict-request-changes", "text": "Verdict is 'Request Changes' (the architecture violation warrants requesting changes, not just approving with suggestions)"},
|
||||
{"id": "no-stylistic-nitpicks", "text": "Review does not flag purely cosmetic/stylistic issues (formatting, whitespace, naming conventions, comment grammar, code style preferences) unless they affect performance or rendering. Missing JSDoc on new public APIs is NOT a stylistic issue — it is a legitimate finding."},
|
||||
{"id": "no-false-breaking-changes", "text": "Review does not flag breaking changes (this PR only adds new code, no public API is removed or modified)"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
# Breaking Changes Reference
|
||||
|
||||
This document describes how to detect and validate breaking changes during PR review. It covers both backend (.NET) and frontend (TypeScript/Lit) patterns.
|
||||
|
||||
---
|
||||
|
||||
## Version Detection
|
||||
|
||||
**Always read `version.json`** at the repository root to determine the current major version. This drives the obsolete removal target calculation:
|
||||
|
||||
- Current major version: read from `version.json` → `version` field (e.g., `"17.4.0-rc"` → major version `17`)
|
||||
- Obsolete removal target: `current + 2` (e.g., if current is 17, removal is scheduled for Umbraco 19)
|
||||
- Format: `[Obsolete("... Scheduled for removal in Umbraco {current+2}.")]`
|
||||
|
||||
---
|
||||
|
||||
## Backend (.NET) Breaking Changes
|
||||
|
||||
### What Constitutes a Breaking Change
|
||||
|
||||
Any of these on a `public` or `protected` member:
|
||||
|
||||
- Removing or renaming a class, interface, struct, record, or enum
|
||||
- Removing or renaming a method, property, or field
|
||||
- Changing a method signature (parameters, return type)
|
||||
- Adding required parameters to an existing method
|
||||
- Adding methods to a public interface (without default implementation)
|
||||
- Changing a constructor signature on a public class
|
||||
- Removing or changing enum values
|
||||
- Changing type hierarchy (base class, implemented interfaces)
|
||||
|
||||
### Pattern 1: Obsolete Constructor + StaticServiceProvider
|
||||
|
||||
When a public class needs new dependencies, the existing constructor must be preserved.
|
||||
|
||||
**Correct pattern:**
|
||||
|
||||
```csharp
|
||||
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public MyService(IDependencyA depA)
|
||||
: this(
|
||||
depA,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDependencyB>())
|
||||
{
|
||||
}
|
||||
|
||||
public MyService(IDependencyA depA, IDependencyB depB)
|
||||
{
|
||||
_depA = depA;
|
||||
_depB = depB;
|
||||
}
|
||||
```
|
||||
|
||||
**Validation checklist:**
|
||||
|
||||
- [ ] Old constructor has `[Obsolete]` attribute with correct removal version
|
||||
- [ ] Old constructor calls new constructor via `: this(...)`
|
||||
- [ ] `StaticServiceProvider.Instance.GetRequiredService<T>()` used for new params only
|
||||
- [ ] DI registration uses the NEW constructor (old is for external consumers only)
|
||||
- [ ] Removal version is `{current_major + 2}`
|
||||
|
||||
**Common mistakes to flag:**
|
||||
|
||||
- Removing the old constructor entirely (breaking change!)
|
||||
- Old constructor NOT calling new constructor (code duplication)
|
||||
- Wrong removal version in `[Obsolete]`
|
||||
- Missing `StaticServiceProvider` resolution for new dependencies
|
||||
- DI registration still using the old constructor
|
||||
|
||||
### Pattern 2: Obsolete Method + New Overload
|
||||
|
||||
When a method signature needs to change, add the new overload and obsolete the old.
|
||||
|
||||
**Correct pattern:**
|
||||
|
||||
```csharp
|
||||
[Obsolete("Use the overload taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public void DoThing(string name)
|
||||
=> DoThing(name, extraParam: null);
|
||||
|
||||
public void DoThing(string name, string? extraParam)
|
||||
{
|
||||
// Real implementation here
|
||||
}
|
||||
```
|
||||
|
||||
**Validation checklist:**
|
||||
|
||||
- [ ] Old method has `[Obsolete]` attribute with correct removal version
|
||||
- [ ] Old method calls new method, providing defaults for new parameters
|
||||
- [ ] All internal callers updated to use the new method
|
||||
- [ ] No internal code references the obsolete method (except the delegation)
|
||||
|
||||
### Pattern 3: Default Interface Implementation
|
||||
|
||||
When adding methods to a public interface, provide a default implementation.
|
||||
|
||||
**Correct pattern:**
|
||||
|
||||
```csharp
|
||||
public interface IMyService
|
||||
{
|
||||
void ExistingMethod();
|
||||
|
||||
// New method with default implementation
|
||||
void NewMethod(string param)
|
||||
=> ExistingMethod(); // delegate to existing if possible
|
||||
}
|
||||
```
|
||||
|
||||
**Strategies for defaults (in order of preference):**
|
||||
|
||||
1. Use existing interface methods to satisfy the contract
|
||||
2. Return a sensible default (empty collection, null, etc.)
|
||||
3. Throw `NotImplementedException` if no reasonable default exists
|
||||
|
||||
**Validation checklist:**
|
||||
|
||||
- [ ] New interface method has a default implementation
|
||||
- [ ] TODO comment present: `// TODO (V{next-major}): Remove the default implementation when {obsolete method} is removed.`
|
||||
- [ ] Default implementation is functionally correct (even if not optimal)
|
||||
- [ ] If `StaticServiceProvider` is used in default impl, noted as temporary
|
||||
|
||||
### Obsolete Attribute Validation
|
||||
|
||||
For any `[Obsolete]` attribute found in changed code:
|
||||
|
||||
1. **Format**: Must contain `"Scheduled for removal in Umbraco {version}."`
|
||||
2. **Version**: Must be `current_major + 2` (read from `version.json`)
|
||||
3. **Pragma**: Where obsolete members must call each other, `#pragma warning disable CS0618` / `#pragma warning restore CS0618` must be present
|
||||
|
||||
### Internal Caller Check
|
||||
|
||||
After finding obsolete patterns, verify:
|
||||
|
||||
- Search the codebase for usages of the obsolete member
|
||||
- **No internal code** (inside `src/`) should reference obsolete members
|
||||
- Only the obsolete member's own delegation (calling the new version) is acceptable
|
||||
- External consumers (outside the repo) get the deprecation period to migrate
|
||||
|
||||
---
|
||||
|
||||
## Frontend (TypeScript/Lit) Breaking Changes
|
||||
|
||||
The backoffice is published as `@umbraco-cms/backoffice` with 140+ named exports. Plugin developers depend on this public API surface.
|
||||
|
||||
**Critical frontend rule (does not apply to backend .NET where `public`/`protected` visibility determines the API surface): only symbols reachable through the `package.json` `exports` field are public API.** Anything not exported — whether classes, functions, constants, types, or entire files — is an internal implementation detail, even if other internal code imports it. Removing or changing unexported frontend symbols is not a breaking change. Before flagging a frontend deletion or rename as breaking, verify the symbol is reachable via `package.json` exports. If it is not, do not flag it.
|
||||
|
||||
### Custom Elements (Web Components)
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Renaming or removing a registered custom element tag (`umb-*`)
|
||||
- Removing elements from `HTMLElementTagNameMap`
|
||||
- Removing or changing `@property()` decorated fields on exported components
|
||||
- Removing event emissions (checked via `this.dispatchEvent`)
|
||||
- Removing CSS custom properties (`@cssprop` in JSDoc)
|
||||
- Removing CSS parts (`@csspart` in JSDoc)
|
||||
|
||||
**How to detect:**
|
||||
|
||||
- Check diff for removed `@customElement('umb-...')` decorators
|
||||
- Check diff for removed `@property()` fields on exported components
|
||||
- Check diff for removed entries in `HTMLElementTagNameMap` declarations
|
||||
|
||||
### Exported Types/Interfaces
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Removing exports from `package.json` `exports` field
|
||||
- Changing the shape of exported interfaces (removing properties, changing types)
|
||||
- Renaming exported types (consumers import by name)
|
||||
- Removing union type members
|
||||
- Changing generic type parameter constraints
|
||||
|
||||
**How to detect:**
|
||||
|
||||
- Check if `package.json` `exports` field is modified
|
||||
- Check diff for removed `export` statements
|
||||
- Check diff for changed interface/type shapes
|
||||
|
||||
### Manifest/Extension System
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Renaming a manifest `alias` value — plugin developers reference aliases by string in conditions, overwrites, and extension registry lookups. Alias renames are not caught by the compiler since they are string-based. A renamed alias silently breaks any plugin that references the old string.
|
||||
- Removing support for a manifest `type` that plugins use
|
||||
- Changing manifest `alias` resolution or validation
|
||||
- Removing or renaming manifest `kind` types
|
||||
- Changing extension bundle structure
|
||||
|
||||
**How to detect:**
|
||||
|
||||
- **Alias renames**: Compare `alias:` values in manifest files before and after. Changed alias strings are Critical — the old alias should be preserved as a deprecated entry.
|
||||
- Search for changes to manifest type definitions
|
||||
- Check for removed or renamed manifest kinds
|
||||
|
||||
### Context API
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Removing context tokens from exports
|
||||
- Changing the shape of data provided by a context
|
||||
- Removing context provider/consumer mechanisms
|
||||
|
||||
**How to detect:**
|
||||
|
||||
- Check for removed context token exports
|
||||
- Check for changes to context provider classes
|
||||
|
||||
### Controllers/Lifecycle
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Changing controller base class inheritance requirements
|
||||
- Removing controller lifecycle hooks
|
||||
- Breaking cleanup mechanisms in `disconnectedCallback()`
|
||||
|
||||
### Observable/State
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Removing observable properties from the public API
|
||||
- Changing observable emission patterns
|
||||
|
||||
### npm Publishing
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Changing version constraints that exclude previously-supported versions
|
||||
- Adding incompatible peer dependency constraints
|
||||
|
||||
**How to detect:**
|
||||
|
||||
- Check if `package.json` `peerDependencies` or `dependencies` changed
|
||||
- Verify version ranges are not narrowed
|
||||
|
||||
---
|
||||
|
||||
## Reporting Breaking Changes
|
||||
|
||||
When a breaking change is detected, report:
|
||||
|
||||
1. **What**: The specific change and which public symbol is affected
|
||||
2. **Pattern**: Which mitigation pattern should be applied (Pattern 1, 2, or 3 for backend)
|
||||
3. **Severity**: Critical (no mitigation present) or Important (mitigation present but incorrect)
|
||||
4. **Fix**: Concrete code suggestion showing the correct pattern
|
||||
|
||||
If no breaking changes are detected, state: "No breaking changes detected."
|
||||
@@ -0,0 +1,168 @@
|
||||
# Coding Preferences & Review Criteria
|
||||
|
||||
These are the coding preferences and code review standards used by the review skill. They define what the review evaluates against.
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
- **Always create blackbox tests** for new/changed code
|
||||
- Choose the appropriate test level:
|
||||
- **Unit tests** for isolated logic
|
||||
- **Integration tests** for application services/use cases
|
||||
- **E2E tests** for API endpoints
|
||||
|
||||
### Test Class Naming
|
||||
|
||||
- Test classes must be postfixed with `Tests` (e.g., `OrderServiceTests`)
|
||||
- One test class per class under test
|
||||
|
||||
### Test Method Naming
|
||||
|
||||
**C# tests**: Use the `Can_`/`Cannot_` pattern with PascalCase underscore-separated words:
|
||||
|
||||
- `Can_Schedule_Publish_Invariant`
|
||||
- `Cannot_Delete_Non_Existing`
|
||||
- `Can_Schedule_Publish_Single_Culture`
|
||||
|
||||
Large test classes are split into partial files by method: `ContentServiceTests.Delete.cs`, `ContentServiceTests.Publish.cs`.
|
||||
|
||||
**TypeScript tests**: Use BDD-style `it()` with natural language descriptions:
|
||||
|
||||
- `it('should not allow the returned value to be lower than min')`
|
||||
- `it('converts string to camelCase')`
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Optional, but must be blackbox tests so refactoring does not break tests
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Every use case / application service must have integration tests
|
||||
- Tests run against real database (containerized or similar)
|
||||
- Test the full flow from application layer through infrastructure
|
||||
|
||||
### E2E Tests
|
||||
|
||||
- Every API endpoint must have E2E tests
|
||||
- Test realistic scenarios including error cases
|
||||
|
||||
---
|
||||
|
||||
## Trade-offs
|
||||
|
||||
When making decisions, prioritize:
|
||||
|
||||
- **Readability** over cleverness
|
||||
- **Flexibility** over rigidity
|
||||
- Explain trade-offs when deviating from these defaults
|
||||
|
||||
---
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- Communicate breaking changes at the **OpenAPI/openapi.json level**
|
||||
- Clearly document what changed and the migration path
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Document all public or exported types** (classes, interfaces, types, methods, properties)
|
||||
- Keep documentation in sync with code changes
|
||||
- Add **JS Docs** on all public frontend APIs (classes, methods, properties)
|
||||
- Focus on "why" and usage, not restating the obvious
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Use what's available in the codebase, unless there is no good choice
|
||||
- **Flag new dependencies** for review — new packages should be justified
|
||||
- Prefer well-maintained, widely-used packages
|
||||
|
||||
---
|
||||
|
||||
## Error Messages & Logging
|
||||
|
||||
- **User-facing errors**: Clear, friendly, actionable
|
||||
- **Log messages**: Technical, detailed, with context
|
||||
- Include correlation IDs and relevant data in logs
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
- **Always check for security issues** using OWASP Top 10 as baseline
|
||||
- Flag potential vulnerabilities immediately
|
||||
- Suggest secure alternatives when spotting risky patterns
|
||||
- Apply principle of least privilege
|
||||
|
||||
---
|
||||
|
||||
## Immutability
|
||||
|
||||
- Prefer **immutability** by default
|
||||
- Allow internal properties to be mutated, as long as they are not direct references coming from the outside
|
||||
|
||||
---
|
||||
|
||||
## Nullability
|
||||
|
||||
- **TypeScript / JavaScript**
|
||||
- Prefer `undefined` for optional/omitted values (e.g., optional parameters, props, and fields)
|
||||
- Use `null` only when the domain model explicitly encodes "no value" or "not set" (e.g., `string | null` from APIs/DB), and be consistent with existing types
|
||||
- Avoid mixing `null` and `undefined` for the same concept within the same model or API surface
|
||||
|
||||
- **C#**
|
||||
- use nullable types (e.g., `string?`, `int?`) where absence is valid
|
||||
- Prefer domain modeling (value objects, options/results, empty collections) over `null` where appropriate, but respect existing conventions in the codebase
|
||||
|
||||
---
|
||||
|
||||
## C# Specific
|
||||
|
||||
- use Notification pattern (not C# events), Composer pattern (DI registration), Scoping with `Complete()`, Attempt pattern for operation results.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
- Follow **Clean Architecture** principles
|
||||
- **Fail-fast** principle: detect and report errors as early as possible
|
||||
- Within the established layered architecture (Core/Infrastructure/Web/API), organize code by feature inside each layer where practical, while preserving dependency direction
|
||||
- One class per file
|
||||
- Avoid N+1 queries
|
||||
- Profile before optimizing non-critical paths
|
||||
|
||||
### Type Hierarchy Consistency
|
||||
|
||||
When parallel model types have inconsistent relationships to a shared base type:
|
||||
|
||||
**TypeScript**: manipulations via `Omit`, `Pick`, intersection overrides, or workarounds like `as unknown as` / double-casts to bridge type mismatches.
|
||||
|
||||
**C#**: hiding base members with `new` to change types, explicit interface implementations to mask mismatches, or downcasting base return types in derived classes.
|
||||
|
||||
- **Do NOT suggest** the PR code should deviate from its base type to match a sibling that already deviates. Copying the deviation spreads the problem.
|
||||
- **Do flag** the architectural inconsistency: parallel models should share a compatible base contract. The model that manipulates or deviates from the base type is the one that needs attention — not the one that extends it correctly.
|
||||
- **Frame the suggestion** as: "These related models have inconsistent type hierarchies. `{deviating type}` manipulates the base contract of `{base type}`, which forces shared consumers like `{shared utility}` to require a shape that conforming subtypes can't satisfy."
|
||||
|
||||
---
|
||||
|
||||
## Code Style
|
||||
|
||||
- Follow standard naming conventions for the language (C# or JS/TS)
|
||||
- Keep components small and focused on a single responsibility
|
||||
- Prefer early returns
|
||||
- Small functions
|
||||
- No nested ternaries
|
||||
|
||||
---
|
||||
|
||||
## Severity Levels
|
||||
|
||||
| Severity | Meaning |
|
||||
|----------|---------|
|
||||
| **Critical** | Must fix before merge — security vulnerabilities, data loss risks, broken functionality |
|
||||
| **Important** | Should fix — performance issues, missing tests, architectural violations |
|
||||
| **Suggestion** | Nice to have — readability, minor refactoring, alternative approaches |
|
||||
@@ -0,0 +1,33 @@
|
||||
# PR Complexity Assessment
|
||||
|
||||
Evaluate whether the PR's scope suggests it should be split. This assessment is **informational only** — it never blocks or shortens the review.
|
||||
|
||||
## Always check: Formatting mixed with logic
|
||||
|
||||
This check applies to every PR regardless of size or scope.
|
||||
|
||||
Run both commands and compare per-file line counts:
|
||||
```bash
|
||||
git diff {target}...HEAD --stat
|
||||
git diff {target}...HEAD --stat --ignore-all-space
|
||||
```
|
||||
|
||||
For any file where the whitespace-ignored diff is less than **half** the full diff size (and the full diff is over 50 lines), that file has significant formatting changes mixed with logic. Flag it with a split suggestion: "File(s) {list} contain significant formatting changes mixed with logic. Consider a separate formatting-only commit or PR to keep the functional diff reviewable."
|
||||
|
||||
## Multi-project scope check
|
||||
|
||||
Skip this section entirely if ALL production files reside in a single project directory or if the PR is docs-only, test-only, dependency-bump-only, or rename-only.
|
||||
|
||||
Otherwise, flag any dimension that applies:
|
||||
|
||||
| Dimension | Condition | Suggestion |
|
||||
|---|---|---|
|
||||
| **Size** | 30+ files OR 1500+ lines, spanning 2+ projects | "If changes in {projectA} and {projectB} are independently functional, they could be separate PRs." |
|
||||
| **Layer spread** | 3+ layers touched (Core/Infrastructure/Web/API/Frontend), 10+ files | "Consider splitting by layer — e.g., Core+Infrastructure first, then API/Frontend consumers." |
|
||||
| **Mixed intent** | 2+ intent categories (new feature, bugfix, refactor, dependency update) with 15+ files or 3+ projects | "Consider extracting the {secondary intent} into a separate PR." |
|
||||
|
||||
Intent categories — detect from diff characteristics, not commit messages:
|
||||
- **New feature**: new files or new `public`/`export` declarations
|
||||
- **Bug fix**: small targeted edits, no new files (don't co-flag with new feature)
|
||||
- **Refactor**: file renames, symbols moved but logic unchanged
|
||||
- **Dependency update**: changes to `.csproj`, `Directory.Packages.props`, `package.json`
|
||||
@@ -0,0 +1,23 @@
|
||||
# GH CLI Setup Instructions
|
||||
|
||||
The GitHub CLI (`gh`) is required for this review skill to detect PR target branches.
|
||||
|
||||
## Installation
|
||||
|
||||
Install via Homebrew:
|
||||
|
||||
```
|
||||
brew install gh
|
||||
```
|
||||
|
||||
Or see https://cli.github.com/ for other installation methods.
|
||||
|
||||
## Authentication
|
||||
|
||||
After installing, authorize by running this in the terminal (use the `!` prefix in Claude Code):
|
||||
|
||||
```
|
||||
! gh auth login
|
||||
```
|
||||
|
||||
Follow the prompts to authenticate with your GitHub account.
|
||||
@@ -0,0 +1,153 @@
|
||||
# Impact Analysis Reference
|
||||
|
||||
This document describes how to perform impact analysis during PR review. The goal is to look beyond the diff to understand how changes affect consumers in other parts of the codebase.
|
||||
|
||||
---
|
||||
|
||||
## 1. Extract Changed Public Symbols
|
||||
|
||||
Scan the diff output for changes to public API surface:
|
||||
|
||||
### Backend (.NET)
|
||||
|
||||
Look for added, modified, or removed lines containing:
|
||||
|
||||
- `public class`, `public abstract class`, `public sealed class`
|
||||
- `public interface`
|
||||
- `public record`, `public struct`, `public enum`
|
||||
- `public` or `protected` methods, properties, fields
|
||||
- `public static` members
|
||||
- Constructor signatures on public types
|
||||
|
||||
### Frontend (TypeScript/Lit)
|
||||
|
||||
Look for changes to:
|
||||
|
||||
- `export class`, `export interface`, `export type`, `export enum`
|
||||
- `export function`, `export const`
|
||||
- `@property()` decorated fields on exported components
|
||||
- `@customElement()` registrations
|
||||
- Entries in `package.json` `exports` field
|
||||
|
||||
Collect a list of all changed public symbol names (type names, method names, property names).
|
||||
|
||||
---
|
||||
|
||||
## 2. Search for Consumers
|
||||
|
||||
For each changed public symbol, search the `src/` directory for usages **outside the changed file itself**.
|
||||
|
||||
### Grep Strategy
|
||||
|
||||
Use the Grep tool with these settings:
|
||||
|
||||
```
|
||||
pattern: {symbol name}
|
||||
path: src/
|
||||
output_mode: files_with_matches
|
||||
head_limit: 20
|
||||
```
|
||||
|
||||
Use `head_limit: 20` to avoid overwhelming results — if there are more than 20 consumers, note "20+ consumers found" and list the first 20.
|
||||
|
||||
### What to Search For
|
||||
|
||||
For each changed type/method, search for:
|
||||
|
||||
- **Type references**: class name, interface name (e.g., `IContentService`)
|
||||
- **Method calls**: method name in context (e.g., `\.GetById\(` for a method rename)
|
||||
- **Constructor usage**: `new TypeName(`
|
||||
- **DI registrations**: `.AddSingleton<IType, Type>`, `.AddScoped<`, `.AddTransient<`
|
||||
- **Notification handlers**: if a notification type changed, search for `INotificationHandler<NotificationTypeName>` and `INotificationAsyncHandler<NotificationTypeName>`
|
||||
- **Interface implementations**: if an interface changed, search for `: IInterfaceName` or `IInterfaceName,`
|
||||
|
||||
### Excluding the Changed File
|
||||
|
||||
When reporting consumers, exclude files that are part of the PR's changes (they're already being reviewed). The interesting consumers are those **outside** the PR that may be affected.
|
||||
|
||||
---
|
||||
|
||||
## 3. Check Dependency Flow Direction
|
||||
|
||||
The Umbraco architecture enforces strict unidirectional dependencies:
|
||||
|
||||
```
|
||||
Api.Management / Api.Delivery (depend on Api.Common)
|
||||
↓
|
||||
Api.Common (depends on Web.Common)
|
||||
↓
|
||||
Web.Common (depends on Infrastructure)
|
||||
↓
|
||||
Infrastructure (depends on Core)
|
||||
↓
|
||||
Core (no dependencies)
|
||||
```
|
||||
|
||||
### Layer Mapping
|
||||
|
||||
Map each changed file to its architectural layer:
|
||||
|
||||
| Path prefix | Layer |
|
||||
|---|---|
|
||||
| `src/Umbraco.Core/` | Core |
|
||||
| `src/Umbraco.Infrastructure/` | Infrastructure |
|
||||
| `src/Umbraco.PublishedCache.*` | Infrastructure |
|
||||
| `src/Umbraco.Examine.Lucene/` | Infrastructure |
|
||||
| `src/Umbraco.Cms.Persistence.*` | Infrastructure |
|
||||
| `src/Umbraco.Web.Common/` | Web |
|
||||
| `src/Umbraco.Web.UI/` | Web (Application) |
|
||||
| `src/Umbraco.Web.Website/` | Web |
|
||||
| `src/Umbraco.Cms.Api.Common/` | API |
|
||||
| `src/Umbraco.Cms.Api.Management/` | API |
|
||||
| `src/Umbraco.Cms.Api.Delivery/` | API |
|
||||
| `src/Umbraco.Web.UI.Client/` | Frontend |
|
||||
| `tests/` | Test |
|
||||
|
||||
### Violation Detection
|
||||
|
||||
Flag if a change introduces:
|
||||
|
||||
- **Core depending on Infrastructure**: Core file importing/referencing Infrastructure types
|
||||
- **Core depending on Web/API**: Core file importing/referencing Web or API types
|
||||
- **Infrastructure depending on Web/API**: Infrastructure file importing Web or API types
|
||||
- **Cross-API dependencies**: Management API depending on Delivery API or vice versa
|
||||
|
||||
### How to Check
|
||||
|
||||
1. For each changed file, identify its layer
|
||||
2. Read the file's `using` statements (C#) or `import` statements (TS)
|
||||
3. Check if any imports reference a higher layer
|
||||
4. Also check if new parameters or return types come from higher layers
|
||||
|
||||
---
|
||||
|
||||
## 4. Flag Cross-Project Risks
|
||||
|
||||
### High-Risk Patterns
|
||||
|
||||
These changes have high ripple potential:
|
||||
|
||||
- **Interface changes in Core** — all implementations in Infrastructure must be updated
|
||||
- **Notification type changes** — all handlers across the codebase are affected
|
||||
- **Base class changes** — all derived classes are affected
|
||||
- **Composer changes** — can affect DI container and runtime behavior globally
|
||||
- **Shared model/DTO changes** — can affect serialization, API contracts, and consumers
|
||||
|
||||
### What to Report
|
||||
|
||||
For each cross-project risk found, report:
|
||||
|
||||
1. **What changed**: The specific symbol and how it changed
|
||||
2. **Who is affected**: List of consuming files/projects found via Grep
|
||||
3. **Risk level**: Whether the consumers will break (compile error), behave differently (runtime), or are unaffected
|
||||
4. **Recommendation**: Whether the PR should include updates to affected consumers
|
||||
|
||||
---
|
||||
|
||||
## 5. Performance Notes
|
||||
|
||||
- Use `head_limit: 20` on all Grep searches to cap results
|
||||
- Only search for symbols that actually changed (not every symbol in the file)
|
||||
- For very common type names (e.g., `IScope`, `ILogger`), consider adding more context to the search pattern to reduce false positives
|
||||
- Skip impact analysis for test files — they don't have external consumers
|
||||
- Skip impact analysis for private/internal members — they can't have external consumers
|
||||
@@ -0,0 +1,64 @@
|
||||
name: Claude PR Review
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, ready_for_review]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
review:
|
||||
if: github.event.pull_request.draft == false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY_03 }}
|
||||
base_branch: "main"
|
||||
additional_permissions: "actions: read"
|
||||
claude_args: "--model claude-sonnet-4-6 --allowedTools 'Bash(gh:*),Bash(git:*)'"
|
||||
prompt: |
|
||||
You are reviewing pull request #${{ github.event.pull_request.number }}
|
||||
in the Umbraco CMS repository.
|
||||
|
||||
Read and execute the review procedure defined in `.claude/skills/umb-review/SKILL.md`.
|
||||
|
||||
For each finding that references a specific file and line:
|
||||
- Post an individual inline PR comment on that line.
|
||||
- Format: **[Severity]** explanation, then suggestion.
|
||||
|
||||
For the overall summary (header, impact, verdict):
|
||||
- Post ONE top-level PR comment.
|
||||
|
||||
Do NOT use sticky/updating comments — post new individual comments.
|
||||
|
||||
After reviewing, apply labels to the PR based on changed files:
|
||||
- `area/frontend` — if files under `src/Umbraco.Web.UI.Client/` are changed
|
||||
- `area/backend` — if .cs files outside the frontend client are changed
|
||||
- `area/test` — if only test files are changed
|
||||
- `category/api` — if Management API or Delivery API files are changed
|
||||
- `category/breaking` — if breaking changes were detected in the review
|
||||
- `category/localization` — if localization/language files are changed
|
||||
- `category/test-automation` — if only test files are changed
|
||||
- `category/refactor` — if the PR is pure refactoring with no new features
|
||||
- `category/performance` — if performance-related changes are detected
|
||||
- `category/ux` — if user-facing changes are detected
|
||||
- `category/ui` — if changes to the UI layer are detected
|
||||
|
||||
Only apply labels you are confident about. Never remove existing labels.
|
||||
|
||||
Be friendly and constructive. This project values community contributions.
|
||||
Frame feedback as suggestions where possible.
|
||||
Reserve firm language for genuine Critical issues only.
|
||||
|
||||
Run fully autonomously. Do NOT ask questions.
|
||||
Only review changed files. Do not flag pre-existing issues.
|
||||
Do not suggest changes that would themselves introduce breaking changes.
|
||||
@@ -0,0 +1,91 @@
|
||||
name: Claude
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened, assigned, labeled]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
claude:
|
||||
if: |
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY_03 }}
|
||||
assignee_trigger: "claude"
|
||||
label_trigger: "claude"
|
||||
base_branch: "main"
|
||||
additional_permissions: "actions: read"
|
||||
claude_args: "--model claude-sonnet-4-6 --max-turns 50 --allowedTools 'Bash(gh:*),Bash(git:*),Bash(npm:*),Bash(dotnet:*)'"
|
||||
prompt: |
|
||||
You are an AI assistant for the Umbraco CMS repository, an open-source
|
||||
.NET CMS that welcomes community contributions.
|
||||
|
||||
You were triggered on issue/PR #${{ github.event.issue.number || github.event.pull_request.number }}.
|
||||
|
||||
Read the user's message and do what they ask. The trigger phrase
|
||||
`@claude` is stripped before you see the message, so common requests
|
||||
will look like:
|
||||
|
||||
- `review` — Review PR #${{ github.event.issue.number || github.event.pull_request.number }}.
|
||||
Use `gh pr diff ${{ github.event.issue.number || github.event.pull_request.number }}`
|
||||
and `gh pr view ${{ github.event.issue.number || github.event.pull_request.number }}`
|
||||
to read the changes. Do NOT use git diff or the umb-review skill.
|
||||
Focus on bugs, breaking changes, and architectural concerns.
|
||||
Post inline comments for specific issues and a brief summary.
|
||||
- `help` or a general question — Answer based on the codebase.
|
||||
Read CLAUDE.md files for project structure and conventions.
|
||||
- `fix ...` — Implement the requested fix on a new branch.
|
||||
- `label` — Apply appropriate labels to the PR or issue.
|
||||
|
||||
If the message is empty or just whitespace, treat it as `review`
|
||||
when on a PR, or `help` when on an issue.
|
||||
|
||||
If none of these match, read the user's message carefully and respond
|
||||
to what they actually asked for.
|
||||
|
||||
## Labeling
|
||||
|
||||
When labeling PRs (based on changed files):
|
||||
- `area/frontend`, `area/backend`, `area/test`
|
||||
- `category/api`, `category/breaking`, `category/localization`
|
||||
- `category/refactor`, `category/performance`, `category/ux`, `category/ui`
|
||||
- `category/test-automation`
|
||||
|
||||
When labeling issues (based on content):
|
||||
- `area/frontend`, `area/backend`, `area/test`
|
||||
- `affected/v14` through `affected/v17`, `affected/backoffice`
|
||||
- `category/api`, `category/localization`, `category/performance`
|
||||
- `category/ux`, `category/ui`
|
||||
|
||||
Only apply labels you are confident about. Never remove existing labels.
|
||||
|
||||
## Tone
|
||||
|
||||
Be friendly and constructive. Frame feedback as suggestions.
|
||||
Reserve firm language for genuine critical issues only.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Run fully autonomously. Do NOT ask questions.
|
||||
- Do not suggest changes that would introduce breaking changes.
|
||||
@@ -198,7 +198,7 @@ Use the format: `Area: Description (closes #IssueID)`
|
||||
- Describe the change and its impact
|
||||
- Be specific, not vague (describe "a golden retriever" not just "a dog")
|
||||
|
||||
**Issue Linking**: Add `(closes #IssueID)` to auto-close linked issues on merge.
|
||||
**Issue Linking**: Add `(closes #IssueID)` to the title for readability, AND include a closing keyword on its own line in the PR body (e.g., `Fixes #IssueID`) so GitHub actually auto-links and auto-closes the issue on merge. GitHub only parses closing keywords (`closes`, `fixes`, `resolves`) from the PR body or commit messages — the title suffix is cosmetic and does **not** trigger auto-close on its own.
|
||||
|
||||
### Commit Messages
|
||||
|
||||
@@ -419,64 +419,19 @@ APIs use `Asp.Versioning.Mvc`:
|
||||
- Delivery API: `/umbraco/delivery/api/v{version}/*`
|
||||
- OpenAPI/Swagger docs per version
|
||||
|
||||
### Backoffice npm Package Structure
|
||||
### Updating `OpenApi.json` (Management API)
|
||||
|
||||
The backoffice (`Umbraco.Web.UI.Client`) is published to npm as **`@umbraco-cms/backoffice`** with a plugin architecture:
|
||||
When a PR changes Management API controllers or models, the `OpenApi.json` file in the Management API project must be updated:
|
||||
|
||||
#### Architecture Overview
|
||||
1. Run the Umbraco instance locally
|
||||
2. Open Swagger UI and navigate to the swagger.json link (e.g. `https://localhost:44339/umbraco/swagger/management/swagger.json`)
|
||||
3. Copy the full JSON content and paste it into `src/Umbraco.Cms.Api.Management/OpenApi.json`
|
||||
|
||||
- **Multi-workspace structure**: Subprojects in `src/libs/*`, `src/packages/*`, `src/external/*`
|
||||
- **Export model**: All exports defined in root `package.json` → `./exports` field
|
||||
- **Importmap-driven runtime**: Dependencies provided at runtime via importmap (single source of truth)
|
||||
- **Build-time types**: TypeScript types come from npm peerDependencies
|
||||
- **Plugin model**: Developers create plugins that import from `@umbraco-cms/backoffice/*` exports
|
||||
**Important**: Commit only the substantive changes — not IDE-applied formatting (whitespace, reordering, etc.). Extraneous formatting diffs make PRs harder to review and merge-ups more error-prone.
|
||||
|
||||
#### Dependency Hoisting Strategy
|
||||
### Backoffice npm Package
|
||||
|
||||
When building for npm (`npm pack`), the `cleanse-pkg.js` script hoists subproject dependencies to root `peerDependencies` with intelligent version range conversion:
|
||||
|
||||
**Version Range Logic** (uses `semver` package):
|
||||
|
||||
1. **Pre-release (0.x.y)**: Convert to explicit range
|
||||
- Input: `^0.85.0` or `0.85.0`
|
||||
- Output: `>=0.85.0 <1.0.0`
|
||||
- Rationale: Pre-release caret only allows patch updates, explicit range allows minor upgrades within 0.x.x
|
||||
- Example: Plugin can use `@hey-api/openapi-ts@0.91.1` while backoffice uses `0.85.0`
|
||||
|
||||
2. **Stable with caret (^X.Y.Z where X ≥ 1)**: Keep as-is
|
||||
- Input: `^3.3.1`
|
||||
- Output: `^3.3.1` (unchanged)
|
||||
- Rationale: Caret already implements correct semantics for stable versions
|
||||
|
||||
3. **Stable exact versions (X.Y.Z where X ≥ 1)**: Add caret
|
||||
- Input: `3.16.0`
|
||||
- Output: `^3.16.0`
|
||||
- Rationale: Normalizes to conventional semver format
|
||||
|
||||
#### Key Dependencies
|
||||
|
||||
**Runtime via importmap** (types available from peerDependencies):
|
||||
- `lit`, `rxjs`, `@umbraco-ui/uui` - Core framework
|
||||
- `monaco-editor`, `@tiptap/*` - Feature-specific editors
|
||||
- `@hey-api/openapi-ts` - HTTP client type generation
|
||||
|
||||
**Build-time only** (not hoisted):
|
||||
- `vite`, `typescript`, `eslint` - Dev tooling
|
||||
|
||||
#### Plugin Development Implications
|
||||
|
||||
Plugin developers should:
|
||||
- **Declare explicit dependencies** in their own `package.json` (avoid relying on transitive deps)
|
||||
- **Understand the version ranges**: `>=0.85.0 <1.0.0` means they can use newer pre-release versions
|
||||
- **Know that types match npm ranges**, but runtime comes from importmap (managed by backoffice)
|
||||
- **When `@hey-api` hits 1.0.0**: Published constraint will automatically become `^1.0.0`
|
||||
|
||||
#### Implementation Details
|
||||
|
||||
- Script location: `src/Umbraco.Web.UI.Client/devops/publish/cleanse-pkg.js`
|
||||
- Runs as `prepack` hook before npm pack
|
||||
- Uses `semver.minVersion()` for robust version range parsing
|
||||
- Generates single source of truth for importmap versions
|
||||
The backoffice is published to npm as `@umbraco-cms/backoffice`. Runtime dependencies are provided via importmap; npm peerDependencies provide types only. For full details on dependency hoisting, version range logic, and plugin development, see `/src/Umbraco.Web.UI.Client/CLAUDE.md` → "npm Package Publishing".
|
||||
|
||||
### Known Limitations
|
||||
|
||||
@@ -486,6 +441,68 @@ Plugin developers should:
|
||||
|
||||
---
|
||||
|
||||
## 7. CI/CD — Claude AI Assistant
|
||||
|
||||
Two GitHub Actions workflows powered by `anthropics/claude-code-action@v1`. Advisory only — does not block merging.
|
||||
|
||||
### Workflows
|
||||
|
||||
| File | Trigger | Purpose |
|
||||
|------|---------|---------|
|
||||
| `claude-review.yml` | `pull_request: [opened, ready_for_review]` | Auto-review every non-draft PR using the `umb-review` skill |
|
||||
| `claude.yml` | `@claude` comments, issue assign/label | Interactive assistant for PRs and issues |
|
||||
|
||||
### Auto-Review (`claude-review.yml`)
|
||||
|
||||
Runs the full `.claude/skills/umb-review/SKILL.md` procedure on every newly opened or un-drafted PR. Produces inline comments per finding and one summary comment with a verdict. Skips draft PRs. No turn limit.
|
||||
|
||||
### Interactive (`claude.yml`)
|
||||
|
||||
Responds to `@claude` mentions on PRs and issues. The trigger phrase is stripped before Claude sees the message, so:
|
||||
|
||||
- `@claude review` → light review using `gh pr diff` (not the umb-review skill)
|
||||
- `@claude fix ...` → implements a fix on a new branch
|
||||
- `@claude help` → answers questions about the codebase
|
||||
- `@claude label` → applies labels
|
||||
- `@claude` (empty) → defaults to `review` on PRs, `help` on issues
|
||||
|
||||
Also triggers on issue assignment to `claude` or adding the `claude` label. Gated: only runs when `@claude` appears in the comment/issue body. Max 25 turns.
|
||||
|
||||
**Allowed Bash tools**: `gh`, `git`, `npm`, `dotnet` (interactive only; auto-review allows `gh` and `git`).
|
||||
|
||||
### Labels
|
||||
|
||||
Both workflows apply labels based on content:
|
||||
|
||||
**On PRs** (based on changed files):
|
||||
|
||||
| Label | Condition |
|
||||
|-------|-----------|
|
||||
| `area/frontend` | Files under `src/Umbraco.Web.UI.Client/` |
|
||||
| `area/backend` | `.cs` files outside the frontend client |
|
||||
| `area/test` | Only test files changed |
|
||||
| `category/api` | Management or Delivery API files |
|
||||
| `category/breaking` | Breaking changes detected |
|
||||
| `category/localization` | Localization/language files |
|
||||
| `category/test-automation` | Only test files changed |
|
||||
| `category/refactor` | Pure refactoring, no new features |
|
||||
| `category/performance` | Performance-related changes |
|
||||
| `category/ux` | User-facing changes |
|
||||
| `category/ui` | UI layer changes |
|
||||
|
||||
**On Issues** (based on content): same `area/*` and `category/*` labels, plus `affected/v14` through `affected/v17` and `affected/backoffice`.
|
||||
|
||||
Labels are only added, never removed. Claude applies only labels it is confident about.
|
||||
|
||||
### Key Implementation Notes
|
||||
|
||||
- **Checkout required** — the action internally runs `git fetch origin main` for trusted file restoration. Without `actions/checkout`, it fails with `fatal: not a git repository`.
|
||||
- **`id-token: write` permission** — required for OIDC token exchange with the Claude GitHub App.
|
||||
- **Trigger phrase stripping** — the action strips `@claude` from comments before passing to Claude. Prompts must reference commands without the prefix (e.g., `review` not `@claude review`).
|
||||
- **PR number injection** — the interactive workflow injects the PR/issue number into the prompt via `${{ github.event.issue.number }}` since Claude can't discover it from `gh pr view` when checked out on `main`.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Essential Commands
|
||||
@@ -507,6 +524,16 @@ dotnet format
|
||||
dotnet pack -c Release
|
||||
```
|
||||
|
||||
### Integration Test Database Configuration
|
||||
|
||||
Integration tests are configured in `tests/Umbraco.Tests.Integration/appsettings.Tests.json`.
|
||||
|
||||
The `Tests:Database:DatabaseType` setting controls which database is used:
|
||||
- `"SQLite"` (default) - No external dependencies
|
||||
- `"LocalDb"` - Uses SQL Server LocalDB, required for SQL Server-specific tests (e.g., page-level locking, `sys.dm_tran_locks`)
|
||||
|
||||
SQL Server-specific tests use `BaseTestDatabase.IsSqlite()` to skip when running on SQLite.
|
||||
|
||||
### Key Projects
|
||||
|
||||
| Project | Type | Description |
|
||||
|
||||
@@ -89,4 +89,4 @@
|
||||
<!-- TODO (V19): Remove these pinned dependencies when the Markdown dependency is removed. -->
|
||||
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -614,7 +614,6 @@ stages:
|
||||
UMBRACO__CMS__GLOBAL__VERSIONCHECKPERIOD: 0
|
||||
UMBRACO__CMS__GLOBAL__USEHTTPS: true
|
||||
UMBRACO__CMS__HEALTHCHECKS__NOTIFICATION__ENABLED: false
|
||||
UMBRACO__CMS__KEEPALIVE__DISABLEKEEPALIVETASK: true
|
||||
UMBRACO__CMS__WEBROUTING__UMBRACOAPPLICATIONURL: https://localhost:44331/
|
||||
ASPNETCORE_URLS: https://localhost:44331
|
||||
jobs:
|
||||
|
||||
@@ -4,12 +4,10 @@ pr: none
|
||||
trigger: none
|
||||
|
||||
schedules:
|
||||
- cron: '0 0 * * *'
|
||||
displayName: Daily midnight build
|
||||
- cron: '0 3 * * *'
|
||||
displayName: Daily 3AM build (main)
|
||||
branches:
|
||||
include:
|
||||
- v15/dev
|
||||
- v16/dev
|
||||
- main
|
||||
|
||||
parameters:
|
||||
@@ -321,7 +319,8 @@ stages:
|
||||
|
||||
- stage: DefaultConfigE2E
|
||||
displayName: Default Config E2E Tests
|
||||
dependsOn: Build
|
||||
dependsOn: Integration
|
||||
condition: always()
|
||||
variables:
|
||||
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
||||
# Enable console logging in Release mode
|
||||
@@ -340,7 +339,6 @@ stages:
|
||||
UMBRACO__CMS__GLOBAL__VERSIONCHECKPERIOD: 0
|
||||
UMBRACO__CMS__GLOBAL__USEHTTPS: true
|
||||
UMBRACO__CMS__HEALTHCHECKS__NOTIFICATION__ENABLED: false
|
||||
UMBRACO__CMS__KEEPALIVE__DISABLEKEEPALIVETASK: true
|
||||
UMBRACO__CMS__WEBROUTING__UMBRACOAPPLICATIONURL: https://localhost:44331/
|
||||
ASPNETCORE_URLS: https://localhost:44331
|
||||
jobs:
|
||||
@@ -502,7 +500,8 @@ stages:
|
||||
|
||||
- stage: AdditionalConfigE2E
|
||||
displayName: Additional Config E2E Tests
|
||||
dependsOn: Build
|
||||
dependsOn: DefaultConfigE2E
|
||||
condition: always()
|
||||
variables:
|
||||
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
||||
ASPNETCORE_URLS: https://localhost:44331
|
||||
|
||||
@@ -10,6 +10,7 @@ schedules:
|
||||
include:
|
||||
- v13/dev
|
||||
- v16/dev
|
||||
- v18/dev
|
||||
- main
|
||||
|
||||
steps:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using OpenIddict.Abstractions;
|
||||
using OpenIddict.Server;
|
||||
@@ -41,6 +43,7 @@ internal sealed class HideBackOfficeTokensHandler
|
||||
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IDataProtectionProvider _dataProtectionProvider;
|
||||
private readonly ILogger<HideBackOfficeTokensHandler> _logger;
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
private readonly BackOfficeTokenCookieSettings _backOfficeTokenCookieSettings;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
@@ -51,11 +54,13 @@ internal sealed class HideBackOfficeTokensHandler
|
||||
/// </summary>
|
||||
/// <param name="httpContextAccessor">The HTTP context accessor.</param>
|
||||
/// <param name="dataProtectionProvider">The data protection provider for encrypting cookie values.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="backOfficeTokenCookieSettings">The back-office token cookie settings.</param>
|
||||
/// <param name="globalSettings">The global settings.</param>
|
||||
public HideBackOfficeTokensHandler(
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILogger<HideBackOfficeTokensHandler> logger,
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
IOptions<BackOfficeTokenCookieSettings> backOfficeTokenCookieSettings,
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
@@ -63,6 +68,7 @@ internal sealed class HideBackOfficeTokensHandler
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_dataProtectionProvider = dataProtectionProvider;
|
||||
_logger = logger;
|
||||
_backOfficeTokenCookieSettings = backOfficeTokenCookieSettings.Value;
|
||||
_globalSettings = globalSettings.Value;
|
||||
|
||||
@@ -291,8 +297,19 @@ internal sealed class HideBackOfficeTokensHandler
|
||||
var key = GetCookieKey(httpContext, cookieName);
|
||||
if (httpContext.Request.Cookies.TryGetValue(key, out var cookieValue))
|
||||
{
|
||||
value = EncryptionHelper.Decrypt(cookieValue, _dataProtectionProvider);
|
||||
return true;
|
||||
try
|
||||
{
|
||||
value = EncryptionHelper.Decrypt(cookieValue, _dataProtectionProvider);
|
||||
return true;
|
||||
}
|
||||
catch (CryptographicException ex)
|
||||
{
|
||||
// Decryption can fail if the data protection key ring has changed
|
||||
// (e.g., after deployment, app pool recycle, or slot swap).
|
||||
// Treat this as a missing cookie — the user will need to re-authenticate.
|
||||
_logger.LogWarning(ex, "Failed to decrypt back-office token cookie '{CookieName}'. The user will need to re-authenticate.", cookieName);
|
||||
RemoveCookie(httpContext, cookieName);
|
||||
}
|
||||
}
|
||||
|
||||
value = null;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using Umbraco.Cms.Core.DeliveryApi;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.Examine;
|
||||
|
||||
namespace Umbraco.Cms.Api.Delivery.Indexing.Selectors;
|
||||
|
||||
public sealed class AncestorsSelectorIndexer : IContentIndexHandler
|
||||
{
|
||||
// NOTE: "id" is a reserved field name
|
||||
internal const string FieldName = "itemId";
|
||||
internal const string FieldName = UmbracoExamineFieldNames.DeliveryApiContentIndex.ItemId;
|
||||
|
||||
public IEnumerable<IndexFieldValue> GetFieldValues(IContent content, string? culture)
|
||||
=> new[] { new IndexFieldValue { FieldName = FieldName, Values = new object[] { content.Key } } };
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Cms.Api.Delivery.Services;
|
||||
/// </summary>
|
||||
internal sealed class ApiContentQueryProvider : IApiContentQueryProvider
|
||||
{
|
||||
private const string ItemIdFieldName = "itemId";
|
||||
private const string ItemIdFieldName = UmbracoExamineFieldNames.DeliveryApiContentIndex.ItemId;
|
||||
private readonly IExamineManager _examineManager;
|
||||
private readonly ILogger<ApiContentQueryProvider> _logger;
|
||||
private readonly ApiContentQuerySelectorBuilder _selectorBuilder;
|
||||
|
||||
@@ -26,7 +26,8 @@ RESTful API for Umbraco backoffice operations. Manages content, media, users, an
|
||||
- **Validation**: FluentValidation via base controllers
|
||||
- **Serialization**: System.Text.Json with custom converters
|
||||
- **Mapping**: Manual presentation factories (no AutoMapper)
|
||||
- **Patching**: JsonPatch.Net for PATCH operations
|
||||
- **Patching**: Custom patch engine for PATCH operations (Umbraco.Cms.Api.Management.Patching)
|
||||
- ⚠️ Legacy JsonPatch.Net support (IJsonPatchService) still available but **obsolete** - scheduled for removal in v19
|
||||
- **Real-time**: SignalR hubs (`BackofficeHub`, `ServerEventHub`)
|
||||
- **DI**: Microsoft.Extensions.DependencyInjection via `ManagementApiComposer`
|
||||
|
||||
@@ -70,7 +71,6 @@ src/Umbraco.Cms.Api.Management/
|
||||
- **Umbraco.Cms.Api.Common** - Shared API infrastructure (base controllers, OpenAPI config)
|
||||
- **Umbraco.Infrastructure** - Service implementations, data access
|
||||
- **Umbraco.PublishedCache.HybridCache** - Published content queries
|
||||
- **JsonPatch.Net** - JSON Patch (RFC 6902) support
|
||||
- **Swashbuckle.AspNetCore** - OpenAPI generation
|
||||
|
||||
### Design Patterns
|
||||
|
||||
+6
-1
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Api.Management.Security;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
@@ -13,6 +13,11 @@ public class ConfigureBackOfficeSecurityStampValidatorOptions : IConfigureOption
|
||||
private readonly SecuritySettings _securitySettings;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigureBackOfficeSecurityStampValidatorOptions"/> class with the specified security settings and time provider.
|
||||
/// </summary>
|
||||
/// <param name="securitySettings">The <see cref="IOptions{SecuritySettings}"/> used to access security-related configuration options.</param>
|
||||
/// <param name="timeProvider">The <see cref="TimeProvider"/> used for time-based operations.</param>
|
||||
public ConfigureBackOfficeSecurityStampValidatorOptions(IOptions<SecuritySettings> securitySettings, TimeProvider timeProvider)
|
||||
{
|
||||
_timeProvider = timeProvider;
|
||||
|
||||
+15
@@ -9,15 +9,30 @@ using Umbraco.Cms.Api.Management.OpenApi;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Provides configuration for Swagger generation options specific to the Umbraco Management API.
|
||||
/// This class is used to customize the Swagger documentation for the API endpoints.
|
||||
/// </summary>
|
||||
public class ConfigureUmbracoManagementApiSwaggerGenOptions : IConfigureOptions<SwaggerGenOptions>
|
||||
{
|
||||
private readonly IUmbracoJsonTypeInfoResolver _umbracoJsonTypeInfoResolver;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigureUmbracoManagementApiSwaggerGenOptions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="umbracoJsonTypeInfoResolver">An instance of <see cref="IUmbracoJsonTypeInfoResolver"/> used to resolve JSON type information for Umbraco.</param>
|
||||
public ConfigureUmbracoManagementApiSwaggerGenOptions(IUmbracoJsonTypeInfoResolver umbracoJsonTypeInfoResolver)
|
||||
{
|
||||
_umbracoJsonTypeInfoResolver = umbracoJsonTypeInfoResolver;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the <see cref="SwaggerGenOptions"/> for the Umbraco Management API.
|
||||
/// Sets up the Swagger documentation, including API metadata, security definitions for OAuth2 authentication,
|
||||
/// operation filters for response headers and security requirements, and schema filters for non-nullable properties.
|
||||
/// Also configures polymorphism handling and discriminator properties for OpenAPI schemas.
|
||||
/// </summary>
|
||||
/// <param name="swaggerGenOptions">The <see cref="SwaggerGenOptions"/> instance to configure for the Management API.</param>
|
||||
public void Configure(SwaggerGenOptions swaggerGenOptions)
|
||||
{
|
||||
swaggerGenOptions.SwaggerDoc(
|
||||
|
||||
@@ -7,6 +7,9 @@ using Umbraco.Cms.Core.Hosting;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management;
|
||||
|
||||
/// <summary>
|
||||
/// Provides endpoints for managing back office user authentication and login operations.
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
[Route(LoginPath)]
|
||||
public class BackOfficeLoginController : Controller
|
||||
@@ -15,6 +18,11 @@ public class BackOfficeLoginController : Controller
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BackOfficeLoginController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="globalSettings">A snapshot of the application's global settings options.</param>
|
||||
/// <param name="hostingEnvironment">The current hosting environment for the application.</param>
|
||||
public BackOfficeLoginController(
|
||||
IOptionsSnapshot<GlobalSettings> globalSettings,
|
||||
IHostingEnvironment hostingEnvironment)
|
||||
@@ -24,6 +32,16 @@ public class BackOfficeLoginController : Controller
|
||||
}
|
||||
|
||||
// GET
|
||||
/// <summary>
|
||||
/// Handles the GET request for the back office login page.
|
||||
/// If the user is already authenticated, updates the model accordingly.
|
||||
/// Ensures the return URL is a relative path and sets default values if necessary.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A cancellation token to cancel the operation.</param>
|
||||
/// <param name="model">The model containing login information and the return URL.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> that renders the login view with the model, or a bad request result if the return URL is invalid.
|
||||
/// </returns>
|
||||
public async Task<IActionResult> Index(CancellationToken cancellationToken, BackOfficeLoginModel model)
|
||||
{
|
||||
AuthenticateResult cookieAuthResult = await HttpContext.AuthenticateAsync(Constants.Security.BackOfficeAuthenticationType);
|
||||
|
||||
@@ -2,6 +2,9 @@ using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a model containing the credentials required for logging into the Umbraco back office.
|
||||
/// </summary>
|
||||
[BindProperties]
|
||||
public class BackOfficeLoginModel
|
||||
{
|
||||
@@ -16,5 +19,8 @@ public class BackOfficeLoginModel
|
||||
/// </summary>
|
||||
public string? UmbracoUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the user is already logged in to the back office.
|
||||
/// </summary>
|
||||
public bool UserIsAlreadyLoggedIn { get; set; }
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Content;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a base controller for managing collections of content items, providing shared functionality for handling content collections and their variants.
|
||||
/// </summary>
|
||||
/// <typeparam name="TContent">The content entity type.</typeparam>
|
||||
/// <typeparam name="TCollectionResponseModel">The response model type for the content collection.</typeparam>
|
||||
/// <typeparam name="TValueResponseModelBase">The base type for value response models within the collection.</typeparam>
|
||||
/// <typeparam name="TVariantResponseModel">The response model type for content variants.</typeparam>
|
||||
public abstract class ContentCollectionControllerBase<TContent, TCollectionResponseModel, TValueResponseModelBase, TVariantResponseModel> : ManagementApiControllerBase
|
||||
where TContent : class, IContentBase
|
||||
where TCollectionResponseModel : ContentResponseModelBase<TValueResponseModelBase, TVariantResponseModel>
|
||||
|
||||
@@ -8,6 +8,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Content;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for content management operations in the Umbraco CMS API, providing shared functionality for content-related controllers.
|
||||
/// </summary>
|
||||
public abstract class ContentControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected IActionResult ContentEditingOperationStatusResult(ContentEditingOperationStatus status)
|
||||
@@ -53,6 +56,15 @@ public abstract class ContentControllerBase : ManagementApiControllerBase
|
||||
ContentEditingOperationStatus.PropertyTypeNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("One or more property types could not be found")
|
||||
.Build()),
|
||||
ContentEditingOperationStatus.PropertyTypeCultureVarianceMismatch => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Property type culture variance mismatch")
|
||||
.WithDetail("One or more property values specify a culture for an invariant property, or are missing a culture for a culture-variant property. "
|
||||
+ "This can happen when a property is inherited from a variant composition on an invariant content type, which downgrades it to invariant.")
|
||||
.Build()),
|
||||
ContentEditingOperationStatus.PropertyTypeSegmentVarianceMismatch => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Property type segment variance mismatch")
|
||||
.WithDetail("One or more property values have a segment that does not match the property type's segment variance.")
|
||||
.Build()),
|
||||
ContentEditingOperationStatus.InTrash => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Content is in the recycle bin")
|
||||
.WithDetail("Could not perform the operation because the targeted content was in the recycle bin.")
|
||||
|
||||
@@ -9,18 +9,33 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Culture;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving and managing culture information in the system.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AllCultureController : CultureControllerBase
|
||||
{
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
private readonly ICultureService _cultureService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AllCultureController"/> class with the specified Umbraco mapper and culture service.
|
||||
/// </summary>
|
||||
/// <param name="umbracoMapper">An instance of <see cref="IUmbracoMapper"/> used for mapping Umbraco objects.</param>
|
||||
/// <param name="cultureService">An instance of <see cref="ICultureService"/> used for managing culture information.</param>
|
||||
public AllCultureController(IUmbracoMapper umbracoMapper, ICultureService cultureService)
|
||||
{
|
||||
_umbracoMapper = umbracoMapper;
|
||||
_cultureService = cultureService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of all available cultures, including their English and localized names.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of cultures to skip before starting to collect the result set.</param>
|
||||
/// <param name="take">The maximum number of cultures to return.</param>
|
||||
/// <returns>A task representing the asynchronous operation. The task result contains a <see cref="PagedViewModel{CultureReponseModel}"/> with the paginated cultures.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<CultureReponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Culture;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for API endpoints that manage culture-related operations in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute("culture")]
|
||||
[ApiExplorerSettings(GroupName = "Culture")]
|
||||
public abstract class CultureControllerBase : ManagementApiControllerBase
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for retrieving multiple data type value schemas in a single request.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class BatchSchemasDataTypeController : DataTypeControllerBase
|
||||
{
|
||||
private readonly IPropertyEditorSchemaService _schemaService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BatchSchemasDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="schemaService">The property editor schema service.</param>
|
||||
public BatchSchemasDataTypeController(IPropertyEditorSchemaService schemaService)
|
||||
=> _schemaService = schemaService;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value schemas for multiple data types.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A cancellation token.</param>
|
||||
/// <param name="ids">The unique identifiers of the data types.</param>
|
||||
/// <returns>The schema information for the requested data types.</returns>
|
||||
/// <remarks>
|
||||
/// Returns schema information for property editors that implement <c>IValueSchemaProvider</c>.
|
||||
/// Each item includes an error field if the schema could not be retrieved (e.g., data type not found or schema not supported).
|
||||
/// </remarks>
|
||||
[HttpGet("schemas/batch")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(FetchResponseModel<DataTypeSchemaItemResponseModel>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetSchemas(
|
||||
CancellationToken cancellationToken,
|
||||
[FromQuery(Name = "id")] Guid[] ids)
|
||||
{
|
||||
Guid[] requestedIds = [.. ids.Distinct()];
|
||||
|
||||
if (requestedIds.Length == 0)
|
||||
{
|
||||
return Ok(new FetchResponseModel<DataTypeSchemaItemResponseModel>());
|
||||
}
|
||||
|
||||
var items = new List<DataTypeSchemaItemResponseModel>();
|
||||
|
||||
foreach (Guid id in requestedIds)
|
||||
{
|
||||
Attempt<PropertyValueSchema, PropertyEditorSchemaOperationStatus> attempt = await _schemaService.GetSchemaAsync(id);
|
||||
items.Add(new DataTypeSchemaItemResponseModel
|
||||
{
|
||||
Id = id,
|
||||
ValueTypeName = attempt.Success ? attempt.Result.ValueType?.FullName : null,
|
||||
JsonSchema = attempt.Success ? attempt.Result.JsonSchema : null,
|
||||
Error = attempt.Success ? null : attempt.Status.ToString(),
|
||||
});
|
||||
}
|
||||
|
||||
return Ok(new FetchResponseModel<DataTypeSchemaItemResponseModel>
|
||||
{
|
||||
Total = items.Count,
|
||||
Items = items,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8,18 +8,34 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing data types by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyDataTypeController : DataTypeControllerBase
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ByKeyDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">Service used for managing and retrieving data types.</param>
|
||||
/// <param name="umbracoMapper">The mapper used to map between Umbraco domain models and API models.</param>
|
||||
public ByKeyDataTypeController(IDataTypeService dataTypeService, IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a data type by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the data type to retrieve.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing the data type if found; otherwise, a 404 Not Found result.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(DataTypeResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+12
@@ -8,13 +8,25 @@ using Umbraco.Cms.Core.Configuration.Models;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for managing configuration for data types in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ConfigurationDataTypeController : DataTypeControllerBase
|
||||
{
|
||||
private readonly DataTypesSettings _dataTypesSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigurationDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataTypesSettings">An <see cref="IOptionsSnapshot{T}"/> containing the <see cref="DataTypesSettings"/> configuration options.</param>
|
||||
public ConfigurationDataTypeController(IOptionsSnapshot<DataTypesSettings> dataTypesSettings) => _dataTypesSettings = dataTypesSettings.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the configuration settings for data types, including whether data types can be changed and the identifiers for document and media list views.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing a <see cref="DatatypeConfigurationResponseModel"/> with the data type configuration settings.</returns>
|
||||
[HttpGet("configuration")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(DatatypeConfigurationResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -12,6 +12,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to copy data types within the Umbraco CMS management interface.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)]
|
||||
public class CopyDataTypeController : DataTypeControllerBase
|
||||
@@ -19,12 +22,26 @@ public class CopyDataTypeController : DataTypeControllerBase
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CopyDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">An instance of <see cref="IDataTypeService"/> used to manage data types.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">An instance of <see cref="IBackOfficeSecurityAccessor"/> used to access back office security information.</param>
|
||||
public CopyDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the specified data type.
|
||||
/// The new data type will have a unique Id and its name will have " (copy)" appended.
|
||||
/// Optionally, the copy can be placed in a specified container if a target container Id is provided.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the data type to copy.</param>
|
||||
/// <param name="copyDataTypeRequestModel">The request model containing copy options, such as the target container Id.</param>
|
||||
/// <returns>A result indicating the outcome of the copy operation.</returns>
|
||||
[HttpPost("{id:guid}/copy")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
@@ -13,6 +13,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to create new data types in Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)]
|
||||
public class CreateDataTypeController : DataTypeControllerBase
|
||||
@@ -21,6 +24,12 @@ public class CreateDataTypeController : DataTypeControllerBase
|
||||
private readonly IDataTypePresentationFactory _dataTypePresentationFactory;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreateDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">The <see cref="IDataTypeService"/> used to manage data types.</param>
|
||||
/// <param name="dataTypePresentationFactory">The <see cref="IDataTypePresentationFactory"/> used to create data type presentation models.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">The <see cref="IBackOfficeSecurityAccessor"/> used to access back office security information.</param>
|
||||
public CreateDataTypeController(IDataTypeService dataTypeService, IDataTypePresentationFactory dataTypePresentationFactory, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
@@ -28,6 +37,14 @@ public class CreateDataTypeController : DataTypeControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new data type using the configuration provided in the request model.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="createDataTypeRequestModel">The model containing the configuration details for the new data type.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> that represents the result of the create operation. Returns <c>201 Created</c> on success, or an appropriate error response on failure.
|
||||
/// </returns>
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.Builders;
|
||||
@@ -9,6 +9,10 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for managing data types in the Umbraco CMS API.
|
||||
/// This class is intended to be inherited by controllers that handle data type operations.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.DataType)]
|
||||
[ApiExplorerSettings(GroupName = "Data Type")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrMediaOrMembersOrContentTypes)]
|
||||
@@ -55,6 +59,21 @@ public abstract class DataTypeControllerBase : ManagementApiControllerBase
|
||||
|
||||
protected IActionResult DataTypeNotFound() => OperationStatusResult(DataTypeOperationStatus.NotFound, DataTypeNotFound);
|
||||
|
||||
protected IActionResult PropertyEditorSchemaOperationStatusResult(PropertyEditorSchemaOperationStatus status) =>
|
||||
OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
PropertyEditorSchemaOperationStatus.DataTypeNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("The data type could not be found")
|
||||
.Build()),
|
||||
PropertyEditorSchemaOperationStatus.SchemaNotSupported => NotFound(problemDetailsBuilder
|
||||
.WithTitle("Schema not supported")
|
||||
.WithDetail("The property editor for this data type does not support schema information.")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
|
||||
.WithTitle("Unknown property editor schema operation status.")
|
||||
.Build()),
|
||||
});
|
||||
|
||||
private IActionResult DataTypeNotFound(ProblemDetailsBuilder problemDetailsBuilder)
|
||||
=> NotFound(problemDetailsBuilder
|
||||
.WithTitle("The data type could not be found")
|
||||
|
||||
@@ -11,6 +11,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to delete data types in the system.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)]
|
||||
public class DeleteDataTypeController : DataTypeControllerBase
|
||||
@@ -18,12 +21,23 @@ public class DeleteDataTypeController : DataTypeControllerBase
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">Service used to manage and delete data types.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context and authentication.</param>
|
||||
public DeleteDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a data type identified by the provided Id.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
|
||||
/// <param name="id">The unique identifier of the data type to delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the result of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+5
-1
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -6,6 +6,10 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Filter;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for implementing data type filtering operations in the API.
|
||||
/// Provides common functionality for derived controllers handling data type filters.
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Data Type")]
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Filter}/{Constants.UdiEntityType.DataType}")]
|
||||
// This auth policy might become problematic, as when getting DataTypes on Media types, you don't need access to the document tree.
|
||||
|
||||
+18
@@ -11,18 +11,36 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Filter;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling operations related to filters on data types in the management API.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class FilterDataTypeFilterController : DataTypeFilterControllerBase
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.DataType.Filter.FilterDataTypeFilterController"/> class, responsible for filtering data types.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">The <see cref="IDataTypeService"/> used to manage data types.</param>
|
||||
/// <param name="mapper">The <see cref="IUmbracoMapper"/> used for mapping entities.</param>
|
||||
public FilterDataTypeFilterController(IDataTypeService dataTypeService, IUmbracoMapper mapper)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated and filtered list of data types based on the specified criteria.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to observe while waiting for the task to complete.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set (used for pagination).</param>
|
||||
/// <param name="take">The maximum number of items to return (used for pagination).</param>
|
||||
/// <param name="name">An optional filter to match data type names.</param>
|
||||
/// <param name="editorUiAlias">An optional filter to match the editor UI alias.</param>
|
||||
/// <param name="editorAlias">An optional filter to match the editor alias.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains an <see cref="IActionResult"/> with a paged collection of filtered data types.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DataTypeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+16
@@ -7,9 +7,17 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing data type folders by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for <see cref="Umbraco.Cms.Api.Management.Controllers.DataType.Folder.ByKeyDataTypeFolderController"/>.
|
||||
/// </summary>
|
||||
/// <param name="backOfficeSecurityAccessor">Provides access to back office security features.</param>
|
||||
/// <param name="dataTypeContainerService">Service for managing data type containers.</param>
|
||||
public ByKeyDataTypeFolderController(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IDataTypeContainerService dataTypeContainerService)
|
||||
@@ -17,6 +25,14 @@ public class ByKeyDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a data type folder by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the data type folder to retrieve.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing a <see cref="FolderResponseModel"/> with the folder data if found; otherwise, a <see cref="ProblemDetails"/> with status 404 if not found.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(FolderResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+14
@@ -7,9 +7,17 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for creating folders used to organize data types in the system.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CreateDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreateDataTypeFolderController"/> class, responsible for handling requests related to creating data type folders.
|
||||
/// </summary>
|
||||
/// <param name="backOfficeSecurityAccessor">Provides access to back office security features for authorization and authentication.</param>
|
||||
/// <param name="dataTypeContainerService">Service used to manage data type containers (folders) within the system.</param>
|
||||
public CreateDataTypeFolderController(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IDataTypeContainerService dataTypeContainerService)
|
||||
@@ -17,6 +25,12 @@ public class CreateDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new data type folder using the specified details.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="createFolderRequestModel">The request model containing the folder name and parent location.</param>
|
||||
/// <returns>A <see cref="Task{IActionResult}"/> representing the asynchronous operation result.</returns>
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -9,6 +9,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for operations related to data type folders in the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DataType}/folder")]
|
||||
[ApiExplorerSettings(GroupName = "Data Type")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
|
||||
|
||||
+14
@@ -6,9 +6,17 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling requests to delete data type folders in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteDataTypeFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security operations.</param>
|
||||
/// <param name="dataTypeContainerService">Service for managing data type containers (folders).</param>
|
||||
public DeleteDataTypeFolderController(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IDataTypeContainerService dataTypeContainerService)
|
||||
@@ -16,6 +24,12 @@ public class DeleteDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a data type folder identified by the provided Id.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
|
||||
/// <param name="id">The unique identifier of the data type folder to delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+8
@@ -7,9 +7,17 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to update data type folders in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdateDataTypeFolderController : DataTypeFolderControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateDataTypeFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context and authentication.</param>
|
||||
/// <param name="dataTypeContainerService">Service used to manage data type folders (containers).</param>
|
||||
public UpdateDataTypeFolderController(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IDataTypeContainerService dataTypeContainerService)
|
||||
|
||||
@@ -7,6 +7,9 @@ using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for checking whether a data type is currently in use.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class IsUsedDataTypeController : DataTypeControllerBase
|
||||
{
|
||||
@@ -17,6 +20,14 @@ public class IsUsedDataTypeController : DataTypeControllerBase
|
||||
_dataTypeUsageService = dataTypeUsageService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the data type specified by the given <paramref name="id"/> is currently used in any content, media, or member types.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the data type to check for usage.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing a boolean value: <c>true</c> if the data type is used; <c>false</c> otherwise. Returns <see cref="StatusCodes.Status404NotFound"/> if the data type does not exist.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}/is-used")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
|
||||
|
||||
+4
-1
@@ -1,9 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for operations related to data type items in the management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.DataType}")]
|
||||
[ApiExplorerSettings(GroupName = "Data Type")]
|
||||
public class DatatypeItemControllerBase : ManagementApiControllerBase
|
||||
|
||||
@@ -8,12 +8,20 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for managing individual data type items within the Umbraco CMS management interface.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ItemDatatypeItemController : DatatypeItemControllerBase
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemDatatypeItemController"/> class, which manages item-level operations for data types in the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">Service used to manage and retrieve data type information.</param>
|
||||
/// <param name="mapper">The Umbraco mapper used for mapping between domain and API models.</param>
|
||||
public ItemDatatypeItemController(IDataTypeService dataTypeService, IUmbracoMapper mapper)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
|
||||
+17
@@ -9,6 +9,9 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling search operations for data type items in the management API.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class SearchDataTypeItemController : DatatypeItemControllerBase
|
||||
{
|
||||
@@ -16,6 +19,12 @@ public class SearchDataTypeItemController : DatatypeItemControllerBase
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SearchDataTypeItemController"/> class, which handles search operations for data type items.
|
||||
/// </summary>
|
||||
/// <param name="entitySearchService">Service used to perform entity search operations.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types.</param>
|
||||
/// <param name="mapper">The mapper used to convert between domain and API models.</param>
|
||||
public SearchDataTypeItemController(IEntitySearchService entitySearchService, IDataTypeService dataTypeService, IUmbracoMapper mapper)
|
||||
{
|
||||
_entitySearchService = entitySearchService;
|
||||
@@ -23,6 +32,14 @@ public class SearchDataTypeItemController : DatatypeItemControllerBase
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for data type items matching the specified query, with support for pagination.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="query">The search query used to filter data type items.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set (used for pagination).</param>
|
||||
/// <param name="take">The maximum number of items to return in the result set (used for pagination).</param>
|
||||
/// <returns>A task representing the asynchronous operation. The task result contains an <see cref="IActionResult"/> with a <see cref="PagedModel{DataTypeItemResponseModel}"/> containing the search results.</returns>
|
||||
[HttpGet("search")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedModel<DataTypeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -12,6 +12,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for moving data types within the system.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)]
|
||||
public class MoveDataTypeController : DataTypeControllerBase
|
||||
@@ -19,12 +22,25 @@ public class MoveDataTypeController : DataTypeControllerBase
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">Service used to manage data types.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public MoveDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an existing data type identified by the specified <paramref name="id"/> to a different container.
|
||||
/// The target container Id must be provided in the <paramref name="moveDataTypeRequestModel"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A cancellation token to cancel the operation.</param>
|
||||
/// <param name="id">The unique identifier of the data type to move.</param>
|
||||
/// <param name="moveDataTypeRequestModel">The request model containing the target container information.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the result of the move operation.</returns>
|
||||
[HttpPut("{id:guid}/move")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+16
-1
@@ -9,12 +9,20 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.References;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for managing and retrieving information about where specific data types are referenced within the system.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ReferencedByDataTypeController : DataTypeControllerBase
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReferencedByDataTypeController"/> class, which handles API requests related to data types referenced by other entities.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">Service used to manage and retrieve data type information.</param>
|
||||
/// <param name="relationTypePresentationFactory">Factory for creating presentation models for relation types.</param>
|
||||
public ReferencedByDataTypeController(IDataTypeService dataTypeService, IRelationTypePresentationFactory relationTypePresentationFactory)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
@@ -22,8 +30,15 @@ public class ReferencedByDataTypeController : DataTypeControllerBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paged list of references for the current data type, so you can see where it is being used.
|
||||
/// Gets a paged list of entities that reference the specified data type, allowing you to see where it is being used.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the data type to find references for.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set (used for paging).</param>
|
||||
/// <param name="take">The maximum number of items to return (used for paging).</param>
|
||||
/// <returns>
|
||||
/// A task representing the asynchronous operation. The result contains an <see cref="ActionResult{T}"/> with a <see cref="PagedViewModel{IReferenceResponseModel}"/> listing entities that reference the specified data type.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}/referenced-by")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for retrieving data type value schemas.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class SchemaDataTypeController : DataTypeControllerBase
|
||||
{
|
||||
private readonly IPropertyEditorSchemaService _schemaService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SchemaDataTypeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="schemaService">The property editor schema service.</param>
|
||||
public SchemaDataTypeController(IPropertyEditorSchemaService schemaService)
|
||||
=> _schemaService = schemaService;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value schema for a data type.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the data type.</param>
|
||||
/// <returns>The schema information for the data type's values.</returns>
|
||||
/// <remarks>
|
||||
/// Returns schema information for property editors that implement <c>IValueSchemaProvider</c>.
|
||||
/// Returns 404 if the data type is not found or doesn't support schema information.
|
||||
/// </remarks>
|
||||
[HttpGet("{id:guid}/schema")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(DataTypeSchemaResponseModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Schema(Guid id)
|
||||
{
|
||||
Attempt<PropertyValueSchema, PropertyEditorSchemaOperationStatus> attempt = await _schemaService.GetSchemaAsync(id);
|
||||
if (attempt.Success is false)
|
||||
{
|
||||
return PropertyEditorSchemaOperationStatusResult(attempt.Status);
|
||||
}
|
||||
|
||||
PropertyValueSchema result = attempt.Result;
|
||||
return Ok(new DataTypeSchemaResponseModel
|
||||
{
|
||||
ValueTypeName = result.ValueType?.FullName,
|
||||
JsonSchema = result.JsonSchema,
|
||||
});
|
||||
}
|
||||
}
|
||||
+14
@@ -8,15 +8,29 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling operations related to the ancestors tree structure of data types.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDataTypeTreeController"/> class, which provides API endpoints for retrieving ancestor data types in the tree structure.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the API.</param>
|
||||
/// <param name="dataTypeService">Service used for data type management and retrieval.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDataTypeTreeController"/> class, which manages operations related to ancestor data type trees in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity-related operations.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="dataTypeService">Service used for data type management operations.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public AncestorsDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
|
||||
+23
@@ -9,21 +9,44 @@ using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling operations related to the child nodes of the data type tree in the management API.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the system.</param>
|
||||
/// <param name="dataTypeService">Service used for managing and retrieving data types.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the system.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply additional flags or metadata for entities.</param>
|
||||
/// <param name="dataTypeService">Service responsible for operations related to data types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ChildrenDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated collection of data type tree items that are children of the specified parent ID.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="parentId">The unique identifier of the parent data type tree item whose children are to be retrieved.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set (used for pagination).</param>
|
||||
/// <param name="take">The maximum number of items to return (used for pagination).</param>
|
||||
/// <param name="foldersOnly">If set to <c>true</c>, only folder items will be included in the results.</param>
|
||||
/// <returns>A <see cref="PagedViewModel{T}"/> containing <see cref="DataTypeTreeItemResponseModel"/> instances representing the child items.</returns>
|
||||
[HttpGet("children")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DataTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+14
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for handling operations related to data type trees in the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.DataType}")]
|
||||
[ApiExplorerSettings(GroupName = "Data Type")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)]
|
||||
@@ -22,6 +25,11 @@ public class DataTypeTreeControllerBase : FolderTreeControllerBase<DataTypeTreeI
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTypeTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing Umbraco entities.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types within Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DataTypeTreeControllerBase(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: this(
|
||||
@@ -31,6 +39,12 @@ public class DataTypeTreeControllerBase : FolderTreeControllerBase<DataTypeTreeI
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTypeTreeControllerBase"/> class with the specified services.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the data type tree.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for entities.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public DataTypeTreeControllerBase(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: this(
|
||||
|
||||
+22
@@ -9,21 +9,43 @@ using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling operations related to the root of the data type tree in Umbraco.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types in Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public RootDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDataTypeTreeController"/> class, which manages the root of the data type tree in the Umbraco management API.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the tree.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="dataTypeService">Service used for data type management and retrieval.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public RootDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of data type items from the root of the tree, with optional folder-only filtering.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set.</param>
|
||||
/// <param name="take">The maximum number of items to return.</param>
|
||||
/// <param name="foldersOnly">If true, only folders are included in the results.</param>
|
||||
/// <returns>A paged view model containing data type tree item response models.</returns>
|
||||
[HttpGet("root")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DataTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+23
@@ -8,20 +8,43 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for managing sibling data types in the Umbraco CMS tree.
|
||||
/// </summary>
|
||||
public class SiblingsDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types in Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public SiblingsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDataTypeTreeController"/> class, which manages operations related to sibling data type trees in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the CMS.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SiblingsDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paged collection of data type tree items that are siblings of the specified data type identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="target">The unique identifier of the data type whose siblings are to be retrieved.</param>
|
||||
/// <param name="before">The number of sibling items to retrieve before the target item.</param>
|
||||
/// <param name="after">The number of sibling items to retrieve after the target item.</param>
|
||||
/// <param name="foldersOnly">If set to <c>true</c>, only folders will be included in the results; otherwise, both folders and data types are returned.</param>
|
||||
/// <returns>A task representing the asynchronous operation. The task result contains an <see cref="ActionResult{T}"/> with a <see cref="SubsetViewModel{T}"/> of <see cref="DataTypeTreeItemResponseModel"/> representing the sibling items.</returns>
|
||||
[HttpGet("siblings")]
|
||||
[ProducesResponseType(typeof(SubsetViewModel<DataTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of data type tree sibling items.")]
|
||||
|
||||
@@ -13,6 +13,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to update data types in the Umbraco CMS management interface.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDataTypes)]
|
||||
public class UpdateDataTypeController : DataTypeControllerBase
|
||||
@@ -21,6 +24,12 @@ public class UpdateDataTypeController : DataTypeControllerBase
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private IDataTypePresentationFactory _dataTypePresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateDataTypeController"/> class, responsible for handling data type update operations in the management API.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeService">Service used to manage data types.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="dataTypePresentationFactory">Factory for creating data type presentation models.</param>
|
||||
public UpdateDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, IDataTypePresentationFactory dataTypePresentationFactory)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
@@ -28,6 +37,13 @@ public class UpdateDataTypeController : DataTypeControllerBase
|
||||
_dataTypePresentationFactory = dataTypePresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the data type with the specified ID using the provided request model.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the data type to update.</param>
|
||||
/// <param name="updateDataTypeViewModel">The model containing the updated data type details.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the result of the update operation.</returns>
|
||||
[HttpPut("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
@@ -10,18 +10,34 @@ using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving and managing all dictionary items within the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AllDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemService _dictionaryItemService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AllDictionaryController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">An instance of <see cref="IDictionaryItemService"/> used to manage dictionary items.</param>
|
||||
/// <param name="umbracoMapper">An instance of <see cref="IUmbracoMapper"/> used for mapping between models.</param>
|
||||
public AllDictionaryController(IDictionaryItemService dictionaryItemService, IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_dictionaryItemService = dictionaryItemService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of dictionary items, optionally filtered by name.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="filter">An optional string to filter dictionary items by name.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set.</param>
|
||||
/// <param name="take">The maximum number of items to return.</param>
|
||||
/// <returns>A paginated view model containing dictionary overview response models.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DictionaryOverviewResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
@@ -8,18 +8,36 @@ using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// API controller for managing Umbraco dictionary items by their unique key.
|
||||
/// Provides endpoints for retrieving, updating, and deleting dictionary entries identified by key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemService _dictionaryItemService;
|
||||
private readonly IDictionaryPresentationFactory _dictionaryPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ByKeyDictionaryController"/> class, which manages dictionary items by key.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">The <see cref="IDictionaryItemService"/> used to manage dictionary items.</param>
|
||||
/// <param name="dictionaryPresentationFactory">The <see cref="IDictionaryPresentationFactory"/> used to create dictionary item presentations.</param>
|
||||
public ByKeyDictionaryController(IDictionaryItemService dictionaryItemService, IDictionaryPresentationFactory dictionaryPresentationFactory)
|
||||
{
|
||||
_dictionaryItemService = dictionaryItemService;
|
||||
_dictionaryPresentationFactory = dictionaryPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a dictionary item by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the dictionary item to retrieve.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing the <see cref="DictionaryItemResponseModel"/> if the item is found;
|
||||
/// otherwise, a 404 Not Found response.
|
||||
/// </returns>
|
||||
[HttpGet($"{{{nameof(id)}:guid}}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(DictionaryItemResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+18
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to create new dictionary items in Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CreateDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
@@ -23,6 +26,14 @@ public class CreateDictionaryController : DictionaryControllerBase
|
||||
private readonly IDictionaryPresentationFactory _dictionaryPresentationFactory;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Dictionary.CreateDictionaryController"/> class,
|
||||
/// providing dependencies required for managing dictionary items in the Umbraco back office API.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="dictionaryPresentationFactory">Factory for creating dictionary presentation models.</param>
|
||||
/// <param name="authorizationService">Service for handling authorization checks.</param>
|
||||
public CreateDictionaryController(
|
||||
IDictionaryItemService dictionaryItemService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
@@ -35,6 +46,12 @@ public class CreateDictionaryController : DictionaryControllerBase
|
||||
_authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new dictionary item using the details provided in the request model.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token to monitor for cancellation requests.</param>
|
||||
/// <param name="createDictionaryItemRequestModel">The model containing the details of the dictionary item to create, including translations.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the result of the create operation, including possible status codes for success or failure.</returns>
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -9,12 +9,20 @@ using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling requests to delete dictionary items in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemService _dictionaryItemService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteDictionaryController"/> class, used for handling requests to delete dictionary items in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public DeleteDictionaryController(IDictionaryItemService dictionaryItemService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_dictionaryItemService = dictionaryItemService;
|
||||
|
||||
@@ -8,6 +8,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for API endpoints that manage dictionary-related operations in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute("dictionary")]
|
||||
[ApiExplorerSettings(GroupName = "Dictionary")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDictionary)]
|
||||
|
||||
+19
-1
@@ -1,4 +1,4 @@
|
||||
using System.Net.Mime;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Asp.Versioning;
|
||||
@@ -10,18 +10,36 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for exporting dictionary entries from the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ExportDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemService _dictionaryItemService;
|
||||
private readonly IEntityXmlSerializer _entityXmlSerializer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExportDictionaryController"/> class, providing services for dictionary item management and XML serialization.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">Service used to manage dictionary items.</param>
|
||||
/// <param name="entityXmlSerializer">Service used to serialize entities to XML.</param>
|
||||
public ExportDictionaryController(IDictionaryItemService dictionaryItemService, IEntityXmlSerializer entityXmlSerializer)
|
||||
{
|
||||
_dictionaryItemService = dictionaryItemService;
|
||||
_entityXmlSerializer = entityXmlSerializer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports the dictionary item identified by the provided <paramref name="id"/> as a downloadable file.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the dictionary item to export.</param>
|
||||
/// <param name="includeChildren">If <c>true</c>, child dictionary items will also be included in the export; otherwise, only the specified item is exported.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="FileContentResult"/> containing the exported dictionary data as a file if the dictionary item is found;
|
||||
/// otherwise, a <see cref="NotFoundResult"/> if the item does not exist.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}/export")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
|
||||
|
||||
+18
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.Builders;
|
||||
@@ -11,12 +11,20 @@ using Umbraco.Cms.Core.Security;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for importing dictionary items into the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ImportDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemImportService _dictionaryItemImportService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImportDictionaryController"/> class, which handles dictionary item import operations in the Umbraco backoffice API.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemImportService">Service used to import dictionary items.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public ImportDictionaryController(
|
||||
IDictionaryItemImportService dictionaryItemImportService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
@@ -25,6 +33,15 @@ public class ImportDictionaryController : DictionaryControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports a dictionary from a provided UDT file upload.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used to cancel the import operation.</param>
|
||||
/// <param name="importDictionaryRequestModel">The model containing the uploaded UDT file and optional parent dictionary item information.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> indicating the result of the import operation:
|
||||
/// returns <c>201 Created</c> on success, <c>400 Bad Request</c> for invalid file types or content, and <c>404 Not Found</c> if the parent or file is missing.
|
||||
/// </returns>
|
||||
[HttpPost("import")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
+5
-1
@@ -1,9 +1,13 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for managing dictionary items in the Umbraco CMS Management API.
|
||||
/// Provides common functionality and endpoints for derived controllers handling dictionary item operations.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/dictionary")]
|
||||
[ApiExplorerSettings(GroupName = "Dictionary")]
|
||||
public class DictionaryItemControllerBase : ManagementApiControllerBase
|
||||
|
||||
+15
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Dictionary.Item;
|
||||
@@ -8,18 +8,32 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for managing individual dictionary items within the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ItemDictionaryItemController : DictionaryItemControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemService _dictionaryItemService;
|
||||
private readonly IUmbracoMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemDictionaryItemController"/> class with the specified services.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">An instance of <see cref="IDictionaryItemService"/> used to manage dictionary items.</param>
|
||||
/// <param name="mapper">An instance of <see cref="IUmbracoMapper"/> used for mapping objects.</param>
|
||||
public ItemDictionaryItemController(IDictionaryItemService dictionaryItemService, IUmbracoMapper mapper)
|
||||
{
|
||||
_dictionaryItemService = dictionaryItemService;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a collection of dictionary items matching the specified IDs.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="ids">A set of dictionary item IDs to retrieve.</param>
|
||||
/// <returns>A task representing the asynchronous operation. The result contains an <see cref="IActionResult"/> with the collection of dictionary items.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DictionaryItemItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
|
||||
@@ -10,12 +10,20 @@ using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for moving dictionary items within the Umbraco CMS management interface.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
private readonly IDictionaryItemService _dictionaryItemService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveDictionaryController"/> class, responsible for handling dictionary item move operations in the management API.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">Service used to manage dictionary items.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public MoveDictionaryController(IDictionaryItemService dictionaryItemService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_dictionaryItemService = dictionaryItemService;
|
||||
|
||||
+20
@@ -8,21 +8,41 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for managing and exposing operations related to the ancestors of dictionary items in the dictionary tree.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDictionaryTreeController : DictionaryTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing dictionary items in the Umbraco dictionary tree.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDictionaryTreeController"/> class, which handles operations related to retrieving ancestor dictionary tree items.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used for entity operations.</param>
|
||||
/// <param name="flagProviders">A collection of providers for entity flags.</param>
|
||||
/// <param name="dictionaryItemService">The service used for dictionary item operations.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public AncestorsDictionaryTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, flagProviders, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all ancestor dictionary items for the specified descendant item.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="descendantId">The unique identifier of the descendant dictionary item whose ancestors are to be retrieved.</param>
|
||||
/// <returns>A task representing the asynchronous operation. The task result contains an <see cref="ActionResult{T}"/> with a collection of ancestor <see cref="NamedEntityTreeItemResponseModel"/> items.</returns>
|
||||
[HttpGet("ancestors")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<NamedEntityTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+22
@@ -10,21 +10,43 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for managing and retrieving the child nodes of dictionary items in the Umbraco dictionary tree.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDictionaryTreeController : DictionaryTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the system.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing dictionary items.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply additional flags or metadata for entities.</param>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items used for localization.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ChildrenDictionaryTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, flagProviders, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of dictionary tree items that are direct children of the specified parent dictionary item.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="parentId">The unique identifier of the parent dictionary item whose children are to be retrieved.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set (used for pagination).</param>
|
||||
/// <param name="take">The maximum number of items to return (used for pagination).</param>
|
||||
/// <returns>A paged view model containing the child dictionary tree items.</returns>
|
||||
[HttpGet("children")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<NamedEntityTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+17
-2
@@ -14,6 +14,10 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for operations related to dictionary tree structures in the Umbraco CMS Management API.
|
||||
/// Provides common functionality for derived controllers managing dictionary items in a hierarchical format.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/dictionary")]
|
||||
[ApiExplorerSettings(GroupName = "Dictionary")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDictionaryOrTemplates)]
|
||||
@@ -21,6 +25,11 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
// tree controller base. We'll keep it though, in the hope that we can mend EntityService.
|
||||
public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase<NamedEntityTreeItemResponseModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DictionaryTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the Umbraco system.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing and retrieving dictionary items for localization.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DictionaryTreeControllerBase(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: this(
|
||||
@@ -30,9 +39,15 @@ public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase<NamedE
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DictionaryTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing entities within the system.</param>
|
||||
/// <param name="flagProviders">A collection of providers for entity flags.</param>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items.</param>
|
||||
public DictionaryTreeControllerBase(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, flagProviders) =>
|
||||
DictionaryItemService = dictionaryItemService;
|
||||
|
||||
+24
@@ -10,20 +10,44 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing the root of the dictionary tree in the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDictionaryTreeController : DictionaryTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the dictionary tree.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing dictionary items.</param>
|
||||
public RootDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDictionaryTreeController"/> class, which manages the root nodes of the dictionary tree in the Umbraco management API.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing entities within Umbraco.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for entities.</param>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public RootDictionaryTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, flagProviders, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated collection of dictionary items from the root of the dictionary tree.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination. Defaults to 0.</param>
|
||||
/// <param name="take">The maximum number of items to return for pagination. Defaults to 100.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="ActionResult{T}"/> containing a <see cref="PagedViewModel{NamedEntityTreeItemResponseModel}"/>,
|
||||
/// which represents the paginated dictionary items from the root of the tree.
|
||||
/// </returns>
|
||||
[HttpGet("root")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<NamedEntityTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+18
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -16,6 +16,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to update dictionary items in the Umbraco CMS management interface.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdateDictionaryController : DictionaryControllerBase
|
||||
{
|
||||
@@ -24,6 +27,13 @@ public class UpdateDictionaryController : DictionaryControllerBase
|
||||
private readonly IDictionaryPresentationFactory _dictionaryPresentationFactory;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateDictionaryController"/> class, which handles API requests for updating dictionary items in Umbraco.
|
||||
/// </summary>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="dictionaryPresentationFactory">Factory for creating dictionary item presentation models.</param>
|
||||
/// <param name="authorizationService">Service for handling authorization checks.</param>
|
||||
public UpdateDictionaryController(
|
||||
IDictionaryItemService dictionaryItemService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
@@ -36,6 +46,13 @@ public class UpdateDictionaryController : DictionaryControllerBase
|
||||
_authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an existing dictionary item with the specified identifier using the provided details.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the dictionary item to update.</param>
|
||||
/// <param name="updateDictionaryItemRequestModel">The model containing the updated dictionary item details.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the update operation.</returns>
|
||||
[HttpPut($"{{{nameof(id)}:guid}}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
@@ -16,6 +16,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for retrieving and managing available segments associated with documents.
|
||||
/// </summary>
|
||||
[Obsolete("This controller is temporary. A more permanent solution will follow. Scheduled for removal in Umbraco 20.")]
|
||||
[ApiVersion("1.0")]
|
||||
public class AvailableSegmentsController : DocumentControllerBase
|
||||
@@ -24,6 +27,12 @@ public class AvailableSegmentsController : DocumentControllerBase
|
||||
private readonly ISegmentService _segmentService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AvailableSegmentsController"/> class, which manages API endpoints for retrieving available document segments in Umbraco.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to controller actions.</param>
|
||||
/// <param name="segmentService">Service for retrieving and managing document segments.</param>
|
||||
/// <param name="umbracoMapper">The mapper used to convert between Umbraco domain models and API models.</param>
|
||||
public AvailableSegmentsController(
|
||||
IAuthorizationService authorizationService,
|
||||
ISegmentService segmentService,
|
||||
@@ -34,6 +43,14 @@ public class AvailableSegmentsController : DocumentControllerBase
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paged collection of available content segments for a specified document.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the document for which to retrieve available segments.</param>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of segments to skip before starting to collect the result set (used for paging).</param>
|
||||
/// <param name="take">The maximum number of segments to return (used for paging).</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains an <see cref="IActionResult"/> with a <see cref="PagedViewModel{SegmentResponseModel}"/> representing the paged collection of available segments.</returns>
|
||||
[HttpGet("{id:guid}/available-segment-options")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<SegmentResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -12,6 +12,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing documents in Umbraco that are identified by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -19,6 +22,12 @@ public class ByKeyDocumentController : DocumentControllerBase
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
private readonly IContentQueryService _contentQueryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.ByKeyDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to document resources.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
/// <param name="contentQueryService">Service for querying content data within the CMS.</param>
|
||||
public ByKeyDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IDocumentPresentationFactory documentPresentationFactory,
|
||||
@@ -29,6 +38,15 @@ public class ByKeyDocumentController : DocumentControllerBase
|
||||
_contentQueryService = contentQueryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a document by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique <see cref="Guid"/> of the document to retrieve.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing a <see cref="DocumentResponseModel"/> if the document is found;
|
||||
/// otherwise, a 404 Not Found or 403 Forbidden error response.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(DocumentResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+18
@@ -13,6 +13,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for managing published documents identified by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyPublishedDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -20,6 +23,12 @@ public class ByKeyPublishedDocumentController : DocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ByKeyPublishedDocumentController"/> class, which handles published document operations by key.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to document operations.</param>
|
||||
/// <param name="contentEditingService">Service used for editing content.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
public ByKeyPublishedDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
@@ -30,6 +39,15 @@ public class ByKeyPublishedDocumentController : DocumentControllerBase
|
||||
_documentPresentationFactory = documentPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a published document identified by the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the document to retrieve.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing the <see cref="PublishedDocumentResponseModel"/> if the published document is found;
|
||||
/// otherwise, returns <c>404 Not Found</c> if the document does not exist or is not published, or <c>403 Forbidden</c> if the user is not authorized.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}/published")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PublishedDocumentResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+32
@@ -16,6 +16,9 @@ using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.Collection;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for managing collections of documents identified by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyDocumentCollectionController : DocumentCollectionControllerBase
|
||||
{
|
||||
@@ -23,6 +26,15 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IDocumentCollectionPresentationFactory _documentCollectionPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Collection.ByKeyDocumentCollectionController"/> class,
|
||||
/// which handles document collection operations by document key.
|
||||
/// </summary>
|
||||
/// <param name="contentListViewService">Service for retrieving and managing content list views.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="mapper">The Umbraco object mapper used for mapping between models.</param>
|
||||
/// <param name="documentCollectionPresentationFactory">Factory for creating document collection presentation models.</param>
|
||||
/// <param name="flagProviders">A collection of providers for document collection flags.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ByKeyDocumentCollectionController(
|
||||
IContentListViewService contentListViewService,
|
||||
@@ -37,6 +49,13 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas
|
||||
_documentCollectionPresentationFactory = documentCollectionPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Collection.ByKeyDocumentCollectionController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contentListViewService">Service for managing content list views.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security operations.</param>
|
||||
/// <param name="mapper">Maps Umbraco objects to API models.</param>
|
||||
/// <param name="documentCollectionPresentationFactory">Factory for creating document collection presentation models.</param>
|
||||
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ByKeyDocumentCollectionController(
|
||||
IContentListViewService contentListViewService,
|
||||
@@ -52,6 +71,19 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paged collection of documents identified by the provided unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (key) of the document collection.</param>
|
||||
/// <param name="dataTypeId">An optional data type identifier to filter the collection.</param>
|
||||
/// <param name="orderBy">The field by which to order the collection. Defaults to <c>"updateDate"</c>.</param>
|
||||
/// <param name="orderCulture">An optional culture code to use for ordering.</param>
|
||||
/// <param name="orderDirection">The direction to order the collection. Defaults to <see cref="Direction.Ascending"/>.</param>
|
||||
/// <param name="filter">An optional filter string to filter the collection.</param>
|
||||
/// <param name="skip">The number of items to skip for paging. Defaults to 0.</param>
|
||||
/// <param name="take">The number of items to take for paging. Defaults to 100.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous operation. The task result contains an <see cref="IActionResult"/> with a paged list of <see cref="DocumentCollectionResponseModel"/>.</returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DocumentCollectionResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+3
@@ -13,6 +13,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.Collection;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for handling operations related to document collections within the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Collection}/{Constants.UdiEntityType.Document}")]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)]
|
||||
|
||||
+13
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
@@ -6,15 +6,27 @@ using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling operations related to configuration documents within the Umbraco CMS management area.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ConfigurationDocumentController : DocumentControllerBase
|
||||
{
|
||||
private readonly IConfigurationPresentationFactory _configurationPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigurationDocumentController"/> class, responsible for managing configuration documents.
|
||||
/// </summary>
|
||||
/// <param name="configurationPresentationFactory">Factory used to create configuration presentation models for documents.</param>
|
||||
public ConfigurationDocumentController(
|
||||
IConfigurationPresentationFactory configurationPresentationFactory) =>
|
||||
_configurationPresentationFactory = configurationPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the configuration settings for documents.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing a <see cref="DocumentConfigurationResponseModel"/> with the document configuration settings.</returns>
|
||||
[HttpGet("configuration")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(DocumentConfigurationResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -16,6 +16,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// API controller for handling copy operations on documents in Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CopyDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -23,6 +26,12 @@ public class CopyDocumentController : DocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.CopyDocumentController"/> class, which handles document copy operations in the management API.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize user actions.</param>
|
||||
/// <param name="contentEditingService">Service for editing and managing content.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public CopyDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
@@ -33,6 +42,13 @@ public class CopyDocumentController : DocumentControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of an existing document identified by the specified <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the document to copy.</param>
|
||||
/// <param name="copyDocumentRequestModel">The request model containing details about the copy operation, such as the target location and copy options.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the copy operation.</returns>
|
||||
[HttpPost("{id:guid}/copy")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -12,6 +12,9 @@ using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling operations related to the creation of content documents in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CreateDocumentController : CreateDocumentControllerBase
|
||||
{
|
||||
@@ -19,6 +22,13 @@ public class CreateDocumentController : CreateDocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreateDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to document creation operations.</param>
|
||||
/// <param name="documentEditingPresentationFactory">Factory for creating document editing presentation models.</param>
|
||||
/// <param name="contentEditingService">Service responsible for content editing functionality.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public CreateDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IDocumentEditingPresentationFactory documentEditingPresentationFactory,
|
||||
@@ -31,6 +41,12 @@ public class CreateDocumentController : CreateDocumentControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new document using the specified request model.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token to monitor for cancellation requests.</param>
|
||||
/// <param name="requestModel">The details of the document to create.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the operation.</returns>
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
@@ -9,6 +9,10 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for document creation endpoints in the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for creating documents.
|
||||
/// </summary>
|
||||
public abstract class CreateDocumentControllerBase : DocumentControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
+23
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -16,6 +16,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to create documents with public access permissions in Umbraco.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CreatePublicAccessDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -23,6 +26,12 @@ public class CreatePublicAccessDocumentController : DocumentControllerBase
|
||||
private readonly IPublicAccessPresentationFactory _publicAccessPresentationFactory;
|
||||
private readonly IPublicAccessService _publicAccessService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreatePublicAccessDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to perform permission checks.</param>
|
||||
/// <param name="publicAccessPresentationFactory">Factory for creating public access presentation models.</param>
|
||||
/// <param name="publicAccessService">Service for managing public access settings.</param>
|
||||
public CreatePublicAccessDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IPublicAccessPresentationFactory publicAccessPresentationFactory,
|
||||
@@ -33,6 +42,19 @@ public class CreatePublicAccessDocumentController : DocumentControllerBase
|
||||
_publicAccessService = publicAccessService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates public access rules for the specified document, restricting or allowing access based on the provided access details.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the document to protect.</param>
|
||||
/// <param name="publicAccessRequestModel">The model containing the public access configuration for the document.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> indicating the result of the operation:
|
||||
/// <list type="bullet">
|
||||
/// <item><description><c>201 Created</c> if the public access rules were successfully created.</description></item>
|
||||
/// <item><description><c>404 Not Found</c> if the document does not exist.</description></item>
|
||||
/// </list>
|
||||
/// </returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpPost("{id:guid}/public-access")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to delete documents in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -22,6 +25,12 @@ public class DeleteDocumentController : DocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">An <see cref="IAuthorizationService"/> used to authorize document deletion requests.</param>
|
||||
/// <param name="contentEditingService">An <see cref="IContentEditingService"/> used to perform content editing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">An <see cref="IBackOfficeSecurityAccessor"/> providing access to back office security information.</param>
|
||||
public DeleteDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
@@ -32,6 +41,12 @@ public class DeleteDocumentController : DocumentControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the document with the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the document to delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the outcome of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+18
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -13,18 +13,35 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for deleting public access settings from documents.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeletePublicAccessDocumentController : DocumentControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IPublicAccessService _publicAccessService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeletePublicAccessDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to document operations.</param>
|
||||
/// <param name="publicAccessService">Service used to manage public access settings for documents.</param>
|
||||
public DeletePublicAccessDocumentController(IAuthorizationService authorizationService, IPublicAccessService publicAccessService)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_publicAccessService = publicAccessService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes public access protection and rules from the specified document.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the document from which to remove public access.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> indicating the result of the operation:
|
||||
/// returns <c>200 OK</c> if successful, or <c>404 Not Found</c> if the document or public access settings do not exist.
|
||||
/// </returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpDelete("{id:guid}/public-access")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
@@ -12,6 +12,10 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for implementing document management operations within the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for derived document controllers.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.Document)]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)]
|
||||
|
||||
+10
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.Builders;
|
||||
@@ -9,6 +9,9 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for generating and retrieving preview URLs for documents.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DocumentPreviewUrlController : DocumentControllerBase
|
||||
{
|
||||
@@ -23,6 +26,12 @@ public class DocumentPreviewUrlController : DocumentControllerBase
|
||||
_documentUrlFactory = documentUrlFactory;
|
||||
}
|
||||
|
||||
/// <summary>Retrieves the preview URL for a document by its unique identifier.</summary>
|
||||
/// <param name="id">The unique identifier (GUID) of the document.</param>
|
||||
/// <param name="providerAlias">The alias of the provider used to generate the preview URL.</param>
|
||||
/// <param name="culture">An optional culture code for the preview URL.</param>
|
||||
/// <param name="segment">An optional segment for the preview URL.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the preview URL information if found; otherwise, a <see cref="ProblemDetails"/> response indicating the error.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}/preview-url")]
|
||||
[ProducesResponseType(typeof(DocumentUrlInfo), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
@@ -9,12 +9,21 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for managing and retrieving URLs for documents within the Umbraco CMS.
|
||||
/// Provides endpoints for operations related to document URLs.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DocumentUrlController : DocumentControllerBase
|
||||
{
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IDocumentUrlFactory _documentUrlFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.DocumentUrlController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contentService">An instance of <see cref="IContentService"/> used to manage content operations.</param>
|
||||
/// <param name="documentUrlFactory">An instance of <see cref="IDocumentUrlFactory"/> used to generate document URLs.</param>
|
||||
public DocumentUrlController(
|
||||
IContentService contentService,
|
||||
IDocumentUrlFactory documentUrlFactory)
|
||||
@@ -23,6 +32,11 @@ public class DocumentUrlController : DocumentControllerBase
|
||||
_documentUrlFactory = documentUrlFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the URLs for the documents identified by the specified set of IDs.
|
||||
/// </summary>
|
||||
/// <param name="ids">A set of document IDs for which to retrieve URLs.</param>
|
||||
/// <returns>A task representing the asynchronous operation. The task result contains an <see cref="IActionResult"/> with a collection of URL information for each requested document.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("urls")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DocumentUrlInfoResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for managing domains associated with documents.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DomainsController : DocumentControllerBase
|
||||
{
|
||||
@@ -23,6 +26,11 @@ public class DomainsController : DocumentControllerBase
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
[ActivatorUtilitiesConstructor]
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.DomainsController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="domainService">Service used to manage domain-related operations.</param>
|
||||
/// <param name="umbracoMapper">The mapper used to map Umbraco objects to API models.</param>
|
||||
public DomainsController(IAuthorizationService authorizationService, IDomainService domainService, IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
@@ -39,6 +47,15 @@ public class DomainsController : DocumentControllerBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the list of domains and their associated culture settings assigned to the specified document.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the document for which to retrieve domain assignments.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing a <see cref="DomainsResponseModel"/> with the assigned domains and culture settings, or a <see cref="ProblemDetails"/> if the document is not found.
|
||||
/// </returns>
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}/domains")]
|
||||
[ProducesResponseType(typeof(DomainsResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+20
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for retrieving the audit log of a document.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class GetAuditLogDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -22,6 +25,12 @@ public class GetAuditLogDocumentController : DocumentControllerBase
|
||||
private readonly IAuditService _auditService;
|
||||
private readonly IAuditLogPresentationFactory _auditLogPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.GetAuditLogDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service for handling authorization and access control.</param>
|
||||
/// <param name="auditService">Service for retrieving audit log entries.</param>
|
||||
/// <param name="auditLogPresentationFactory">Factory for creating audit log presentation models.</param>
|
||||
public GetAuditLogDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IAuditService auditService,
|
||||
@@ -32,6 +41,16 @@ public class GetAuditLogDocumentController : DocumentControllerBase
|
||||
_auditLogPresentationFactory = auditLogPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of audit log entries for the specified document.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the document whose audit log is requested.</param>
|
||||
/// <param name="orderDirection">The sort direction for the audit log entries (ascending or descending).</param>
|
||||
/// <param name="sinceDate">An optional date; only audit log entries created on or after this date are included.</param>
|
||||
/// <param name="skip">The number of entries to skip (for pagination).</param>
|
||||
/// <param name="take">The maximum number of entries to return (for pagination).</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains an <see cref="IActionResult"/> with a paged view model of audit log entries.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}/audit-log")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<AuditLogResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+15
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling API requests to retrieve documents with public access settings.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class GetPublicAccessDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -22,6 +25,12 @@ public class GetPublicAccessDocumentController : DocumentControllerBase
|
||||
private readonly IPublicAccessService _publicAccessService;
|
||||
private readonly IPublicAccessPresentationFactory _publicAccessPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GetPublicAccessDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to resources.</param>
|
||||
/// <param name="publicAccessService">Service for managing public access rules for documents.</param>
|
||||
/// <param name="publicAccessPresentationFactory">Factory for creating presentation models for public access data.</param>
|
||||
public GetPublicAccessDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IPublicAccessService publicAccessService,
|
||||
@@ -32,6 +41,12 @@ public class GetPublicAccessDocumentController : DocumentControllerBase
|
||||
_publicAccessPresentationFactory = publicAccessPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the public access protection settings for the specified document.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the document whose public access settings are to be retrieved.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the public access settings if found; otherwise, an error result.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}/public-access")]
|
||||
[ProducesResponseType(typeof(PublicAccessResponseModel), StatusCodes.Status200OK)]
|
||||
|
||||
+4
-1
@@ -1,9 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for document item operations in the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Document}")]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
|
||||
public class DocumentItemControllerBase : ManagementApiControllerBase
|
||||
|
||||
+16
@@ -10,12 +10,22 @@ using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling operations related to item documents within the Umbraco CMS management area.
|
||||
/// Provides endpoints for retrieving, updating, or managing document items.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ItemDocumentItemController : DocumentItemControllerBase
|
||||
{
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Item.ItemDocumentItemController"/> class.
|
||||
/// This controller is responsible for handling API requests related to individual document items in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used to manage and retrieve entities within the CMS.</param>
|
||||
/// <param name="documentPresentationFactory">The factory responsible for creating document presentation models.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ItemDocumentItemController(
|
||||
IEntityService entityService,
|
||||
@@ -25,6 +35,12 @@ public class ItemDocumentItemController : DocumentItemControllerBase
|
||||
_documentPresentationFactory = documentPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of document items identified by the provided Ids.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
|
||||
/// <param name="ids">The set of document item Ids to retrieve.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains an IActionResult with the collection of document items.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DocumentItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+39
@@ -12,6 +12,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for searching document items within the management interface.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
{
|
||||
@@ -19,6 +22,12 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SearchDocumentItemController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="indexedEntitySearchService">Service for searching indexed entities.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SearchDocumentItemController(
|
||||
IIndexedEntitySearchService indexedEntitySearchService,
|
||||
@@ -30,6 +39,11 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
_dataTypeService = dataTypeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SearchDocumentItemController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="indexedEntitySearchService">The service used to perform searches on indexed entities. This dependency is injected.</param>
|
||||
/// <param name="documentPresentationFactory">The factory responsible for creating document presentation models. This dependency is injected.</param>
|
||||
[Obsolete("Use the non-obsolete constructor instead. Scheduled for removal in Umbraco 18.")]
|
||||
public SearchDocumentItemController(
|
||||
IIndexedEntitySearchService indexedEntitySearchService,
|
||||
@@ -41,6 +55,18 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for document items, including those in the recycle bin, using the specified query and filters.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="query">The search query string.</param>
|
||||
/// <param name="trashed">If set, filters results to include only trashed items, only non-trashed items, or both (when null).</param>
|
||||
/// <param name="culture">An optional culture code to filter search results.</param>
|
||||
/// <param name="skip">The number of items to skip (for pagination).</param>
|
||||
/// <param name="take">The maximum number of items to return (for pagination).</param>
|
||||
/// <param name="parentId">An optional parent ID to filter results by parent.</param>
|
||||
/// <param name="allowedDocumentTypes">An optional list of allowed document type IDs to filter results.</param>
|
||||
/// <returns>A task representing the asynchronous operation, with an action result containing the search results.</returns>
|
||||
[Obsolete("Please use the overload taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public async Task<IActionResult> SearchWithTrashed(
|
||||
@@ -63,6 +89,19 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
allowedDocumentTypes,
|
||||
null);
|
||||
|
||||
/// <summary>
|
||||
/// Searches for document items, including those in the recycle bin, based on the specified query and filters.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="query">The search query string.</param>
|
||||
/// <param name="trashed">Whether to include trashed (recycled) items in the search. Optional.</param>
|
||||
/// <param name="culture">The culture to filter the search results by. Optional.</param>
|
||||
/// <param name="skip">The number of items to skip for paging.</param>
|
||||
/// <param name="take">The number of items to return for paging.</param>
|
||||
/// <param name="parentId">The parent ID to filter the search results by. Optional.</param>
|
||||
/// <param name="allowedDocumentTypes">A list of allowed document type IDs to filter the search results by. Optional.</param>
|
||||
/// <param name="dataTypeId">The data type ID to filter the search results by. Optional.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The result contains an <see cref="IActionResult"/> with the search results.</returns>
|
||||
[HttpGet("search")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedModel<DocumentItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -16,6 +16,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling document move operations within the Umbraco CMS API.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -23,6 +26,13 @@ public class MoveDocumentController : DocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.MoveDocumentController"/> class,
|
||||
/// providing services required for document move operations.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize user actions related to document movement.</param>
|
||||
/// <param name="contentEditingService">Service responsible for editing and managing content documents.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context and user information.</param>
|
||||
public MoveDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
@@ -33,6 +43,16 @@ public class MoveDocumentController : DocumentControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the specified document to a new location within the content tree.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the document to move.</param>
|
||||
/// <param name="moveDocumentRequestModel">The request model containing information about the target location.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> indicating the result of the move operation:
|
||||
/// returns <c>200 OK</c> if the move is successful, or <c>404 Not Found</c> if the document or target location does not exist.
|
||||
/// </returns>
|
||||
[HttpPut("{id:guid}/move")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+10
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -15,6 +15,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for moving documents to the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveToRecycleBinDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -22,6 +25,12 @@ public class MoveToRecycleBinDocumentController : DocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveToRecycleBinDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize user actions for moving documents to the recycle bin.</param>
|
||||
/// <param name="contentEditingService">Service responsible for editing and managing content documents.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context and user information.</param>
|
||||
public MoveToRecycleBinDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
|
||||
@@ -14,6 +14,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for managing notifications related to documents.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class NotificationsController : DocumentControllerBase
|
||||
{
|
||||
@@ -21,6 +24,12 @@ public class NotificationsController : DocumentControllerBase
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IDocumentNotificationPresentationFactory _documentNotificationPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NotificationsController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize user actions for document notifications.</param>
|
||||
/// <param name="contentEditingService">Service responsible for editing and managing document content.</param>
|
||||
/// <param name="documentNotificationPresentationFactory">Factory for creating presentation models for document notifications.</param>
|
||||
public NotificationsController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
@@ -31,6 +40,12 @@ public class NotificationsController : DocumentControllerBase
|
||||
_documentNotificationPresentationFactory = documentNotificationPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves notifications for the specified document.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the document.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the notifications for the specified document, or a 404 response if not found.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}/notifications")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DocumentNotificationResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.OperationStatus;
|
||||
using Umbraco.Cms.Api.Management.Patchers;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Patching;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class PatchDocumentController : PatchDocumentControllerBase
|
||||
{
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IDocumentPatcher _documentPatcher;
|
||||
private readonly IDocumentEditingPresentationFactory _presentationFactory;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
public PatchDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentEditingService contentEditingService,
|
||||
IDocumentPatcher documentPatcher,
|
||||
IDocumentEditingPresentationFactory presentationFactory,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: base(authorizationService)
|
||||
{
|
||||
_contentEditingService = contentEditingService;
|
||||
_documentPatcher = documentPatcher;
|
||||
_presentationFactory = presentationFactory;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
[HttpPatch("{id:guid}/patch")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
|
||||
[EndpointSummary("Make partial updates to a document. For more information, see the documentation at https://docs.umbraco.com/umbraco-cms/reference/management-api/patching/document-endpoint-guide or https://docs.umbraco.com/umbraco-cms/reference/management-api/patching/document-endpoint-spec")]
|
||||
[Consumes("application/json-patch+json")]
|
||||
public async Task<IActionResult> Patch(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
PatchDocumentRequestModel requestModel)
|
||||
=> await HandleRequest(id, async () =>
|
||||
{
|
||||
ContentPatchModel patchModel = _presentationFactory.MapPatchModel(requestModel);
|
||||
|
||||
// Apply PATCH operations to create an update request model
|
||||
Attempt<UpdateDocumentRequestModel, ContentPatchingOperationStatus> patchResult =
|
||||
await _documentPatcher.ApplyPatchAsync(id, patchModel);
|
||||
|
||||
if (patchResult.Success is false)
|
||||
{
|
||||
return ContentPatchingOperationStatusResult(patchResult.Status);
|
||||
}
|
||||
|
||||
ContentUpdateModel contentUpdateModel = _presentationFactory.MapUpdateModel(patchResult.Result);
|
||||
|
||||
// Use the standard update method to save the patched content
|
||||
Attempt<ContentUpdateResult, ContentEditingOperationStatus> updateResult =
|
||||
await _contentEditingService.UpdateAsync(id, contentUpdateModel, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return updateResult.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(updateResult.Status);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
public abstract class PatchDocumentControllerBase : UpdateDocumentControllerBase
|
||||
{
|
||||
protected PatchDocumentControllerBase(IAuthorizationService authorizationService)
|
||||
: base(authorizationService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps ContentPatchingOperationStatus to appropriate HTTP responses for PATCH operations.
|
||||
/// </summary>
|
||||
protected IActionResult ContentPatchingOperationStatusResult(ContentPatchingOperationStatus status)
|
||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
ContentPatchingOperationStatus.InvalidOperation => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Invalid operation")
|
||||
.WithDetail("One or more PATCH operations were invalid. Check operation structure, path syntax, and operation types.")
|
||||
.Build()),
|
||||
ContentPatchingOperationStatus.NotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("The document could not be found")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
|
||||
.WithTitle("Unknown error")
|
||||
.WithDetail("An unexpected error occurred during the PATCH operation.")
|
||||
.Build()),
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -17,6 +17,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Provides API endpoints for publishing documents within the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class PublishDocumentController : DocumentControllerBase
|
||||
{
|
||||
@@ -25,6 +28,13 @@ public class PublishDocumentController : DocumentControllerBase
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishDocumentController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize user actions.</param>
|
||||
/// <param name="contentPublishingService">Service responsible for publishing content.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
public PublishDocumentController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentPublishingService contentPublishingService,
|
||||
@@ -37,6 +47,20 @@ public class PublishDocumentController : DocumentControllerBase
|
||||
_documentPresentationFactory = documentPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes the specified document by its unique identifier, using the provided publish schedule and related data.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the document to be published.</param>
|
||||
/// <param name="requestModel">The request model containing publish schedules, cultures, and other publishing options.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> representing the result of the publish operation:
|
||||
/// <list type="bullet">
|
||||
/// <item><description><c>200 OK</c> if the document was published successfully.</description></item>
|
||||
/// <item><description><c>400 Bad Request</c> if the request is invalid or publishing fails due to validation errors.</description></item>
|
||||
/// <item><description><c>404 Not Found</c> if the document does not exist.</description></item>
|
||||
/// </list>
|
||||
/// </returns>
|
||||
[HttpPut("{id:guid}/publish")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+18
@@ -16,6 +16,9 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for publishing a document and all of its descendant documents in the content tree.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class PublishDocumentWithDescendantsController : DocumentControllerBase
|
||||
{
|
||||
@@ -23,6 +26,12 @@ public class PublishDocumentWithDescendantsController : DocumentControllerBase
|
||||
private readonly IContentPublishingService _contentPublishingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishDocumentWithDescendantsController"/> class, which handles publishing a document and its descendants in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize publishing actions.</param>
|
||||
/// <param name="contentPublishingService">Service responsible for executing content publishing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context and user information.</param>
|
||||
public PublishDocumentWithDescendantsController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentPublishingService contentPublishingService,
|
||||
@@ -33,6 +42,15 @@ public class PublishDocumentWithDescendantsController : DocumentControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes the specified document and all of its descendants.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the root document to publish along with its descendants.</param>
|
||||
/// <param name="requestModel">The request model specifying cultures to publish and additional publishing options.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing a <see cref="PublishWithDescendantsResultModel"/> if the operation is accepted, or a <see cref="ProblemDetails"/> if the request is invalid or the document is not found.
|
||||
/// </returns>
|
||||
[HttpPut("{id:guid}/publish-with-descendants")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PublishWithDescendantsResultModel), StatusCodes.Status200OK)]
|
||||
|
||||
+15
@@ -14,12 +14,20 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
/// <summary>
|
||||
/// Controller that handles results of publishing a document and its descendants.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class PublishDocumentWithDescendantsResultController : DocumentControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IContentPublishingService _contentPublishingService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishDocumentWithDescendantsResultController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">An instance of <see cref="IAuthorizationService"/> used to check user permissions.</param>
|
||||
/// <param name="contentPublishingService">An instance of <see cref="IContentPublishingService"/> used to publish content and its descendants.</param>
|
||||
public PublishDocumentWithDescendantsResultController(
|
||||
IAuthorizationService authorizationService,
|
||||
IContentPublishingService contentPublishingService)
|
||||
@@ -28,6 +36,13 @@ public class PublishDocumentWithDescendantsResultController : DocumentController
|
||||
_contentPublishingService = contentPublishingService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the status and result of a publish operation for a document and its descendants.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the document being published.</param>
|
||||
/// <param name="taskId">The unique identifier of the publish operation task.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the status and details of the publish operation, including whether it is complete and any relevant results.</returns>
|
||||
[HttpGet("{id:guid}/publish-with-descendants/result/{taskId:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PublishWithDescendantsResultModel), StatusCodes.Status200OK)]
|
||||
|
||||
+19
-1
@@ -1,4 +1,4 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
@@ -8,14 +8,32 @@ using Umbraco.Cms.Api.Management.ViewModels.Document.RecycleBin;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for managing operations related to the child documents within the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDocumentRecycleBinController : DocumentRecycleBinControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the recycle bin.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
public ChildrenDocumentRecycleBinController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of documents that are children of the specified parent document in the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="parentId">The unique identifier (GUID) of the parent document whose children are to be retrieved.</param>
|
||||
/// <param name="skip">The number of items to skip before starting to collect the result set. Defaults to 0.</param>
|
||||
/// <param name="take">The maximum number of items to return. Defaults to 100.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="ActionResult{T}"/> containing a <see cref="PagedViewModel{T}"/> of <see cref="DocumentRecycleBinItemResponseModel"/> representing the child documents in the recycle bin.
|
||||
/// </returns>
|
||||
[HttpGet("children")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<DocumentRecycleBinItemResponseModel>), StatusCodes.Status200OK)]
|
||||
|
||||
+18
@@ -16,6 +16,10 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling requests to delete items from the document recycle bin.
|
||||
/// Provides endpoints for permanently removing documents that have been moved to the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteDocumentRecycleBinController : DocumentRecycleBinControllerBase
|
||||
{
|
||||
@@ -23,6 +27,14 @@ public class DeleteDocumentRecycleBinController : DocumentRecycleBinControllerBa
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteDocumentRecycleBinController"/> class, which handles operations related to deleting items from the document recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used for entity operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
/// <param name="authorizationService">Service for handling authorization checks.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="contentEditingService">Service for editing content.</param>
|
||||
public DeleteDocumentRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IDocumentPresentationFactory documentPresentationFactory,
|
||||
@@ -36,6 +48,12 @@ public class DeleteDocumentRecycleBinController : DocumentRecycleBinControllerBa
|
||||
_contentEditingService = contentEditingService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes a document from the recycle bin, identified by the provided ID.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
|
||||
/// <param name="id">The unique identifier of the document to permanently delete from the recycle bin.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the result of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
|
||||
+9
-1
@@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Controllers.RecycleBin;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
@@ -13,6 +13,9 @@ using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for handling operations related to the document recycle bin in the management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.RecycleBin}/{Constants.UdiEntityType.Document}")]
|
||||
[RequireDocumentTreeRootAccess]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
|
||||
@@ -21,6 +24,11 @@ public class DocumentRecycleBinControllerBase : RecycleBinControllerBase<Documen
|
||||
{
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DocumentRecycleBinControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the recycle bin.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
public DocumentRecycleBinControllerBase(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService)
|
||||
=> _documentPresentationFactory = documentPresentationFactory;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user