Skip to content

Added full content management to the API service, Australian date formats and 'work' project aliases. - #283

Merged
AlexSkrypnyk merged 5 commits into
developfrom
feature/api-perms-au-dates
Aug 4, 2026
Merged

Added full content management to the API service, Australian date formats and 'work' project aliases.#283
AlexSkrypnyk merged 5 commits into
developfrom
feature/api-perms-au-dates

Conversation

@AlexSkrypnyk

Copy link
Copy Markdown
Member

Checklist before requesting a review

  • Subject includes ticket number as [#123] Verb in past tense.
  • Ticket number #123 added to description
  • Added context in Changed section
  • Self-reviewed code and commented in commented complex areas.
  • Added tests for fix/feature.
  • Relevant tests run and passed locally.

Changed

  1. Granted the content API service account full content management. config/default/user.role.do_content_api.yml previously granted create + edit-own only. It now also grants administer nodes (labelled "Administer content" in the permissions UI), access content overview, edit any and delete any for all five bundles (blog, civictheme_alert, civictheme_event, civictheme_page, project), view any unpublished content, view latest version, and every remaining transition of the civictheme_editorial workflow (archive, restore, restore_to_draft, restore_to_needs_review, send_back_to_draft). The workflow transitions matter for a non-obvious reason: content_moderation forbids an update outright when the account holds no valid transition out of the entity's current state, so without them archived content was deletable but not editable on every bundle. Verified against real data: all 19 bundle/moderation-state combinations now allow view, update and delete. bypass node access was deliberately not used - the role enumerates bundles explicitly so a future content type is a deliberate grant rather than an automatic one. docs/content-api.md was rewritten to describe the account accurately, including that the draft-on-create rule covers creation only (an update may publish) and that media access stays narrower; the reconciliation comment in do_content_api.deploy.php was updated to match, since the role is no longer least-privilege. A new unit test ServiceRolePermissionsTest pins the exported permission array to an exact allow-list plus semantic assertions (every creatable bundle is also editable and deletable, every workflow transition is granted, the role is not is_admin, media edit/delete are withheld).
  2. Switched date formats and regional settings from American to Australian. core.date_format.short (m/d/Y - H:id/m/Y - H:i), medium (D, m/d/Y - H:iD, d/m/Y - H:i), fallback (same change as medium), and long (l, F j, Y - H:il, j F Y - H:i). system.date.yml gains first_day: 1 (Monday) and country.default: AU; its timezone was already Australia/Melbourne. The medium format is public-facing, not admin-only: core.entity_view_display.node.civictheme_event.default.yml renders event date ranges with format_type: medium. The seven html_* formats are deliberately left as ISO 8601 - they populate the datetime attribute of <time> elements and HTML5 date input values, where the format is fixed by specification. A new unit test DateFormatConfigTest renders every shipped pattern against a fixed reference date (4 August 2026, 14:30) and asserts the exact Australian output, asserts the html_* patterns stay ISO, and asserts the regional settings.
  3. Moved project URL aliases from /projects/ to /work/. pathauto.pattern.project.yml changes from /projects/[node:title] to /work/[node:title], nesting projects under the existing "Our work" landing page already at /work. A new deploy hook do_base_deploy_move_projects_to_work() in do_base.deploy.php regenerates existing aliases through pathauto, batched via Helper::entity()->batchQuery(); its query on path_alias doubles as the idempotency guard, since a regenerated alias no longer matches /projects/%. Because redirect.settings.auto_redirect is true, each rename leaves a 301 behind automatically - verified: 20 aliases moved, 20 301 redirects created, the old URL 301s to the new one, and the new URL returns 200. The XML sitemap needs no extra work because it stores internal paths (/node/N) and resolves aliases at generation time - verified: 18 /work/ URLs and 0 /projects/ URLs after regeneration. Behat assertions in project_content_type.feature and xmlsitemap.feature were updated, and a new PathautoPatternConfigTest pins each bundle's alias prefix and confirms each pattern is scoped to its own bundle.

Screenshots

Admin content listing showing day-first Australian dates

Before / After

┌──────────────────────────────────────────────┬──────────────────────────────────────────────┐
│ BEFORE                                       │ AFTER                                        │
├──────────────────────────────────────────────┼──────────────────────────────────────────────┤
│ API role: create + edit-own only, 5 bundles  │ API role: + edit any + delete any, 5 bundles │
│ No archive / restore / send-back transitions │ + archive, restore, restore-to-*, send-back  │
│ Cannot view unpublished or pending revisions │ + view any unpublished, view latest version  │
├──────────────────────────────────────────────┼──────────────────────────────────────────────┤
│ Date: 08/04/2026 - 14:30  (m/d/Y, US order)  │ Date: 04/08/2026 - 14:30  (d/m/Y, AU order)  │
│ Week starts Sunday, country: (none)          │ Week starts Monday, country: AU              │
├──────────────────────────────────────────────┼──────────────────────────────────────────────┤
│ URL: /projects/example-project               │ URL: /work/example-project                   │
│ (no redirect recorded)                       │ old URL 301-redirects to the new URL         │
└──────────────────────────────────────────────┴──────────────────────────────────────────────┘

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 59 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 48689d0a-af1c-443e-bea1-e59b03903058

📥 Commits

Reviewing files that changed from the base of the PR and between db29116 and d2be948.

📒 Files selected for processing (15)
  • config/default/core.date_format.fallback.yml
  • config/default/core.date_format.long.yml
  • config/default/core.date_format.medium.yml
  • config/default/core.date_format.short.yml
  • config/default/pathauto.pattern.project.yml
  • config/default/system.date.yml
  • config/default/user.role.do_content_api.yml
  • docs/content-api.md
  • tests/behat/features/project_content_type.feature
  • tests/behat/features/xmlsitemap.feature
  • web/modules/custom/do_base/do_base.deploy.php
  • web/modules/custom/do_base/tests/src/Unit/DateFormatConfigTest.php
  • web/modules/custom/do_base/tests/src/Unit/PathautoPatternConfigTest.php
  • web/modules/custom/do_content_api/do_content_api.deploy.php
  • web/modules/custom/do_content_api/tests/src/Unit/ServiceRolePermissionsTest.php

Comment @coderabbitai help to get the list of available commands.

@AlexSkrypnyk AlexSkrypnyk added the AUTOMERGE Pull request has been approved and set to automerge label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Code coverage (threshold: 80%)

  Classes: 52.94% (9/17)
  Methods: 70.27% (26/37)
  Lines:   91.13% (370/406)
Per-class coverage
Drupal\do_content_api\EventSubscriber\JsonApiWriteGateSubscriber
  Methods:  66.67% ( 2/ 3)   Lines:  88.89% (  8/  9)
Drupal\do_content_api\Hook\EntityCreateAccessHook
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  9/  9)
Drupal\do_content_api\Hook\ModerationPolicyHook
  Methods:  50.00% ( 1/ 2)   Lines:  93.75% ( 15/ 16)
Drupal\do_content_api\Routing\RouteSubscriber
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  6/  6)
Drupal\do_feed\FeedUrlBuilder
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 18/ 18)
Drupal\do_feed\Form\FeedSettingsForm
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 15/ 15)
Drupal\do_feed\Hook\EntityDeleteHook
  Methods:  50.00% ( 1/ 2)   Lines:  92.31% ( 12/ 13)
Drupal\do_feed\Hook\EntityPresaveHook
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 54/ 54)
Drupal\do_feed\Hook\PreprocessParagraphHook
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% ( 14/ 14)
Drupal\do_feed\Hook\PreprocessViewsViewRowRssHook
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  3/  3)
Drupal\do_feed\Hook\ViewsPreViewHook
  Methods:  50.00% ( 1/ 2)   Lines:  96.43% ( 27/ 28)
Drupal\do_generated_content\Generator\CaseMatrix
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 12/ 12)
Drupal\do_generated_content\Generator\RelativeDate
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.84%. Comparing base (db29116) to head (d2be948).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop     #283   +/-   ##
========================================
  Coverage    85.84%   85.84%           
========================================
  Files           18       18           
  Lines          226      226           
========================================
  Hits           194      194           
  Misses          32       32           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Aug 4, 2026
@AlexSkrypnyk
AlexSkrypnyk requested a deployment to PR-283 August 4, 2026 03:28 Abandoned
@AlexSkrypnyk
AlexSkrypnyk merged commit f52e967 into develop Aug 4, 2026
10 checks passed
@AlexSkrypnyk
AlexSkrypnyk deleted the feature/api-perms-au-dates branch August 4, 2026 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AUTOMERGE Pull request has been approved and set to automerge Needs review Pull request needs a review from assigned developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants