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
+51 -1
View File
@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
@@ -19,7 +20,7 @@ use Laravel\Sanctum\HasApiTokens;
* acceptance of versioned legal documents (Terms, Privacy, Cookies)
* required by the Brazilian LGPD.
*/
#[Fillable(['name', 'email', 'password', 'role', 'locale', 'is_active'])]
#[Fillable(['name', 'email', 'password', 'role', 'status', 'locale', 'is_active'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
@@ -40,6 +41,37 @@ class User extends Authenticatable
*/
public const ROLE_USER = 'user';
/**
* Account registered but not yet approved by an administrator.
*
* @var string
*/
public const STATUS_PENDING = 'pending';
/**
* Account approved and able to enter the platform.
*
* @var string
*/
public const STATUS_ACTIVE = 'active';
/**
* Account blocked by an administrator.
*
* @var string
*/
public const STATUS_BANNED = 'banned';
/**
* In-world character belonging to this user.
*
* @return HasOne<Character, $this>
*/
public function character(): HasOne
{
return $this->hasOne(Character::class);
}
/**
* Stores owned by this user.
*
@@ -80,6 +112,14 @@ class User extends Authenticatable
return $this->role === self::ROLE_ADMIN;
}
/**
* Determine whether the account has been approved by an administrator.
*/
public function isApproved(): bool
{
return $this->status === self::STATUS_ACTIVE;
}
/**
* Check whether the user accepted every current legal document version.
*/
@@ -96,6 +136,16 @@ class User extends Authenticatable
return $currentIds->diff($acceptedIds)->isEmpty();
}
/**
* Keep the legacy is_active flag mirrored from status on save.
*/
protected static function booted(): void
{
static::saving(function (self $user): void {
$user->is_active = $user->status === self::STATUS_ACTIVE;
});
}
/**
* Get the attributes that should be cast.
*