Skip to content

refactor: site rename add to create - #113

Merged
loadinglucian merged 7 commits into
mainfrom
refactor/site-rename-add-to-create
Dec 4, 2025
Merged

refactor: site rename add to create#113
loadinglucian merged 7 commits into
mainfrom
refactor/site-rename-add-to-create

Conversation

@loadinglucian

@loadinglucian loadinglucian commented Dec 4, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Optional repo/branch inputs for deploy/site commands; inventory can be updated when provided.
    • Post-operation “next steps” guidance shown after server and site actions.
  • Changes

    • Site workflow terminology changed from "Add" → "Create" (site:create); prompts and help updated accordingly.
    • Messaging standardized (e.g., "remove" → "delete"); playbook/help texts revised.
    • Removed scaffold hello command from CLI.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 4, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Renames site "add" to "create" across commands and playbooks, removes HelloCommand, makes SiteDTO repo/branch nullable, adds SiteRepository::update(), enhances SiteDeployCommand with repo/branch resolution and inventory updates, and standardizes messaging and CLI descriptions.

Changes

Cohort / File(s) Summary
Development Rules Update
\.cursor/rules/00-main.mdc
Added File Operations subsection, expanded Execution Protocol with STEP BY STEP and ACT steps, and introduced "Test later" guidance.
Console command removed
app/Console/HelloCommand.php
Deleted HelloCommand class and its registration/imports.
Server commands (metadata & messaging)
app/Console/Server/ServerAddCommand.php, app/Console/Server/ServerListCommand.php, app/Console/Server/ServerDeleteCommand.php, app/Console/Server/ServerInstallCommand.php, app/Console/Server/ServerProvisionDigitalOceanCommand.php
Normalized command descriptions, adjusted deletion/install wording, and added post-add usage hints in ServerAdd flows.
Site create/refactor & registration
app/Console/Site/SiteCreateCommand.php, app/SymfonyApp.php, app/Console/Site/SiteListCommand.php, app/Console/Site/SiteHttpsCommand.php, app/Console/Site/SiteDeleteCommand.php
Renamed SiteAdd → SiteCreate and AsCommand names; removed git options from create; updated SymfonyApp registration; changed messages to use "create"/"delete" and site:create references.
Site deploy enhancements
app/Console/Site/SiteDeployCommand.php
Added --repo and --branch options and new resolveRepoAndBranch() helper; resolve repo/branch before deploy, update inventory when changed, and add stricter null/empty checks.
DTO nullability
app/DTOs/SiteDTO.php
Made repo and branch constructor parameters and properties nullable (?string).
Repository updates
app/Repositories/SiteRepository.php
Added public function update(SiteDTO $site): void; refactored hydrate/dehydrate to omit repo/branch when null and to persist nullable values.
Traits & helpers
app/Traits/SitesTrait.php
Terminology updates (site:add → site:create), stricter comparisons (e.g., 0 === count(...), null ===), conditional Repo/Branch display, and minor spacing/doc fixes.
Playbooks (rename & messaging)
playbooks/site-create.sh, playbooks/site-delete.sh
Updated playbook descriptions to "create", renamed remove_* functions to delete_*, adjusted call sites and user-facing messages.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review hotspots:
    • app/Console/Site/SiteDeployCommand.php — new CLI options, resolveRepoAndBranch(), inventory update and replay payload changes.
    • app/Repositories/SiteRepository.php — new update() and hydrate/dehydrate changes for nullable repo/branch.
    • app/DTOs/SiteDTO.php and all call sites — ensure nullable repo/branch handling is safe.
    • app/Console/Site/SiteCreateCommand.php & app/Traits/SitesTrait.php — removal of git options and message/validation consistency.
    • playbooks/site-delete.sh — renamed functions and their call sites.

Possibly related PRs

Poem

🐰 I hopped from add to create with glee,

Goodbye hello, inventory set free.
Repos nullable, branches take flight,
Playbooks renamed, messages bright,
A rabbit's cheer for tidy code tonight 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: site rename add to create' accurately describes the primary change in the changeset—renaming the site:add command to site:create throughout the codebase and related refactoring.
Docstring Coverage ✅ Passed Docstring coverage is 97.44% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/site-rename-add-to-create

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
.cursor/rules/00-main.mdc (1)

60-62: Tighten conversational prose in "Test later" section to imperative mood.

Line 62 ("Tests are something we will focus on...") shifts to conversational explanation rather than maintaining the imperative directive tone required in rule files. Based on learnings, rule files should use imperative mood throughout.

Apply this diff to align with imperative mood:

 ### Test later
 
-Don't run or create or update tests UNLESS explicitly instructed to do so.
-
-Tests are something we will focus on separately from building features.
+Do not run, create, or update tests unless explicitly instructed.
app/Console/Site/SiteHttpsCommand.php (1)

105-105: Inconsistent terminology: "re-add" should be "re-create".

Line 105 still references "re-add the site" which is inconsistent with the PR's terminology refactoring from "add" to "create". For consistency, this should be updated to "re-create the site".

Apply this diff to maintain consistent terminology:

-            $this->nay("Could not detect PHP version for '{$site->domain}' from server config; re-add the site or run server:info to debug.");
+            $this->nay("Could not detect PHP version for '{$site->domain}' from server config; re-create the site or run server:info to debug.");
🧹 Nitpick comments (3)
app/Console/Server/ServerDeleteCommand.php (1)

183-183: Terminology normalized for consistency.

The change aligns the success message with the informational messages on lines 85 and 97, creating consistency within the command flow. While the command name and description still use "delete", the distinction between "delete" (the overall operation) and "remove from inventory" (the specific inventory action) appears intentional.

If full consistency is desired, consider updating line 18 as well:

-    description: 'Delete a server from inventory'
+    description: 'Remove a server from inventory'
app/Console/Site/SiteDeployCommand.php (1)

260-266: Consider conditional inclusion of repo/branch in replay payload.

Per the learning about commandReplay(): "only include conditional options if they were actually used." Since repo and branch are now always included regardless of whether they came from stored values or CLI input, the replay command will always contain these options.

If the intent is for users to replay with minimal options (relying on stored values), consider including repo/branch only when they were explicitly provided via CLI or prompted.

 $this->commandReplay('site:deploy', [
     'domain' => $site->domain,
-    'repo' => $repo,
-    'branch' => $branch,
+    ...($needsUpdate ? ['repo' => $repo, 'branch' => $branch] : []),
     'keep-releases' => $keepReleases,
     'yes' => true,
 ]);
app/Console/Site/SiteCreateCommand.php (1)

180-191: Align validateServerReady docblock wording with “create” terminology

The tightened Caddy availability check (true === ($info['caddy']['available'] ?? false)) is a nice improvement, and the overall validation logic is straightforward.

The docblock summary still says “ready to add site”, which is now out of sync with the command’s terminology. Consider updating for clarity:

-     * Validate that server is ready to add site.
+     * Validate that server is ready to create a site.

Also applies to: 193-206

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b66ea8 and 095ad6f.

📒 Files selected for processing (18)
  • .cursor/rules/00-main.mdc (1 hunks)
  • app/Console/HelloCommand.php (0 hunks)
  • app/Console/Server/ServerAddCommand.php (2 hunks)
  • app/Console/Server/ServerDeleteCommand.php (1 hunks)
  • app/Console/Server/ServerInstallCommand.php (1 hunks)
  • app/Console/Server/ServerListCommand.php (1 hunks)
  • app/Console/Server/ServerProvisionDigitalOceanCommand.php (1 hunks)
  • app/Console/Site/SiteCreateCommand.php (13 hunks)
  • app/Console/Site/SiteDeleteCommand.php (5 hunks)
  • app/Console/Site/SiteDeployCommand.php (15 hunks)
  • app/Console/Site/SiteHttpsCommand.php (1 hunks)
  • app/Console/Site/SiteListCommand.php (1 hunks)
  • app/DTOs/SiteDTO.php (1 hunks)
  • app/Repositories/SiteRepository.php (3 hunks)
  • app/SymfonyApp.php (2 hunks)
  • app/Traits/SitesTrait.php (10 hunks)
  • playbooks/site-create.sh (2 hunks)
  • playbooks/site-delete.sh (4 hunks)
💤 Files with no reviewable changes (1)
  • app/Console/HelloCommand.php
🧰 Additional context used
📓 Path-based instructions (5)
**/*.php

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

**/*.php: Eliminate single-use methods: inline if called once
Cache computed values: initialize expensive calculations in constructor
Avoid method call overhead: direct property access when appropriate
Group related functions into comment-separated sections
Order alphabetically after grouping logically

**/*.php: Follow PSR-12 standard with strict types enabled and use PHP 8.x features (unions, match, attributes, readonly)
Use explicit return types with generics (e.g., Collection<int, User>) for all functions and methods
Use dependency injection via Symfony patterns for all object dependencies
Use Symfony classes over native PHP functions (Filesystem, Process) for testability
Always use Yoda conditions: place constants/literals on the LEFT side of comparisons (e.g., null === $value) to prevent accidental assignment
Always use braces for ALL control structures (if, else, elseif, for, foreach, while, do-while), even for single-line bodies
Use @var annotations to help PHPStan understand types it cannot infer, not assert() in production code
Always add use statements for vendor packages and project classes; root namespace FQDNs acceptable for built-in exceptions (e.g., \InvalidArgumentException)
Use $container->build(ClassName::class) for all object creation; use this except for DTOs, value objects, and pure data structures
Use constructor injection in production code and direct instantiation in tests for container access
All object dependencies must be declared in constructor signatures; NO circular dependencies allowed
Use minimalist DocBlock descriptions with parameters and return types for classes and functions; separate sections visually with one newline between headers/paragraphs

**/*.php: Services and Repositories must throw \RuntimeException with complete, actionable messages that include relevant context (paths, names, IDs, hosts) and are user-facing, not fragments
When catching and re-throwing exceptions in Services and Repositories, use t...

Files:

  • app/Console/Server/ServerInstallCommand.php
  • app/Console/Server/ServerProvisionDigitalOceanCommand.php
  • app/Console/Server/ServerListCommand.php
  • app/DTOs/SiteDTO.php
  • app/Console/Server/ServerDeleteCommand.php
  • app/Console/Server/ServerAddCommand.php
  • app/Console/Site/SiteDeleteCommand.php
  • app/Console/Site/SiteListCommand.php
  • app/Console/Site/SiteHttpsCommand.php
  • app/Traits/SitesTrait.php
  • app/Console/Site/SiteCreateCommand.php
  • app/Console/Site/SiteDeployCommand.php
  • app/Repositories/SiteRepository.php
  • app/SymfonyApp.php
**/*Command.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Command Layer: handle user interaction and orchestrate Services; contain NO business logic, NO duplicate orchestration, NO invocation of other commands

**/*Command.php: Command layer (Commands and Orchestration Traits) must display caught \RuntimeException messages directly without adding redundant prefixes like 'Failed to...'
Only add contextual information to exception displays in Command layer when necessary: raw output for debugging, actionable troubleshooting steps, or when the exception message is too technical/generic

Files:

  • app/Console/Server/ServerInstallCommand.php
  • app/Console/Server/ServerProvisionDigitalOceanCommand.php
  • app/Console/Server/ServerListCommand.php
  • app/Console/Server/ServerDeleteCommand.php
  • app/Console/Server/ServerAddCommand.php
  • app/Console/Site/SiteDeleteCommand.php
  • app/Console/Site/SiteListCommand.php
  • app/Console/Site/SiteHttpsCommand.php
  • app/Console/Site/SiteCreateCommand.php
  • app/Console/Site/SiteDeployCommand.php
**/{*Command,*Service}.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Only Commands perform console I/O using SymfonyStyle; Services return exceptions/data for Commands to display

Files:

  • app/Console/Server/ServerInstallCommand.php
  • app/Console/Server/ServerProvisionDigitalOceanCommand.php
  • app/Console/Server/ServerListCommand.php
  • app/Console/Server/ServerDeleteCommand.php
  • app/Console/Server/ServerAddCommand.php
  • app/Console/Site/SiteDeleteCommand.php
  • app/Console/Site/SiteListCommand.php
  • app/Console/Site/SiteHttpsCommand.php
  • app/Console/Site/SiteCreateCommand.php
  • app/Console/Site/SiteDeployCommand.php
**/*.{sh,bash}

📄 CodeRabbit inference engine (.cursor/rules/05-bash.mdc)

**/*.{sh,bash}: Use [[ ... ]] for conditionals instead of [ ... ] or test
Use $(...) for command substitution instead of backticks
Use ((...)) and $((...)) for math operations, never use let
Define functions without function keyword and always use local for variables within functions
Place then on the same line as if, and do on the same line as while in block statements
Prefer parameter expansion over external commands (e.g., use ${0##*/} instead of $(basename "$0"))
Use double quotes for parameter expansions and single quotes for string literals
Exception: Variables controlled by the script (not user input) may be unquoted in [[ ... ]] contexts
Use bash arrays instead of space-separated strings, and use quoted array expansion "${array[@]}"
Always check commands that can fail with || exit or similar error handling
Use set -o pipefail to catch errors in pipelines
Do not use set -e (errexit); prefer explicit error checking instead
Never use eval due to security risks and inability to perform static analysis
Use redirection or built-in read for reading files, stream with while IFS= read loops instead of loading entire files
Never parse ls output for listing files; use shell globs instead
Use tabs for indentation in Bash scripts
Maintain maximum line length of 80 columns in Bash scripts
Use semicolons only in control statements like if true; then
Maintain maximum 1 blank line between sections in Bash scripts
Use shebang #!/usr/bin/env bash at the start of Bash scripts

Files:

  • playbooks/site-delete.sh
  • playbooks/site-create.sh
**/*Trait.php

📄 CodeRabbit inference engine (.cursor/rules/04-exceptions.mdc)

**/*Trait.php: Input Validation Traits must provide a validateNameInput() method that returns ?string (error message or null) for prompts/CLI options validation
Heavy I/O Validation Traits must provide a validate*() method that throws \RuntimeException with complete error messages instead of returning ?string

Files:

  • app/Traits/SitesTrait.php
🧠 Learnings (29)
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Use `main()` function as the entry point with `main "$@"` at the bottom of playbooks

Applied to files:

  • playbooks/site-delete.sh
  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Use idempotent checks before modifying resources (e.g., `if ! command -v`, `if [[ ! -d`, `if ! systemctl is-enabled`)

Applied to files:

  • playbooks/site-delete.sh
  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Support both Ubuntu and Debian distributions using `case $DEPLOYER_DISTRO` statements only when distributions differ

Applied to files:

  • playbooks/site-delete.sh
  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Validate `DEPLOYER_OUTPUT_FILE` environment variable before any work in all playbooks

Applied to files:

  • playbooks/site-delete.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Write parsable YAML output to `DEPLOYER_OUTPUT_FILE` with error checking on write operations

Applied to files:

  • playbooks/site-delete.sh
  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Group related helper functions with comment headers using format `# ---- <section_name> ----` or `#
# Helper Functions
# ----`

Applied to files:

  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Export `DEBIAN_FRONTEND=noninteractive` at the top of playbook files

Applied to files:

  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Provisioning playbooks must validate `DEPLOYER_DISTRO` and `DEPLOYER_PERMS` environment variables in addition to `DEPLOYER_OUTPUT_FILE`

Applied to files:

  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Use shebang `#!/usr/bin/env bash` at the top of all playbook files

Applied to files:

  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Applies to **/*playbook*.sh : Use `-y -q` flags with apt package manager and `--batch --yes` flags with GPG operations for non-interactive execution

Applied to files:

  • playbooks/site-create.sh
📚 Learning: 2025-12-03T12:36:20.794Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/06-playbooks.mdc:0-0
Timestamp: 2025-12-03T12:36:20.794Z
Learning: Playbooks are idempotent, non-interactive bash scripts that execute one or more related tasks and receive context via environment variables

Applied to files:

  • playbooks/site-create.sh
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Command option naming: use --server for selecting existing servers, --name for defining new resource names, --yes/-y for skip confirmation, --force/-f for skip type-to-confirm

Applied to files:

  • app/Console/Server/ServerListCommand.php
  • app/Console/Server/ServerDeleteCommand.php
  • app/Console/Server/ServerAddCommand.php
  • app/Console/Site/SiteCreateCommand.php
  • app/Console/Site/SiteDeployCommand.php
  • app/SymfonyApp.php
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Detect and reject conflicting option combinations (e.g., --generate-deploy-key and --custom-deploy-key together)

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
  • app/Console/Site/SiteDeployCommand.php
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Use OPTIONS only, never ARGUMENTS, to enable getOptionOrPrompt() functionality in Symfony Console commands

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Multiselect CLI options: validate CLI-provided values against allowed options and reject unknown options

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Before committing rule changes, remove outdated file references, check for duplication, verify no contradictions, test code examples, and run token count comparison

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Avoid repetitive CRITICAL/IMMUTABLE warnings in rule files

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Verify all mdc:// references point to existing files in rule files

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Include single 'All rules MANDATORY' statement per rule file

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Remove 'Benefits', 'Why This Matters', and 'Key Benefits' sections from rule files

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Use imperative mood in rule files, not conversational prose

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Remove references to deleted files immediately from rule files

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Do not copy third-party documentation verbatim in rule files; summarize key points only

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:36:37.985Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/rules.mdc:0-0
Timestamp: 2025-12-03T12:36:37.985Z
Learning: Applies to **/*rules*.{md,mdc} : Maintain single source of truth per concept across rule files; if a rule appears in multiple contexts, pick primary location

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:34:49.483Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/00-main.mdc:0-0
Timestamp: 2025-12-03T12:34:49.483Z
Learning: Code should appear written by single person: naming, parameter precedence, logic flow, organization

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:34:49.483Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/00-main.mdc:0-0
Timestamp: 2025-12-03T12:34:49.483Z
Learning: Review surrounding code for reusable patterns

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T12:34:49.483Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/00-main.mdc:0-0
Timestamp: 2025-12-03T12:34:49.483Z
Learning: Applies to **/*.php : Group related functions into comment-separated sections

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T21:58:53.505Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/01-architecture.mdc:0-0
Timestamp: 2025-12-03T21:58:53.505Z
Learning: Applies to **/*.php : Always use braces for ALL control structures (if, else, elseif, for, foreach, while, do-while), even for single-line bodies

Applied to files:

  • .cursor/rules/00-main.mdc
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : In commandReplay(), only include conditional options if they were actually used (e.g., only include --custom-deploy-key if user selected custom path)

Applied to files:

  • app/Console/Site/SiteDeployCommand.php
🧬 Code graph analysis (10)
app/Console/Server/ServerProvisionDigitalOceanCommand.php (1)
app/Contracts/BaseCommand.php (1)
  • ul (232-240)
playbooks/site-delete.sh (1)
playbooks/helpers.sh (1)
  • run_cmd (19-25)
app/DTOs/SiteDTO.php (1)
app/DTOs/ServerDTO.php (1)
  • __construct (10-20)
app/Console/Server/ServerDeleteCommand.php (1)
app/Contracts/BaseCommand.php (1)
  • yay (206-209)
app/Console/Server/ServerAddCommand.php (1)
app/Contracts/BaseCommand.php (1)
  • ul (232-240)
app/Console/Site/SiteDeleteCommand.php (1)
app/Contracts/BaseCommand.php (2)
  • warn (214-217)
  • yay (206-209)
app/Traits/SitesTrait.php (4)
app/Contracts/BaseCommand.php (4)
  • info (198-201)
  • ul (232-240)
  • nay (222-225)
  • out (264-267)
app/Repositories/SiteRepository.php (1)
  • findByDomain (101-112)
app/Services/IOService.php (1)
  • out (57-74)
app/DTOs/SiteDTO.php (1)
  • SiteDTO (7-24)
app/Console/Site/SiteCreateCommand.php (4)
app/Contracts/BaseCommand.php (3)
  • BaseCommand (30-355)
  • ul (232-240)
  • commandReplay (305-354)
app/Traits/ServersTrait.php (1)
  • selectServer (129-165)
app/Traits/SitesTrait.php (1)
  • displaySiteDeets (110-127)
app/Traits/PlaybooksTrait.php (1)
  • executePlaybookSilently (37-52)
app/Console/Site/SiteDeployCommand.php (6)
app/DTOs/SiteDTO.php (1)
  • SiteDTO (7-24)
app/Contracts/BaseCommand.php (2)
  • info (198-201)
  • warn (214-217)
app/Repositories/SiteRepository.php (1)
  • update (75-93)
app/Services/GitService.php (2)
  • detectRemoteUrl (30-36)
  • detectCurrentBranch (44-50)
app/Services/IOService.php (2)
  • getValidatedOptionOrPrompt (211-233)
  • promptText (251-267)
app/Traits/SitesTrait.php (2)
  • validateSiteRepo (198-225)
  • validateSiteBranch (180-191)
app/Repositories/SiteRepository.php (3)
app/DTOs/SiteDTO.php (1)
  • SiteDTO (7-24)
app/Repositories/ServerRepository.php (1)
  • assertInventoryLoaded (145-150)
app/Services/InventoryService.php (1)
  • set (54-60)
🪛 PHPMD (2.15.0)
app/Console/Site/SiteCreateCommand.php

149-149: Avoid unused local variables such as '$displayUrl'. (undefined)

(UnusedLocalVariable)

🔇 Additional comments (32)
.cursor/rules/00-main.mdc (2)

44-52: File Operations section is well-structured.

Terminal commands follow the imperative mood and provide clear, practical guidance for file management. The organization into a dedicated subsection aligns with the codebase philosophy of grouping related guidance. Based on learnings, this section meets standards for rule file content.


57-58: Execution Protocol expansion clarifies process steps.

The addition of "STEP BY STEP" and "ACT" steps creates a more complete procedure flow. Steps are concise and directive.

app/Console/Site/SiteHttpsCommand.php (1)

96-97: LGTM! Terminology correctly updated.

The message correctly reflects the refactoring from "add" to "create" terminology. The guidance is clear and actionable for users.

app/Console/Server/ServerProvisionDigitalOceanCommand.php (1)

174-177: LGTM! Enhanced user guidance after provisioning.

The addition of usage hints after successful provisioning improves the user experience by clearly indicating the next steps. The implementation is consistent with similar changes in ServerAddCommand.php.

app/Console/Server/ServerInstallCommand.php (1)

159-159: LGTM! Terminology updated to reflect site:create command.

The change from site:add to site:create is consistent with the PR's refactoring objectives.

playbooks/site-create.sh (2)

4-6: LGTM! Playbook description updated to reflect "create" terminology.

The header comments now correctly reference "Site Create Playbook" instead of "Site Add Playbook", aligning with the broader terminology changes in this PR.


114-114: LGTM! User-facing message improved for clarity.

The change from "Deploy your application with" to "Deploy your new site with" provides clearer context about what is being deployed.

app/Console/Site/SiteListCommand.php (1)

16-16: LGTM! Command description made more concise.

Removing "the" from the description improves consistency with similar commands across the codebase.

app/Console/Server/ServerListCommand.php (1)

17-17: LGTM! Command description made more concise.

Removing "the" from the description improves consistency with similar commands across the codebase.

playbooks/site-delete.sh (1)

6-10: LGTM! Terminology consistently updated from "remove" to "delete".

The function renames and message updates throughout the script are consistent:

  • remove_caddy_vhostdelete_caddy_vhost
  • remove_site_filesdelete_site_files
  • All call sites updated correctly
  • User-facing messages now use "Deleting" instead of "Removing"

The changes align with the PR's objective to standardize terminology across the codebase.

Also applies to: 39-53, 70-84, 94-96

app/Console/Server/ServerAddCommand.php (2)

20-20: LGTM! Command description made more concise.

Removing "the" from the description improves consistency with other list commands in the codebase.


99-102: LGTM! Enhanced user guidance after adding server.

The addition of usage hints after successful server addition improves UX by clearly indicating the next steps. The implementation is consistent with the pattern used in ServerProvisionDigitalOceanCommand.php.

app/Traits/SitesTrait.php (8)

40-40: LGTM! PHPDoc formatting improved.

Minor spacing adjustments in PHPDoc comments improve consistency.

Also applies to: 66-66


53-55: LGTM! Yoda condition applied and command reference updated.

The changes correctly:

  • Apply Yoda condition (0 === count($allSites)) per coding guidelines
  • Update command reference from site:add to site:create

98-98: LGTM! Yoda condition applied correctly.

Using null === $site follows the coding guideline to place constants/literals on the left side of comparisons.


117-123: LGTM! Display logic updated for nullable fields.

The conditional display of Repo and Branch fields aligns with the SiteDTO changes that made these fields nullable. This prevents displaying null values in the site details.


147-154: LGTM! Yoda conditions applied correctly.

Both comparisons now use Yoda conditions as per coding guidelines:

  • Line 147: Expression reformatted for clarity
  • Line 154: null !== $existing places the constant on the left

186-186: LGTM! Yoda conditions applied to validation logic.

Both empty string checks now use Yoda conditions ('' === trim(...)) per coding guidelines.

Also applies to: 204-204


248-251: LGTM! Validation updated with Yoda condition and new terminology.

The changes correctly:

  • Apply Yoda condition (0 !== $result['exit_code'])
  • Update messaging from "added" to "created"
  • Update command reference from site:add to site:create

271-271: LGTM! Path construction spacing normalized.

The path building logic is now more consistent:

  • Direct concatenation with proper spacing
  • getSiteSharedPath() reuses getSiteRootPath() for DRY principle

Also applies to: 279-279

app/DTOs/SiteDTO.php (1)

13-20: LGTM!

The nullable repo and branch properties align with the ServerDTO pattern and the updated site creation flow where git details are optional at creation time. DocBlock accurately documents the nullable semantics.

app/SymfonyApp.php (1)

19-19: LGTM!

The import and command registration are consistent with the rename from SiteAddCommand to SiteCreateCommand.

Also applies to: 151-151

app/Console/Site/SiteDeleteCommand.php (1)

102-178: LGTM!

The terminology refactor from "remove" to "delete" for server operations and "remove" for inventory operations provides clear semantic distinction. The variable renaming from removedFromServer to deletedFromServer is consistently applied throughout the execution flow.

app/Repositories/SiteRepository.php (2)

69-93: LGTM!

The new update() method follows the established repository pattern: it asserts inventory is loaded, searches by domain, updates in-place via dehydrateSiteDTO(), and throws a RuntimeException with an actionable message when the site is not found. This aligns with the ServerRepository pattern shown in relevant snippets.


200-215: LGTM!

Conditional inclusion of repo and branch in the dehydrated array prevents storing null values in inventory, keeping the storage representation clean. This pairs well with hydrateSiteDTO() defaulting missing keys to null.

app/Console/Site/SiteDeployCommand.php (4)

47-48: LGTM!

New --repo and --branch options follow the established naming convention and enable CLI-driven deployment without stored git configuration.


275-347: Verify CLI override behavior for stored repo/branch values.

The resolveRepoAndBranch() logic allows CLI options (--repo/--branch) to override stored values without setting needsUpdate, meaning temporary overrides won't persist to inventory. This appears intentional for one-off deployments to alternate repos/branches.

Confirm this is the desired behavior—if CLI overrides should persist, the needsUpdate flag should be set when a CLI value differs from the stored value.


234-240: LGTM!

Catching RuntimeException from the inventory update and logging a warning (rather than failing the deployment) is appropriate—the deployment itself succeeded, and inventory persistence is a secondary concern.


459-461: Defensive null check is acceptable but should be unreachable.

Given the flow—resolveRepoAndBranch() either populates repo/branch or returns null (causing early exit), and the new SiteDTO is constructed with these values—this null check should never trigger. The early return of [] (no missing hooks) is safe as defensive coding, though it could theoretically mask issues if null values somehow slip through.

app/Console/Site/SiteCreateCommand.php (3)

18-23: Command rename and execution flow look consistent

Renaming to site:create, updating the heading to “Create New Site”, adding the null === $server->info guard, and short‑circuiting on null === $siteInfo all align with the new “create” semantics and improve robustness without changing behavior in unexpected ways. Instantiating SiteDTO with repo: null and branch: null matches the nullable DTO shape introduced elsewhere.

Also applies to: 51-52, 57-60, 71-80, 85-90, 91-107


220-236: PHP version selection and validation logic is solid

Extracting installed PHP versions in a backward‑compatible way, auto‑selecting when only one exists, preferring the configured default when present, and finally validating the CLI‑provided --php-version against $installedPhpVersions gives a clear and predictable flow. Using strict in_array(..., true) and Yoda comparison (1 === count(...)) matches the coding guidelines.

Also applies to: 237-247, 251-255, 256-267, 270-275


281-287: gatherSiteInfo flow and typing match the new Git‑less site model

The updated return shape (domain, phpVersion, wwwMode) and nullability are consistent with the new model. Domain validation/normalization, guarded WWW mode selection with explicit validation, and delegating PHP version selection to selectPhpVersion() all look correct. The early returns on null === $domain / null === $wwwMode cleanly handle user cancellations or validation failures without leaking partial state.

Also applies to: 289-303, 312-327, 331-333, 339-349

Comment thread app/Console/Site/SiteCreateCommand.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
app/Console/Site/SiteCreateCommand.php (3)

57-60: Server selection and readiness checks are sound; update docblock wording

Short‑circuiting is_int($server) avoids property access on error codes, and validateServerReady() cleanly enforces the Caddy/PHP preconditions with a single Command::FAILURE exit path. The docblock still says “add site” though; consider updating it to reflect the site:create rename:

-     * Validate that server is ready to add site.
+     * Validate that server is ready to create a site.

Also applies to: 71-80, 186-205


85-96: Site info wiring and inventory write align with nullable repo/branch

gatherSiteInfo()’s nullable return is handled correctly in execute(), SiteDTO is constructed with repo: null / branch: null in line with the updated DTO and displaySiteDeets(), and the try/catch around $this->sites->create($site) keeps the command layer limited to showing the RuntimeException message. If you want the success copy to mirror the create wording, you could slightly tweak the message:

-        $this->yay("Site '{$domain}' added to inventory");
+        $this->yay("Site '{$domain}' created on server and added to inventory");

Also applies to: 101-107, 135-143


111-125: Playbook invocation and DNS next steps are coherent; optional www‑mode hints

The site-create playbook call with distro/perms/domain/PHP version/WWW mode looks correct, and the DNS checklist is concise and uses the server host consistently with no unused locals left over from the earlier $displayUrl approach. As a small UX enhancement, you could tailor the DNS text to explain the canonical URL based on $wwwMode, for example:

-        $this->ul([
-            'Point <fg=cyan>@</> (root) to <fg=cyan>' . $server->host . '</>',
-            'Point <fg=cyan>www</> to <fg=cyan>' . $server->host . '</>',
-            'Run <fg=cyan>site:https</> to enable HTTPS once you have your DNS records set up',
-            'Deploy your new site with <fg=cyan>site:deploy</>'
-        ]);
+        $dnsLines = [
+            'Point <fg=cyan>@</> (root) to <fg=cyan>' . $server->host . '</>',
+            'Point <fg=cyan>www</> to <fg=cyan>' . $server->host . '</>',
+            'Run <fg=cyan>site:https</> to enable HTTPS once you have your DNS records set up',
+            'Deploy your new site with <fg=cyan>site:deploy</>',
+        ];
+
+        if ('redirect-to-www' === $wwwMode) {
+            $dnsLines[] = 'Your canonical URL will be <fg=cyan>www.' . $domain . '</>; non-www will redirect there.';
+        } else {
+            $dnsLines[] = 'Your canonical URL will be <fg=cyan>' . $domain . '</>; www will redirect there.';
+        }
+
+        $this->ul($dnsLines);

Also applies to: 149-156

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 095ad6f and c917fa8.

📒 Files selected for processing (1)
  • app/Console/Site/SiteCreateCommand.php (13 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.php

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

**/*.php: Eliminate single-use methods: inline if called once
Cache computed values: initialize expensive calculations in constructor
Avoid method call overhead: direct property access when appropriate
Group related functions into comment-separated sections
Order alphabetically after grouping logically

**/*.php: Follow PSR-12 standard with strict types enabled and use PHP 8.x features (unions, match, attributes, readonly)
Use explicit return types with generics (e.g., Collection<int, User>) for all functions and methods
Use dependency injection via Symfony patterns for all object dependencies
Use Symfony classes over native PHP functions (Filesystem, Process) for testability
Always use Yoda conditions: place constants/literals on the LEFT side of comparisons (e.g., null === $value) to prevent accidental assignment
Always use braces for ALL control structures (if, else, elseif, for, foreach, while, do-while), even for single-line bodies
Use @var annotations to help PHPStan understand types it cannot infer, not assert() in production code
Always add use statements for vendor packages and project classes; root namespace FQDNs acceptable for built-in exceptions (e.g., \InvalidArgumentException)
Use $container->build(ClassName::class) for all object creation; use this except for DTOs, value objects, and pure data structures
Use constructor injection in production code and direct instantiation in tests for container access
All object dependencies must be declared in constructor signatures; NO circular dependencies allowed
Use minimalist DocBlock descriptions with parameters and return types for classes and functions; separate sections visually with one newline between headers/paragraphs

**/*.php: Services and Repositories must throw \RuntimeException with complete, actionable messages that include relevant context (paths, names, IDs, hosts) and are user-facing, not fragments
When catching and re-throwing exceptions in Services and Repositories, use t...

Files:

  • app/Console/Site/SiteCreateCommand.php
**/*Command.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Command Layer: handle user interaction and orchestrate Services; contain NO business logic, NO duplicate orchestration, NO invocation of other commands

**/*Command.php: Command layer (Commands and Orchestration Traits) must display caught \RuntimeException messages directly without adding redundant prefixes like 'Failed to...'
Only add contextual information to exception displays in Command layer when necessary: raw output for debugging, actionable troubleshooting steps, or when the exception message is too technical/generic

Files:

  • app/Console/Site/SiteCreateCommand.php
**/{*Command,*Service}.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Only Commands perform console I/O using SymfonyStyle; Services return exceptions/data for Commands to display

Files:

  • app/Console/Site/SiteCreateCommand.php
🧠 Learnings (4)
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Command option naming: use --server for selecting existing servers, --name for defining new resource names, --yes/-y for skip confirmation, --force/-f for skip type-to-confirm

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Detect and reject conflicting option combinations (e.g., --generate-deploy-key and --custom-deploy-key together)

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Use OPTIONS only, never ARGUMENTS, to enable getOptionOrPrompt() functionality in Symfony Console commands

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
📚 Learning: 2025-12-03T21:59:13.882Z
Learnt from: CR
Repo: loadinglucian/deployer PR: 0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-12-03T21:59:13.882Z
Learning: Applies to **/Command.php : Multiselect CLI options: validate CLI-provided values against allowed options and reject unknown options

Applied to files:

  • app/Console/Site/SiteCreateCommand.php
🧬 Code graph analysis (1)
app/Console/Site/SiteCreateCommand.php (4)
app/Contracts/BaseCommand.php (6)
  • BaseCommand (30-355)
  • h1 (171-179)
  • info (198-201)
  • yay (206-209)
  • ul (232-240)
  • commandReplay (305-354)
app/Traits/ServersTrait.php (1)
  • selectServer (129-165)
app/Traits/SitesTrait.php (1)
  • displaySiteDeets (110-127)
app/Traits/PlaybooksTrait.php (1)
  • executePlaybookSilently (37-52)
🔇 Additional comments (3)
app/Console/Site/SiteCreateCommand.php (3)

19-22: Command rename and CLI surface are consistent with conventions

The AsCommand name/description, configure() options, H1 label, and commandReplay() all use site:create and “Create New Site”, and you rely solely on options (including --server) with no arguments, which matches the command rules and option‑naming guidance. Based on learnings, this aligns with the expected command option conventions.

Also applies to: 32-41, 51-51, 162-167


233-237: PHP version selection handles edge cases and validates CLI input

selectPhpVersion() fails with Command::FAILURE when no versions are installed, auto‑selects when only one is available, prefers the configured default (or newest) when prompting, and then validates any --php-version value against the discovered list with a clear error if it’s invalid; this fits well with the validated‑option guidance from the command rules.

Also applies to: 239-242, 245-252, 262-268


281-299: gatherSiteInfo() contract and validation look consistent with the new model

The updated return type {domain, phpVersion, wwwMode}|null matches what execute() actually consumes, early null checks cleanly propagate abort/validation failures, and normalizing the domain before further use keeps downstream behaviour consistent; no issues noticed here.

Also applies to: 304-325, 327-345

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/Console/Site/SiteDeleteCommand.php (1)

101-176: Server-deletion flag and confirmation flow look correct; consider clarifying success messaging

The refactor from removedFromServer to deletedFromServer, plus the updated “Deleting site from server...” and “Failed to delete site from server” messages, all align with the new terminology and the control flow around server vs inventory deletion looks sound:

  • $deletedFromServer is initialized once (line 105) and only flipped to true on successful playbook execution (line 145).
  • When the server is missing, unreachable, or the playbook fails, the subsequent if (!$deletedFromServer) branch (line 154) correctly gates whether to prompt “Remove site from inventory anyway?” before proceeding.
  • Early return Command::FAILURE; when the user declines (line 165) avoids emitting a misleading success message.

One small UX consideration: the final success message is now always "Site '{$site->domain}' removed from inventory" (line 175), even when the server deletion succeeded. That’s accurate, but a bit opaque about whether the server was also cleaned up. If you want to make this clearer for operators, you could optionally differentiate the message when $deletedFromServer === true (e.g., "deleted from server and removed from inventory") while preserving the current behavior as the default.

Overall, the logic is correct and consistent with the guidelines that Commands orchestrate rather than contain business logic.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c917fa8 and 290b0c1.

📒 Files selected for processing (1)
  • app/Console/Site/SiteDeleteCommand.php (5 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.php

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

**/*.php: Eliminate single-use methods: inline if called once
Cache computed values: initialize expensive calculations in constructor
Avoid method call overhead: direct property access when appropriate
Group related functions into comment-separated sections
Order alphabetically after grouping logically

**/*.php: Follow PSR-12 standard with strict types enabled and use PHP 8.x features (unions, match, attributes, readonly)
Use explicit return types with generics (e.g., Collection<int, User>) for all functions and methods
Use dependency injection via Symfony patterns for all object dependencies
Use Symfony classes over native PHP functions (Filesystem, Process) for testability
Always use Yoda conditions: place constants/literals on the LEFT side of comparisons (e.g., null === $value) to prevent accidental assignment
Always use braces for ALL control structures (if, else, elseif, for, foreach, while, do-while), even for single-line bodies
Use @var annotations to help PHPStan understand types it cannot infer, not assert() in production code
Always add use statements for vendor packages and project classes; root namespace FQDNs acceptable for built-in exceptions (e.g., \InvalidArgumentException)
Use $container->build(ClassName::class) for all object creation; use this except for DTOs, value objects, and pure data structures
Use constructor injection in production code and direct instantiation in tests for container access
All object dependencies must be declared in constructor signatures; NO circular dependencies allowed
Use minimalist DocBlock descriptions with parameters and return types for classes and functions; separate sections visually with one newline between headers/paragraphs

**/*.php: Services and Repositories must throw \RuntimeException with complete, actionable messages that include relevant context (paths, names, IDs, hosts) and are user-facing, not fragments
When catching and re-throwing exceptions in Services and Repositories, use t...

Files:

  • app/Console/Site/SiteDeleteCommand.php
**/*Command.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Command Layer: handle user interaction and orchestrate Services; contain NO business logic, NO duplicate orchestration, NO invocation of other commands

**/*Command.php: Command layer (Commands and Orchestration Traits) must display caught \RuntimeException messages directly without adding redundant prefixes like 'Failed to...'
Only add contextual information to exception displays in Command layer when necessary: raw output for debugging, actionable troubleshooting steps, or when the exception message is too technical/generic

Files:

  • app/Console/Site/SiteDeleteCommand.php
**/{*Command,*Service}.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Only Commands perform console I/O using SymfonyStyle; Services return exceptions/data for Commands to display

Files:

  • app/Console/Site/SiteDeleteCommand.php
🧬 Code graph analysis (1)
app/Console/Site/SiteDeleteCommand.php (1)
app/Contracts/BaseCommand.php (2)
  • warn (214-217)
  • yay (206-209)
🔇 Additional comments (1)
app/Console/Site/SiteDeleteCommand.php (1)

17-20: Description wording is consistent with the new lifecycle terminology

The updated command description reads clearly and matches the “delete from server / remove from inventory” flow used in the rest of the command and related site commands. No issues here.

@loadinglucian
loadinglucian merged commit 7d7d6c7 into main Dec 4, 2025
5 checks passed
@loadinglucian
loadinglucian deleted the refactor/site-rename-add-to-create branch December 4, 2025 11:40
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