Files
City10/docs/superpowers/plans/2026-10-18-citizens-persistence.md
T
marcocosta10000 c299a4ae21 feat(city): implement marketplace, missions, customization and admin dashboard
- Add database migrations for market_listings, missions and character cosmetics
- Create controllers for marketplace, missions, presence and character customization
- Implement admin world dashboard with live platform metrics
- Add feature tests for world functionality
- Include phase 2 design documents and gap analysis
2026-10-17 23:21:23 -03:00

171 lines
8.8 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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