Skip to content

Startup improvements#3928

Open
jmendeza wants to merge 14 commits into
craftercms:developfrom
jmendeza:feature/8652-5x
Open

Startup improvements#3928
jmendeza wants to merge 14 commits into
craftercms:developfrom
jmendeza:feature/8652-5x

Conversation

@jmendeza
Copy link
Copy Markdown
Member

@jmendeza jmendeza commented May 21, 2026

Startup improvements
craftercms/craftercms#8652

Summary by CodeRabbit

  • New Features

    • Enforced site bootstrap completion for relevant operations and added runtime tracking of site bootstrap state.
    • New API error reported when a site’s bootstrap is not complete.
  • Bug Fixes

    • Updated API error codes and responses to reflect site bootstrap state instead of organization-specific statuses.
  • Chores

    • Removed legacy WebDAV v1 and Elastic Transcoder integrations.
    • Removed organization-based management; group/user flows are now organization-agnostic.
    • Database schema bumped to 5.0.0.18 reflecting organization removal and bootstrap handling.
    • Refactored startup/upgrade bootstrap flow to event-driven coordination.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Walkthrough

This PR removes organization-scoped group and user management APIs, introduces per-site bootstrap state tracking with annotation-based operation gating, refactors the startup event flow using semaphore-based coordination between system and site upgrades, removes deprecated WebDAV and ElasticTranscoder features, and updates the database schema to version 5.0.0.18.

Changes

Organization Removal & Site Bootstrap State Gating

Layer / File(s) Summary
Site Bootstrap State Tracking Interface & Implementation
src/main/java/org/craftercms/studio/api/v2/utils/spring/context/SiteBootstrapStateProvider.java, src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/SiteBootstrapStateProviderImpl.java, src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java
Introduces SiteBootstrapStateProvider interface for querying/marking per-site bootstrap readiness, implements with thread-safe in-memory tracking, wires into SitesServiceInternalImpl.getAllSites() to check bootstrap state and return sites in BOOTSTRAPPING state when not ready.
Bootstrap Completion Annotation & AspectJ Guard Handler
src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteBootstrapComplete.java, src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteBootstrapCompleteAnnotationHandler.java
Adds @RequireSiteBootstrapComplete annotation targeting methods/types, implements AspectJ @Around handler that intercepts annotated calls, extracts site ID, checks siteBootstrapStateProvider.isSiteReady(siteId), and throws SiteBootstrapNotCompleteException when bootstrap incomplete.
Organization Removal from Service Contracts
src/main/java/org/craftercms/studio/api/v2/service/security/GroupService.java, src/main/java/org/craftercms/studio/api/v2/service/security/UserService.java
Updates GroupService to remove organization-scoped overloads (getAllGroups, getAllGroupsTotal, createGroup, updateGroup that accepted orgId), updates UserService to remove orgId from getAllUsersForSite and getAllUsersForSiteTotal.
Organization Removal from Service Implementations
src/main/java/org/craftercms/studio/impl/v2/service/security/GroupServiceImpl.java, src/main/java/org/craftercms/studio/impl/v2/service/security/UserServiceImpl.java, src/main/java/org/craftercms/studio/impl/v2/service/security/internal/GroupServiceInternalImpl.java, src/main/java/org/craftercms/studio/impl/v2/service/security/internal/UserServiceInternalImpl.java
Removes OrganizationServiceInternal dependency from GroupServiceImpl constructor, updates group/user listing methods to omit orgId parameter and organization-existence validation, delegates directly to internal service counterparts.
Organization Removal from DAL & Models
src/main/java/org/craftercms/studio/api/v2/dal/GroupDAO.java, src/main/java/org/craftercms/studio/api/v2/dal/Organization.java, src/main/java/org/craftercms/studio/api/v2/dal/AuditLog.java, src/main/java/org/craftercms/studio/api/v2/dal/Group.java, src/main/java/org/craftercms/studio/api/v2/dal/QueryParameterNames.java, src/main/java/org/craftercms/studio/api/v2/exception/OrganizationNotFoundException.java
Removes Organization DAL class, OrganizationNotFoundException exception, ORG_ID query parameter, organizationId from AuditLog, organization association from Group, and updates GroupDAO signatures to omit orgId.
REST Controller Organization Removal
src/main/java/org/craftercms/studio/controller/rest/v2/GroupsController.java, src/main/java/org/craftercms/studio/controller/rest/v2/UsersController.java, src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java
Removes DEFAULT_ORGANIZATION_ID usage from controller endpoints, updates service call signatures to omit orgId, removes OrganizationNotFoundException from throws clauses and exception handler.
Bootstrap Completion Gating Applied to Content Service
src/main/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImpl.java
Adds @RequireSiteBootstrapComplete to all public content operation endpoints (exists checks, retrieval, deletion, locking, moving, reads, version history, writes, copies, duplicates, listing).
Bootstrap Completion Gating Applied to Sites Service
src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java
Adds @RequireSiteBootstrapComplete to site operation endpoints (updateSite, unlockSite, deleteSite, getPublishingStatus, enablePublishing, duplicate).
Bootstrap/Upgrade Event Flow Refactoring
src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java, src/main/java/org/craftercms/studio/impl/v2/utils/spring/event/StartSitesBootstrapEvent.java, src/main/java/org/craftercms/studio/impl/v2/utils/spring/event/StartSitesUpgradeEvent.java, src/main/java/org/craftercms/studio/impl/v2/utils/spring/event/StartSystemUpgradeEvent.java
Refactors BootstrapManagerImpl to use semaphore-based coordination, splits upgrade flow into StartSystemUpgradeEvent (blueprint/db) and StartSitesUpgradeEvent (per-site), renames events, adds ApplicationEventPublisherAware for event publication.
Upgrade Manager Bootstrap State Integration
src/main/java/org/craftercms/studio/impl/v2/upgrade/StudioUpgradeManagerImpl.java
Wires SiteBootstrapStateProvider into constructor, marks sites as ready after configuration upgrade, splits startUpgrade() listener into separate system and sites upgrade handlers.
Startup Configuration & Event Listener Updates
src/main/java/org/craftercms/studio/impl/v2/repository/GitStartupConfig.java, src/main/java/org/craftercms/studio/impl/v2/repository/RepositoryStartupCleanup.java, src/main/java/org/craftercms/studio/api/v2/utils/spring/context/BootstrapManager.java
Updates GitStartupConfig to listen on ContextRefreshedEvent (root context) with execution-time logging, adds @LogExecutionTime to RepositoryStartupCleanup, introduces BootstrapManager interface for lifecycle hooks.
Database Schema & DAL Mapper Updates
src/main/resources/crafter/studio/database/createDDL.sql, src/main/resources/crafter/studio/database/upgrade/5.0.x/5.0.0.17-to-5.0.0.18.sql, src/main/resources/org/craftercms/studio/api/v2/dal/AuditDAO.xml, src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml
Updates schema to version 5.0.0.18, removes organization and organization_user tables, removes org_id from group, updates migration script to drop organization references, removes organizationId mapping from AuditDAO.xml, updates GroupDAO.xml queries to omit org_id.
Spring Bean & XML Configuration
src/main/resources/crafter/studio/studio-services-context.xml, src/main/resources/crafter/studio/security/common.xml, src/main/resources/crafter/studio/studio-config.yaml, src/main/resources/crafter/studio/studio-upgrade-context.xml, src/main/resources/crafter/studio/studio-websocket-context.xml, src/main/resources/crafter/studio/upgrade/pipelines.yaml
Converts repositoryStartupCleanup to conditional bean, changes bootstrapManager to BootstrapManagerImpl, adds siteBootstrapStateProvider bean, removes organizationServiceInternal, removes transcoder/WebDAV beans, adds bootstrap annotation handler bean, adds startup cleanup config property, corrects pipeline YAML structure.
Legacy Feature & Deprecation Cleanup
src/main/java/org/craftercms/studio/api/v1/aws/elastictranscoder/ElasticTranscoder.java, src/main/java/org/craftercms/studio/impl/v1/aws/elastictranscoder/TranscoderProfileMapper.java, src/main/java/org/craftercms/studio/api/v1/service/webdav/WebDavService.java, src/main/java/org/craftercms/studio/impl/v1/service/webdav/WebDavServiceImpl.java, src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/plugin/DescriptorV2UpgradeOperation.java, src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AddSiteUuidOperation.java, src/main/java/org/craftercms/studio/api/v1/constant/StudioConstants.java, src/main/java/org/craftercms/studio/model/rest/ApiResponse.java
Removes ElasticTranscoder interface and TranscoderProfileMapper implementation, removes deprecated WebDAV v1 WebDavService interface and WebDavServiceImpl, removes DescriptorV2UpgradeOperation and AddSiteUuidOperation upgrade operations, removes DEFAULT_ORGANIZATION_ID constant, removes organization-related ApiResponse codes (ORG_NOT_FOUND, ORG_ALREADY_EXISTS), adds SITE_BOOTSTRAP_NOT_COMPLETE code.
Miscellaneous Updates & Tests
src/main/java/org/craftercms/studio/impl/v1/service/content/DmPageNavigationOrderServiceImpl.java, src/test/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImplTest.java, src/main/java/org/craftercms/studio/impl/v2/service/audit/internal/AuditServiceInternalImpl.java
Updates copyright years across files (2025/2022 → 2026), reorders imports, updates test to use AnnotationUtils.getAnnotation() for annotation presence checks, adds Site.State.BOOTSTRAPPING constant.

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • sumerjabri
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java`:
- Around line 129-132: The enablePublishing method is annotated with
`@RequireSiteBootstrapComplete` but its siteId parameter lacks the `@SiteId`
annotation so the bootstrap aspect cannot reliably resolve the target site;
update the method signature for enablePublishing to annotate the siteId
parameter with `@SiteId` in addition to the existing
`@ProtectedResourceId`(SITE_ID_RESOURCE_ID) so the bootstrap gating aspect can
correctly resolve and validate the site before calling
sitesServiceInternal.enablePublishing.

In
`@src/main/java/org/craftercms/studio/impl/v2/upgrade/StudioUpgradeManagerImpl.java`:
- Around line 139-141: The call to siteBootstrapStateProvider.markSiteAsReady is
executed unconditionally even though upgradeSiteConfiguration catches and
swallows errors; change the flow so the site is only marked ready when the
config upgrade actually succeeded by having upgradeSiteConfiguration report
success (e.g., return boolean or throw on failure) and update
StudioUpgradeManagerImpl to check that result before calling
siteBootstrapStateProvider.markSiteAsReady(context.getTarget()); alternatively
catch specific exceptions around upgradeSiteConfiguration here and skip marking
ready on failure, ensuring upgradeSiteConfiguration and/or the caller use clear
success/failure signaling rather than logging-only.

In
`@src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java`:
- Around line 87-94: The catch for InterruptedException in BootstrapManagerImpl
currently logs and restores the interrupt but then lets execution continue and
returns a StartSitesUpgradeEvent; change the catch to stop the flow by either
rethrowing a runtime exception or returning a no-op (do not produce
StartSitesUpgradeEvent). Concretely, inside the catch where
upgradeSemaphore.acquire() is handled, after Thread.currentThread().interrupt()
either throw a new IllegalStateException("Interrupted waiting for system
upgrade", e) (so callers won't start site upgrades) or return null/a dedicated
abort event instead of falling through to return new
StartSitesUpgradeEvent(this); update any callers if you choose to return null to
handle the abort case.

In `@src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml`:
- Around line 53-71: The mapper IDs in GroupDAO.xml don't match the DAO method
names; rename the <select> id "getAllGroups" to "getAllGroupsForOrganization"
and "getAllGroupsTotal" to "getAllGroupsForOrganizationTotal" so MyBatis can
bind to the GroupDAO methods; keep the existing resultMap/resultType, parameter
bindings (keyword -> pattern bind), and SQL clauses unchanged, only update the
id attributes to exactly match the GroupDAO method names.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5a58e55f-7793-42e2-afec-b0517e741d2c

📥 Commits

Reviewing files that changed from the base of the PR and between c7abf4e and 32a6f03.

📒 Files selected for processing (54)
  • src/main/api/studio-api.yaml
  • src/main/java/org/craftercms/studio/api/v1/aws/elastictranscoder/ElasticTranscoder.java
  • src/main/java/org/craftercms/studio/api/v1/constant/StudioConstants.java
  • src/main/java/org/craftercms/studio/api/v1/service/webdav/WebDavService.java
  • src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteBootstrapComplete.java
  • src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteBootstrapCompleteAnnotationHandler.java
  • src/main/java/org/craftercms/studio/api/v2/dal/AuditLog.java
  • src/main/java/org/craftercms/studio/api/v2/dal/Group.java
  • src/main/java/org/craftercms/studio/api/v2/dal/GroupDAO.java
  • src/main/java/org/craftercms/studio/api/v2/dal/Organization.java
  • src/main/java/org/craftercms/studio/api/v2/dal/QueryParameterNames.java
  • src/main/java/org/craftercms/studio/api/v2/dal/Site.java
  • src/main/java/org/craftercms/studio/api/v2/exception/OrganizationNotFoundException.java
  • src/main/java/org/craftercms/studio/api/v2/exception/SiteBootstrapNotCompleteException.java
  • src/main/java/org/craftercms/studio/api/v2/service/security/GroupService.java
  • src/main/java/org/craftercms/studio/api/v2/service/security/UserService.java
  • src/main/java/org/craftercms/studio/api/v2/utils/spring/context/BootstrapManager.java
  • src/main/java/org/craftercms/studio/api/v2/utils/spring/context/SiteBootstrapStateProvider.java
  • src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java
  • src/main/java/org/craftercms/studio/controller/rest/v2/GroupsController.java
  • src/main/java/org/craftercms/studio/controller/rest/v2/UsersController.java
  • src/main/java/org/craftercms/studio/impl/v1/aws/elastictranscoder/TranscoderProfileMapper.java
  • src/main/java/org/craftercms/studio/impl/v1/service/content/DmPageNavigationOrderServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v1/service/webdav/WebDavServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/repository/GitStartupConfig.java
  • src/main/java/org/craftercms/studio/impl/v2/repository/RepositoryStartupCleanup.java
  • src/main/java/org/craftercms/studio/impl/v2/service/audit/internal/AuditServiceInternalImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/security/GroupServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/security/UserServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/security/internal/GroupServiceInternalImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/security/internal/UserServiceInternalImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/upgrade/StudioUpgradeManagerImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/plugin/DescriptorV2UpgradeOperation.java
  • src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AddSiteUuidOperation.java
  • src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/SiteBootstrapStateProviderImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/utils/spring/event/StartSitesBootstrapEvent.java
  • src/main/java/org/craftercms/studio/impl/v2/utils/spring/event/StartSitesUpgradeEvent.java
  • src/main/java/org/craftercms/studio/impl/v2/utils/spring/event/StartSystemUpgradeEvent.java
  • src/main/java/org/craftercms/studio/model/rest/ApiResponse.java
  • src/main/resources/crafter/studio/database/createDDL.sql
  • src/main/resources/crafter/studio/database/upgrade/5.0.x/5.0.0.17-to-5.0.0.18.sql
  • src/main/resources/crafter/studio/security/common.xml
  • src/main/resources/crafter/studio/studio-config.yaml
  • src/main/resources/crafter/studio/studio-services-context.xml
  • src/main/resources/crafter/studio/studio-upgrade-context.xml
  • src/main/resources/crafter/studio/studio-websocket-context.xml
  • src/main/resources/crafter/studio/upgrade/pipelines.yaml
  • src/main/resources/org/craftercms/studio/api/v2/dal/AuditDAO.xml
  • src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml
  • src/test/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImplTest.java
💤 Files with no reviewable changes (11)
  • src/main/java/org/craftercms/studio/api/v1/constant/StudioConstants.java
  • src/main/java/org/craftercms/studio/api/v1/aws/elastictranscoder/ElasticTranscoder.java
  • src/main/java/org/craftercms/studio/controller/rest/v2/ExceptionHandlers.java
  • src/main/java/org/craftercms/studio/impl/v1/aws/elastictranscoder/TranscoderProfileMapper.java
  • src/main/java/org/craftercms/studio/api/v1/service/webdav/WebDavService.java
  • src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AddSiteUuidOperation.java
  • src/main/java/org/craftercms/studio/api/v2/dal/Organization.java
  • src/main/java/org/craftercms/studio/api/v2/exception/OrganizationNotFoundException.java
  • src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/plugin/DescriptorV2UpgradeOperation.java
  • src/main/resources/crafter/studio/studio-upgrade-context.xml
  • src/main/java/org/craftercms/studio/impl/v1/service/webdav/WebDavServiceImpl.java

Comment thread src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml
@jmendeza jmendeza marked this pull request as ready for review May 22, 2026 15:53
@jmendeza jmendeza requested a review from sumerjabri as a code owner May 22, 2026 15:53
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java (1)

101-105: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

BootstrapFinishedEvent fires before site bootstrap completes.

This listener releases the semaphore and immediately returns BootstrapFinishedEvent, but the sites bootstrap path is still running on the async branch. That means systemReady can flip to true while repository cleanup / site upgrade work is still in flight. Please move the finished event to the end of the sites-bootstrap chain instead of emitting it from system-upgrade completion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java`
around lines 101 - 105, The onStartSystemUpgrade() listener currently releases
the upgradeSemaphore and immediately returns a new BootstrapFinishedEvent(this),
causing BootstrapFinishedEvent to fire before async site bootstrap work
finishes; remove the return/new event from onStartSystemUpgrade() (keep
upgradeSemaphore.release()) and instead publish/return BootstrapFinishedEvent at
the very end of the sites-bootstrap async chain (after all repository
cleanup/site upgrade work completes) so that BootstrapFinishedEvent is emitted
only when the sites-bootstrap flow has fully finished.
src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java (1)

601-608: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Bootstrap-aware state is only applied to the list path.

getAllSites() rewrites READY to BOOTSTRAPPING, but getSite() and getSiteDetails() still return the raw DAO state. That lets the same site appear bootstrapping in list responses and ready in detail reads. Please centralize this state decoration and reuse it for single-site reads as well.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java`
around lines 601 - 608, The list method getAllSites() currently mutates READY ->
BOOTSTRAPPING inline; extract that logic into a single reusable helper (e.g.,
decorateSiteState(Site) or decorateSites(List<Site>)) and call it from
getAllSites(), getSite(), and getSiteDetails() so single-site reads are
decorated the same way; use the same symbols siteBootstrapStateProvider,
Site.State.READY, and Site.State.BOOTSTRAPPING and avoid duplicating
state-mutation logic by reusing the helper from the service methods that return
one or many Site objects.
♻️ Duplicate comments (1)
src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java (1)

129-131: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep @ProtectedResourceId(SITE_ID_RESOURCE_ID) on enablePublishing.

Replacing it with @SiteId fixes bootstrap resolution, but it drops the resource binding used by the permission check on this endpoint. This regresses the earlier fix; the parameter needs both annotations.

💡 Proposed fix
-	public void enablePublishing(`@SiteId` String siteId, boolean enabled) {
+	public void enablePublishing(`@SiteId` `@ProtectedResourceId`(SITE_ID_RESOURCE_ID) String siteId, boolean enabled) {
 		sitesServiceInternal.enablePublishing(siteId, enabled);
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java`
around lines 129 - 131, The enablePublishing method lost its resource binding
when `@ProtectedResourceId`(SITE_ID_RESOURCE_ID) was removed; restore permission
checks by annotating the siteId parameter with both `@SiteId` and
`@ProtectedResourceId`(SITE_ID_RESOURCE_ID) so RequireSiteBootstrapComplete and
HasPermission (DefaultPermission, PERMISSION_START_STOP_PUBLISHER) still work
together for permission resolution and bootstrap handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java`:
- Around line 601-608: The list method getAllSites() currently mutates READY ->
BOOTSTRAPPING inline; extract that logic into a single reusable helper (e.g.,
decorateSiteState(Site) or decorateSites(List<Site>)) and call it from
getAllSites(), getSite(), and getSiteDetails() so single-site reads are
decorated the same way; use the same symbols siteBootstrapStateProvider,
Site.State.READY, and Site.State.BOOTSTRAPPING and avoid duplicating
state-mutation logic by reusing the helper from the service methods that return
one or many Site objects.

In
`@src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java`:
- Around line 101-105: The onStartSystemUpgrade() listener currently releases
the upgradeSemaphore and immediately returns a new BootstrapFinishedEvent(this),
causing BootstrapFinishedEvent to fire before async site bootstrap work
finishes; remove the return/new event from onStartSystemUpgrade() (keep
upgradeSemaphore.release()) and instead publish/return BootstrapFinishedEvent at
the very end of the sites-bootstrap async chain (after all repository
cleanup/site upgrade work completes) so that BootstrapFinishedEvent is emitted
only when the sites-bootstrap flow has fully finished.

---

Duplicate comments:
In
`@src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java`:
- Around line 129-131: The enablePublishing method lost its resource binding
when `@ProtectedResourceId`(SITE_ID_RESOURCE_ID) was removed; restore permission
checks by annotating the siteId parameter with both `@SiteId` and
`@ProtectedResourceId`(SITE_ID_RESOURCE_ID) so RequireSiteBootstrapComplete and
HasPermission (DefaultPermission, PERMISSION_START_STOP_PUBLISHER) still work
together for permission resolution and bootstrap handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d8b2a12-541c-4923-a311-19cb13108fdb

📥 Commits

Reviewing files that changed from the base of the PR and between 32a6f03 and 002e657.

📒 Files selected for processing (5)
  • src/main/java/org/craftercms/studio/api/v2/dal/GroupDAO.java
  • src/main/java/org/craftercms/studio/impl/v2/service/security/internal/GroupServiceInternalImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java
  • src/main/java/org/craftercms/studio/impl/v2/utils/spring/context/BootstrapManagerImpl.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant