- 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
171 lines
8.8 KiB
Markdown
171 lines
8.8 KiB
Markdown
# Cidadãos Persistentes — Implementation Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** Each admin-approved user gets a persistent human-like character (needs, jobs, housing, family, chat) in a multi-city world that progresses via an always-on scheduler without requiring anyone online.
|
||
|
||
**Architecture:** Laravel 13 + MariaDB hold all character/world state. `city:tick` (every minute) applies need decay, salaries, building progress and simple offline AI. The existing Three.js viewer becomes a client for the caller's character (throttled position sync) plus action HUD/UI. Admin manages citizen approval, territory expansion and new cities.
|
||
|
||
**Tech Stack:** Laravel 13, PHP 8.3+, MariaDB, Sanctum (existing), Three.js viewer (existing), PHPUnit, Playwright MCP. No new production dependencies.
|
||
|
||
**Spec:** `docs/superpowers/specs/2026-10-18-citizens-persistence-design.md`
|
||
|
||
## Global Constraints
|
||
|
||
- PHP 8.3+; follow existing conventions (Form Requests, `#[Fillable]`, English PHPDoc, Pint).
|
||
- All user-visible strings in `lang/pt_BR.json`, `lang/en.json`, `lang/es.json`.
|
||
- LGPD protections, CAPTCHA, CSRF unchanged; no secrets in repo.
|
||
- `php artisan test` and `vendor/bin/pint --test` must pass before considering a task done.
|
||
- Registration must leave users `pending` until admin approval.
|
||
- World must progress with zero users online (`city:tick` + `schedule:run`).
|
||
- Character death is not simulated; needs floor at 0 with energy penalties only.
|
||
|
||
## Review Focus
|
||
|
||
1. **Unapproved login:** user with `status=pending` must not enter dashboard/city; expect friendly wait screen + logout.
|
||
2. **Tick idempotency:** running `city:tick` twice in one minute must not double-decay needs or double-pay salary (guard by `last_tick_at`).
|
||
3. **Ownership:** actions (eat/build/sleep/position) must reject another user's character ID (403/422).
|
||
4. **Build occupancy:** two characters must not complete houses on the same footprint (unique site check by AABB).
|
||
5. **City bounds:** movement and building must clamp/fail outside active city bounds; new city layout must derive from `cities.bounds`, not only store positions.
|
||
6. **Family graph:** spouse requires accepted friendship; child requires both spouses; child NPC has `user_id=null` and never logs in.
|
||
7. **Migration safety:** existing `is_active` users become `active` and can still log in after the `status` column ships.
|
||
|
||
---
|
||
|
||
### Task 1: Schema + seeders (cities, characters, buildings, relationships, inventory, transactions, jobs, messages)
|
||
|
||
**Files:**
|
||
- Create: `database/migrations/2026_10_18_000100_add_status_to_users_table.php`
|
||
- Create: `database/migrations/2026_10_18_000200_create_cities_table.php`
|
||
- Create: `database/migrations/2026_10_18_000300_create_characters_table.php`
|
||
- Create: `database/migrations/2026_10_18_000400_create_buildings_table.php`
|
||
- Create: `database/migrations/2026_10_18_000500_create_relationships_table.php`
|
||
- Create: `database/migrations/2026_10_18_000600_create_inventory_items_table.php`
|
||
- Create: `database/migrations/2026_10_18_000700_create_transactions_table.php`
|
||
- Create: `database/migrations/2026_10_18_000800_create_jobs_table.php`
|
||
- Create: `database/migrations/2026_10_18_000900_create_character_messages_table.php`
|
||
- Create: `app/Models/City.php`, `Character.php`, `Building.php`, `Relationship.php`, `InventoryItem.php`, `Transaction.php`, `Job.php`, `CharacterMessage.php`
|
||
- Create: `database/factories/CharacterFactory.php`, `CityFactory.php`
|
||
- Create: `database/seeders/CityWorldSeeder.php` (City10 + jobs; backfill users status; ensure characters for active users)
|
||
- Modify: `database/seeders/DatabaseSeeder.php` (register seeder)
|
||
- Modify: `app/Models/User.php` (status const/cast/relation)
|
||
|
||
**Steps:**
|
||
- [ ] Write migrations/models/factories/seeder per spec §3
|
||
- [ ] `php artisan migrate` in container
|
||
- [ ] Feature test: seeder creates City10 + character for active user; `users.status` backfilled
|
||
- [ ] Run `php artisan test --filter=CityWorld` and Pint
|
||
- [ ] Commit
|
||
|
||
### Task 2: Registration pending + admin citizens approval
|
||
|
||
**Files:**
|
||
- Create: `app/Http/Controllers/Web/Admin/CitizenAdminController.php`
|
||
- Create: `resources/views/admin/citizens/index.blade.php`
|
||
- Create: `app/Http/Requests/...` if needed
|
||
- Modify: `app/Http/Controllers/Web/AuthController.php` (register → pending; login branch for pending)
|
||
- Create: `resources/views/auth/pending.blade.php`
|
||
- Modify: `routes/web.php` (admin citizens routes; pending view route or inline response)
|
||
- Modify: `app/Http/Middleware/EnsureUserIsActive.php` if needed
|
||
- Modify: lang files (pending/approve/ban strings)
|
||
- Modify: `resources/views/dashboard` or layout nav (Admin → Cidadãos link)
|
||
|
||
**Steps:**
|
||
- [ ] Failing tests: register creates pending; login as pending redirects to wait screen; admin approve activates + creates character; banned cannot login
|
||
- [ ] Implement controller/views/routes
|
||
- [ ] `php artisan test --filter=Citizen` green + Pint
|
||
- [ ] Commit
|
||
|
||
### Task 3: World ticker `city:tick` + schedule
|
||
|
||
**Files:**
|
||
- Create: `app/Console/Commands/CityTick.php`
|
||
- Modify: `routes/console.php` (everyMinute)
|
||
- Create: `tests/Feature/CityTickTest.php`
|
||
|
||
**Steps:**
|
||
- [ ] Failing test: needs decay once per call; second immediate call no-ops; sleep recovers energy; work pays; building progress completes at 100
|
||
- [ ] Implement command + offline AI rules (spec §4)
|
||
- [ ] Tests green + Pint; `php artisan schedule:list` shows entry
|
||
- [ ] Commit
|
||
|
||
### Task 4: City data payload + layout from bounds + character position sync
|
||
|
||
**Files:**
|
||
- Modify: `app/Http/Controllers/Web/CityViewerController.php` (city param, characters/buildings/jobs/bounds; layout from city bounds)
|
||
- Modify: `app/Http/Controllers/Api/...` if mirrored
|
||
- Create: `app/Http/Controllers/Web/CityActionController.php` (position + actions stubs for this task: position only)
|
||
- Modify: `routes/web.php`
|
||
- Create: `tests/Feature/CityDataTest.php`, `CityPositionTest.php`
|
||
|
||
**Steps:**
|
||
- [ ] Failing tests: `/city/data` includes own character + bounds; layout covers full bounds; position POST persists and clamps to bounds; cannot set another character
|
||
- [ ] Implement
|
||
- [ ] Tests green + Pint
|
||
- [ ] Commit
|
||
|
||
### Task 5: Actions API (eat/drink/sleep/wake/work/study/buy/sell/build)
|
||
|
||
**Files:**
|
||
- Modify: `app/Http/Controllers/Web/CityActionController.php`
|
||
- Create: Form Requests under `app/Http/Requests/`
|
||
- Create: `tests/Feature/CityActionsTest.php`
|
||
- Modify: lang files (action labels/errors)
|
||
|
||
**Steps:**
|
||
- [ ] Failing tests per action happy path + key rejects (no house, no job, no money, occupied site, insufficient materials)
|
||
- [ ] Implement actions with DB transactions where money/inventory move
|
||
- [ ] Tests green + Pint
|
||
- [ ] Commit
|
||
|
||
### Task 6: Social (friends, spouse, child, character chat)
|
||
|
||
**Files:**
|
||
- Modify: `app/Http/Controllers/Web/CitySocialController.php` (create)
|
||
- Create: `app/Http/Controllers/Web/CharacterChatController.php` or extend `ChatController`
|
||
- Create: `tests/Feature/CitySocialTest.php`
|
||
- Modify: lang files
|
||
|
||
**Steps:**
|
||
- [ ] Failing tests: friend request/accept; marry requires accepted friend + no existing spouse; child creates NPC character with parent links; message POST persists and is readable by recipient
|
||
- [ ] Implement
|
||
- [ ] Tests green + Pint
|
||
- [ ] Commit
|
||
|
||
### Task 7: Admin territory expand + multi-city
|
||
|
||
**Files:**
|
||
- Create: `app/Http/Controllers/Web/Admin/CityAdminController.php`
|
||
- Create: `resources/views/admin/cities/*` (index + create + expand form)
|
||
- Modify: `routes/web.php`
|
||
- Create: `tests/Feature/CityExpansionTest.php`
|
||
- Modify: lang files
|
||
|
||
**Steps:**
|
||
- [ ] Failing tests: create city; expand bounds +40 up to cap; layout for new city uses its bounds
|
||
- [ ] Implement
|
||
- [ ] Tests green + Pint
|
||
- [ ] Commit
|
||
|
||
### Task 8: Viewer frontend — own character, HUD needs, action menu, citizens, buildings
|
||
|
||
**Files:**
|
||
- Modify: `resources/views/city/viewer.blade.php` (HUD + action panel markup)
|
||
- Modify: `public/js/city/app.js` (own character control, needs HUD poll, action fetches, render characters/buildings from payload, bounds clamp, position throttle)
|
||
- Modify: lang files
|
||
|
||
**Steps:**
|
||
- [ ] Manual/Playwright: after Task 2–7, load `/city`, see own avatar, move persists (reload keeps position), action buttons update needs/money, second character visible, build marker
|
||
- [ ] No console errors; Pint N/A (JS); `node --check app.js`
|
||
- [ ] Commit
|
||
|
||
### Task 9: End-to-end Playwright + bugfix pass
|
||
|
||
**Files:**
|
||
- Screenshots under `.playwright-mcp/`
|
||
- Fix any bugs found in previous tasks
|
||
|
||
**Steps:**
|
||
- [ ] Full journey: register → pending screen → admin approves → login → accept terms if needed → `/city` → move → eat/work/sleep → build house → friend with second user → chat → admin expand → new city
|
||
- [ ] Console clean; PHPUnit full suite green; Pint green
|
||
- [ ] Final commit |