feat(world): add persistent citizen simulation with needs, jobs, and social features

- Adds Character model with survival needs (hunger, thirst, energy) and state machine
- Implements city:tick world ticker for offline progression every minute
- Adds city territory expansion and building construction system
- Introduces job economy, inventory, and transaction audit trail
- Adds social graph (friends, marriage, children) and character chat
- Implements admin approval workflow for new registrations
- Adds hospital admission system for traffic accidents
- Includes comprehensive feature tests and world seeders
This commit is contained in:
2026-10-17 21:46:23 -03:00
parent 79d12fa2f4
commit 79ce2a1825
132 changed files with 11809 additions and 1036 deletions
@@ -0,0 +1,89 @@
# Validation and Forms Best Practices
## Extract Validation When It Improves the Boundary
Use a form request when validation or authorization is substantial, reused, or clearer outside the controller. Inline `$request->validate()` remains appropriate for a small, endpoint-specific rule set.
```php
public function store(StorePostRequest $request): RedirectResponse
{
$post = Post::create($request->validated());
return redirect()->route('posts.show', $post);
}
```
A form request's `authorize()` method can enforce access to the operation. Validation establishes the shape and values of input; it does not itself authorize the user.
## Prefer Readable Rule Syntax
Array syntax composes cleanly with rule objects and avoids delimiter issues. Prefer it in new code when it improves readability, while following a consistent local style.
```php
'email' => ['required', 'email', Rule::unique('users')],
```
String syntax remains valid for simple rules:
```php
'email' => 'required|email|unique:users',
```
## Use Only Intended Validated Data
Use `validated()` or `safe()` instead of `$request->all()` when passing request data onward. Then select the fields intended for the operation when the validation rules also cover control fields or nested data.
Unsafe:
```php
Post::create($request->all());
```
Preferred:
```php
$post = Post::create($request->safe()->only(['title', 'body']));
```
Validated data is not automatically safe for mass assignment. Keep model `$fillable` or `$guarded` rules aligned with the operation, and never add a sensitive attribute to validation merely to make mass assignment convenient.
## Express Conditional Rules Clearly
Use conditional rules such as `Rule::when()`, `required_if`, or `exclude_unless` when they make the condition explicit. Choose the simplest form that remains easy to test.
```php
'company_name' => [
'string',
'max:255',
Rule::when(
$this->input('account_type') === 'business',
['required'],
['nullable'],
),
],
```
## Add Cross-Field Validation After Base Rules
Use a form request's `after()` method for validation that depends on multiple fields or application state. Avoid expensive queries when prerequisite fields have already failed validation.
```php
public function after(): array
{
return [
function (Validator $validator) {
if ($validator->errors()->hasAny(['product_id', 'quantity'])) {
return;
}
$stock = Product::find($this->integer('product_id'))?->stock;
if ($stock !== null && $this->integer('quantity') > $stock) {
$validator->errors()->add('quantity', 'Not enough stock.');
}
},
];
}
```
Validation against mutable state does not prevent a race between validation and persistence. Enforce inventory, uniqueness, and similar invariants with database constraints, atomic updates, or a database transaction as appropriate.