Files
City10/docs/superpowers/plans/2026-10-18-citizens-persistence.md
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

8.8 KiB
Executable File
Raw Permalink Blame History

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