This document outlines the coding standards and best practices for {{$nombre_del_proyecto}} project, to be used by the Gemini CLI. Adherence to these guidelines ensures code consistency, readability, and maintainability.
- File Storage: All generated
.md
files must be saved in the/docs
directory. - Artisan Commands: Use the
sail art
alias for all Artisan commands (e.g.,sail art migrate
). - PHP & Laravel Versions: The system uses PHP {{$php_version}} and Laravel {{$laravel_version}}. Leverage the most modern features available in these versions.
- Null Checks: Always use
is_null()
to check if a value is null.
- PSR Compliance: Code style must follow PSR-1, PSR-2, and PSR-12.
- Naming Conventions (General): Everything string-like that is not public-facing should use
camelCase
. - Nullable Types: Prefer the short nullable notation (
?string
) over union types (string|null
).- GOOD:
public ?string $variable;
- BAD:
public string | null $variable;
- GOOD:
- Void Return Types: Indicate
void
for methods that do not return a value. - Typed Properties: Type properties whenever possible. Avoid redundant docblocks for fully typed properties.
- GOOD:
class Foo { public string $bar; }
- BAD:
class Foo { /** @var string */ public $bar; }
- GOOD:
- Enums: Values in enums should use
PascalCase
.- Example:
enum Suit { case Clubs; case Diamonds; case Hearts; case Spades; }
- Example:
- Docblocks:
- Avoid for fully type-hinted methods unless a description is needed.
- Descriptions should be full sentences, ending with a period.
- Always import class names in docblocks.
- Prefer single-line docblocks where possible (e.g.,
/** @var string */
,/** @test */
). - For multiple types, list the most common type first.
- If one docblock is required, add all others for consistency.
- For Iterables: Add docblocks to specify key and value types (e.g.,
array<int, MyObject>
,Collection<int,SomeObject>
).
- Constructor Property Promotion: Use if all properties can be promoted. Each promoted property should be on its own line, with a trailing comma.
- Example:
class MyClass { public function __construct( protected string $firstArgument, protected string $secondArgument, ) {} } ```* **Traits**: Each applied trait should be on its own line, using the `use` keyword for each.
- GOOD:
class MyClass { use TraitA; use TraitB; }
- BAD:
class MyClass { use TraitA, TraitB; }
- Example:
- Strings: Prefer string interpolation over
sprintf
or concatenation (.
) when possible.- GOOD:
$greeting = "Hi, I am {$name}.";
- BAD:
$greeting = 'Hi, I am ' . $name . '.';
- GOOD:
- Ternary Operators: Each portion of a ternary expression should be on its own line, unless the expression is very short.
- Short:
$name = $isFoo ? 'foo' : 'bar';
- Longer:
$result = $object instanceof Model ? $object->name : 'A default value';
- Short:
- If Statements:
- Always use curly brackets.
- Happy Path: Structure functions with the "unhappy path" first and the "happy path" last using early returns.
- Avoid
else
: Refactorelse
statements using early returns or ternary operators. - Compound
if
s: Prefer separateif
statements over compound conditions (&&
,||
) for easier debugging.
- Comments:
- Avoid comments by writing expressive code.
- If necessary, format single-line comments with a preceding space (
// Comment
). - Block comments use
/* * Comment */
. - Refactor comments into descriptive function names.
- Whitespace:
- Add blank lines between statements unless they are a sequence of single-line equivalent operations.
- Do not add extra empty lines between
{}
brackets.
- File Names: Configuration files must use
kebab-case
(e.g.,config/pdf-generator.php
). - Keys: Configuration keys must use
snake_case
(e.g.,'chrome_path'
). env()
Helper: Avoid using theenv()
helper outside of configuration files. Define configuration values from environment variables within config files.- Service Configurations: Add configuration values for specific services to
config/services.php
instead of creating new config files.
- Names: Command names should be
kebab-case
(e.g.,php artisan delete-old-records
). - Feedback: Commands should always provide feedback on the result. Minimally, use
$this->comment('All ok!');
. - Progress Tracking: For processing items, add output inside the loop (before processing the item) and provide a summary at the end.
- Public URLs: Public-facing URLs must use
kebab-case
(e.g.,https://spatie.be/open-source
). - Notation: Prefer the route tuple notation (
[OpenSourceController::class, 'index']
). - Route Names: Route names must use
camelCase
(e.g.,openSource
). - HTTP Verb Order: When defining routes, place the HTTP verb first for readability.
- Route Parameters: Route parameters should use
camelCase
(e.g.,news/{newsItem}
). - URL Prefix: A route URL should not start with
/
unless the URL would be an empty string (i.e., for the root/
).- GOOD:
Route::get('/', [HomeController::class, 'index']);
- GOOD:
Route::get('open-source', [OpenSourceController::class, 'index']);
- BAD:
Route::get('/open-source', [OpenSourceController::class, 'index']);
- GOOD:
- Naming Conventions:
- Use the plural form of the resource name.
- Use
kebab-case
for the resource name (e.g.,error-occurrences
).
- Nesting: Limit deep nesting. Use deeper nesting only when providing context is necessary for the relationship between resources.
- Resource Controllers: Controllers that manage a resource must use the plural resource name (e.g.,
PostsController
). - Simplicity: Keep controllers simple and adhere to default CRUD keywords (
index
,create
,store
,show
,edit
,update
,destroy
). Extract new controllers for additional actions.- Example: Instead of
PostsController@favorite
, create aFavoritePostsController
withstore
anddestroy
methods.
- Example: Instead of
- File Names: View files must use
camelCase
(e.g.,resources/views/openSource.blade.php
).
- Multiple Rules: When using multiple rules for one field in a form request, always use array notation instead of
|
.- GOOD:
'email' => ['required', 'email'],
- BAD:
'email' => 'required|email',
- GOOD:
- Custom Rules: All custom validation rules must use
snake_case
.
- Indentation: Indent using four spaces.
- Control Structures: Do not add spaces after control structures (e.g.,
@if($condition)
).
- Policies: Policies must use
camelCase
(e.g.,editPost
). - Abilities: Try to name abilities using default CRUD words. Replace
show
withview
(a servershows
a resource, a userviews
it).
- Translations must be rendered using the
__()
function, as it can be used in both Blade views and regular PHP code.- Example:
<h2>{{ __('newsletter.form.title') }}</h2>
- Example:
- Controllers:
- Resourceful: Plural resource name +
Controller
suffix (e.g.,UsersController
). - Invokable (single action): Action +
Controller
suffix (e.g.,PerformCleanupController
).
- Resourceful: Plural resource name +
- Resources (and Transformers): Plural resource +
Resource
orTransformer
suffix (e.g.,UsersResource
). - Jobs: Name should describe its action (e.g.,
CreateUser
). - Events: Name should clearly indicate the tense (before or after action).
- Before:
ApprovingLoan
- After:
LoanApproved
- Before:
- Listeners: Action +
Listener
suffix (e.g.,SendInvitationMailListener
). - Commands: Action +
Command
suffix (e.g.,PublishScheduledPostsCommand
). - Mailables: Event/action/question +
Mail
suffix (e.g.,AccountActivatedMail
). - Enums: No specific prefix needed.
- Directory: Create all tests in the
/tests
directory. - Framework: Utilize Pest for testing.
- Running Tests: After imports, add a comment indicating how to run the test from the terminal.
- Example:
// sail art test tests/Feature/Services/Pbx/ServerTenantUpdateServiceTest.php
- Example:
- Assertions: Chain
expect()
assertions usingand()
instead of multiple separateexpect()
calls.- GOOD:
expect($id)->toBe(14)->and($name)->toBe('Nuno');
- GOOD:
- Service Testing: When testing services, prioritize testing the service directly over using mocks.
- Code Modification & Validation: When modifying code, check for associated tests. Consult the user if they wish to execute them to validate changes. If tests fail, proceed to correct the error.