Restore user profile status editing and display #36

Closed
opened 2024-01-14 14:37:52 -06:00 by jimmyb · 3 comments
Owner

Users should be able to set and update a short profile status, and that status should be shown prominently on their public profile.

The current Laravel checkout already has a nullable `users.status` column and the `User` model allows it to be filled, but the Livewire profile settings page only updates username and email. Public profile pages render the user header, stats, bio, consoles, social links, and comments, but do not display the stored status. This issue tracks restoring the missing status-editing workflow, making the status visible enough to be meaningful on profiles, and enabling the existing First Status achievement badge.

Scope

  • Account settings profile page at `/settings/profile`.
  • Public profile pages at `/profile/{username}`.
  • Existing `users.status` column.
  • Authenticated current-user status updates only.
  • Safe public rendering for empty, plain-text, and malicious status values.
  • Enable the existing code-managed First Status badge when a user successfully saves their first non-empty status.
  • Idempotent badge persistence, existing flash/JSON award feedback, and targeted/backfill evaluation for users with a currently non-empty status.
  • Existing Laravel/Livewire/Tailwind profile and settings patterns.

Acceptance Criteria

  • Authenticated users can set, update, and clear their status from profile settings.
  • Status updates save to the existing `users.status` column.
  • Status input has a reasonable maximum length and clear validation feedback.
  • Updating status does not require changing username or email.
  • Updating username/email continues to work as before.
  • Public profiles display a non-empty status prominently near the username/header area.
  • Profiles with no status do not show a broken or awkward placeholder.
  • Status text is escaped and cannot inject HTML or JavaScript.
  • Saving a non-empty status evaluates and awards the existing First Status badge exactly once, using the existing idempotent badge persistence and feedback conventions.
  • Updating an existing status, clearing a status, or retrying the same request does not create duplicate First Status awards.
  • Backfill/targeted recalculation can award the badge to users with a currently non-empty status; users whose historical status was cleared do not receive an inferred historical award without evidence.
  • Banned, deleted, and soft-deleted users still do not expose public profiles.
  • User-facing UI supports light/dark mode and follows existing Laravel/Livewire/Tailwind profile patterns.

Test Coverage Required

  • Livewire feature test confirming users can set and update status from profile settings.
  • Livewire feature test confirming users can clear status.
  • Validation test confirming overly long status values are rejected.
  • Regression test confirming username/email profile updates still work.
  • Feature test confirming public profiles show a saved status near the profile header.
  • Feature test confirming empty status does not render a misleading placeholder.
  • Security regression test confirming status output is escaped.
  • Badge tests confirming the first non-empty save awards First Status, subsequent updates/clears remain idempotent, empty status never awards it, and current-status backfill/targeted recalculation is idempotent.
  • Tests should use Pest and focused settings/profile coverage.
  • Run the focused profile settings/profile display and badge tests, then run `vendor/bin/pint --dirty` before closing the issue.

Progress Checklist

  • `users.status` column exists
  • `User` model includes `status` as fillable
  • Profile settings page exists
  • Public profile page exists
  • Existing profile settings tests cover username/email updates
  • Add status state, validation, and persistence to the profile settings Livewire component
  • Add status input/control to the profile settings view
  • Render non-empty status prominently on public profiles
  • Escape status output and avoid rendering empty placeholders
  • Enable First Status badge evaluation, idempotent persistence, and action feedback
  • Add First Status backfill/targeted recalculation coverage for current non-empty statuses
  • Add tests for set, update, clear, validation, display, escaping, badge behavior, and username/email regressions
  • Confirm status UI matches existing profile/settings light and dark mode patterns
Users should be able to set and update a short profile status, and that status should be shown prominently on their public profile. The current Laravel checkout already has a nullable \`users.status\` column and the \`User\` model allows it to be filled, but the Livewire profile settings page only updates username and email. Public profile pages render the user header, stats, bio, consoles, social links, and comments, but do not display the stored status. This issue tracks restoring the missing status-editing workflow, making the status visible enough to be meaningful on profiles, and enabling the existing First Status achievement badge. ## Scope - Account settings profile page at \`/settings/profile\`. - Public profile pages at \`/profile/{username}\`. - Existing \`users.status\` column. - Authenticated current-user status updates only. - Safe public rendering for empty, plain-text, and malicious status values. - Enable the existing code-managed First Status badge when a user successfully saves their first non-empty status. - Idempotent badge persistence, existing flash/JSON award feedback, and targeted/backfill evaluation for users with a currently non-empty status. - Existing Laravel/Livewire/Tailwind profile and settings patterns. ## Acceptance Criteria - Authenticated users can set, update, and clear their status from profile settings. - Status updates save to the existing \`users.status\` column. - Status input has a reasonable maximum length and clear validation feedback. - Updating status does not require changing username or email. - Updating username/email continues to work as before. - Public profiles display a non-empty status prominently near the username/header area. - Profiles with no status do not show a broken or awkward placeholder. - Status text is escaped and cannot inject HTML or JavaScript. - Saving a non-empty status evaluates and awards the existing First Status badge exactly once, using the existing idempotent badge persistence and feedback conventions. - Updating an existing status, clearing a status, or retrying the same request does not create duplicate First Status awards. - Backfill/targeted recalculation can award the badge to users with a currently non-empty status; users whose historical status was cleared do not receive an inferred historical award without evidence. - Banned, deleted, and soft-deleted users still do not expose public profiles. - User-facing UI supports light/dark mode and follows existing Laravel/Livewire/Tailwind profile patterns. ## Test Coverage Required - Livewire feature test confirming users can set and update status from profile settings. - Livewire feature test confirming users can clear status. - Validation test confirming overly long status values are rejected. - Regression test confirming username/email profile updates still work. - Feature test confirming public profiles show a saved status near the profile header. - Feature test confirming empty status does not render a misleading placeholder. - Security regression test confirming status output is escaped. - Badge tests confirming the first non-empty save awards First Status, subsequent updates/clears remain idempotent, empty status never awards it, and current-status backfill/targeted recalculation is idempotent. - Tests should use Pest and focused settings/profile coverage. - Run the focused profile settings/profile display and badge tests, then run \`vendor/bin/pint --dirty\` before closing the issue. ## Progress Checklist - [x] \`users.status\` column exists - [x] \`User\` model includes \`status\` as fillable - [x] Profile settings page exists - [x] Public profile page exists - [x] Existing profile settings tests cover username/email updates - [x] Add status state, validation, and persistence to the profile settings Livewire component - [x] Add status input/control to the profile settings view - [x] Render non-empty status prominently on public profiles - [x] Escape status output and avoid rendering empty placeholders - [x] Enable First Status badge evaluation, idempotent persistence, and action feedback - [x] Add First Status backfill/targeted recalculation coverage for current non-empty statuses - [x] Add tests for set, update, clear, validation, display, escaping, badge behavior, and username/email regressions - [x] Confirm status UI matches existing profile/settings light and dark mode patterns
Codex changed title from Add Back Functionality to Allow Users to Set and Update Their Status to Restore user profile status editing and display 2026-05-26 01:00:57 -05:00
Codex self-assigned this 2026-10-14 09:56:26 -05:00
Member

Re-reviewed the implementation against the issue description, every acceptance criterion, required test coverage, and the progress checklist. All eight remaining checklist items are supported by code, tests, and development verification; no outstanding implementation gaps were found.

  • Settings and the owner-only profile modal set, update, and clear the existing users.status field. Both enforce the agreed 36-character limit, normalize blank input to null, and preserve username/email behavior.
  • Public status text is escaped in Blade and inserted with textContent after AJAX saves. Empty statuses hide the text and comment icon. Guests and other users cannot edit a status, and banned/deleted/soft-deleted profiles remain unavailable.
  • First Status is enabled through the catalog and a forward migration. Existing unique/idempotent persistence prevents duplicate awards; feedback is shown through the settings event and profile JSON/toasts, with ordinary form flash feedback retained. Targeted and full recalculation award currently non-empty statuses without inferring cleared history or changing existing earned dates.
  • The agreed UI refinements are included: Edit Status is the main button on the owner's profile, View List is first in its dropdown, the modal saves without reloading, and the icon uses gap-1 with a 3px top margin. Empty status remains editable. Cancel/Escape, focus restoration, validation failures, server failures, and safe AJAX rendering are covered.

Final verification: 125 focused Pest tests / 945 assertions; 19 browser tests across light/dark and mobile/desktop; Pint, PHPStan, frontend build, and diff checks all passed. All 19 changed runtime files match the development deployment; the dev database has the First Status migration applied and badge enabled. The owner modal was also confirmed manually by jimmyb.

Implementation and checklist are complete. The issue remains open with status/in progress; changes are still uncommitted on codex/issue-36-profile-status. No PR or production deployment has been performed.

Re-reviewed the implementation against the issue description, every acceptance criterion, required test coverage, and the progress checklist. All eight remaining checklist items are supported by code, tests, and development verification; no outstanding implementation gaps were found. - Settings and the owner-only profile modal set, update, and clear the existing `users.status` field. Both enforce the agreed 36-character limit, normalize blank input to null, and preserve username/email behavior. - Public status text is escaped in Blade and inserted with `textContent` after AJAX saves. Empty statuses hide the text and comment icon. Guests and other users cannot edit a status, and banned/deleted/soft-deleted profiles remain unavailable. - First Status is enabled through the catalog and a forward migration. Existing unique/idempotent persistence prevents duplicate awards; feedback is shown through the settings event and profile JSON/toasts, with ordinary form flash feedback retained. Targeted and full recalculation award currently non-empty statuses without inferring cleared history or changing existing earned dates. - The agreed UI refinements are included: Edit Status is the main button on the owner's profile, View List is first in its dropdown, the modal saves without reloading, and the icon uses gap-1 with a 3px top margin. Empty status remains editable. Cancel/Escape, focus restoration, validation failures, server failures, and safe AJAX rendering are covered. Final verification: 125 focused Pest tests / 945 assertions; 19 browser tests across light/dark and mobile/desktop; Pint, PHPStan, frontend build, and diff checks all passed. All 19 changed runtime files match the development deployment; the dev database has the First Status migration applied and badge enabled. The owner modal was also confirmed manually by jimmyb. Implementation and checklist are complete. The issue remains open with status/in progress; changes are still uncommitted on codex/issue-36-profile-status. No PR or production deployment has been performed.
Member

Merged in PR #967: #967. All acceptance criteria and required test coverage were re-reviewed; all progress checklist items are complete.

Status editing supports set/update/clear with a shared 36-character limit from account settings and the owner-only profile modal. Edit Status is the primary action on your own profile; View List moves into its dropdown. AJAX saves update escaped text in place, and empty statuses hide the comment icon. Existing username/email behavior and public-account visibility rules are preserved.

The forward migration 2026_10_14_120000_enable_first_status_badge enables the existing First Status badge. Saves use the existing idempotent evaluator and award feedback. Repeated saves and clears retain a single award. Current-status backfill is available through mvgl:recalculate-badges (optionally --user=<id>); it does not infer awards for previously cleared statuses or invent historical earned dates. Rollback disables the badge while retaining earned awards.

Verification passed: 125 focused Pest tests / 945 assertions, 19 browser tests, Pint, PHPStan, frontend build, and diff checks. The dev preview was checked against deployed file hashes and the modal was confirmed by jimmyb. Font Awesome kit 1.0.46 includes the new status icon.

The merged release will now be deployed to dev first, then production, with backups, the scoped badge migration, release manifests, and served-asset verification. No bulk badge backfill is included in deployment.

Merged in PR #967: https://code.myvideogamelist.com/MyVideoGameList/myvideogamelist.com/pulls/967. All acceptance criteria and required test coverage were re-reviewed; all progress checklist items are complete. Status editing supports set/update/clear with a shared 36-character limit from account settings and the owner-only profile modal. Edit Status is the primary action on your own profile; View List moves into its dropdown. AJAX saves update escaped text in place, and empty statuses hide the comment icon. Existing username/email behavior and public-account visibility rules are preserved. The forward migration `2026_10_14_120000_enable_first_status_badge` enables the existing First Status badge. Saves use the existing idempotent evaluator and award feedback. Repeated saves and clears retain a single award. Current-status backfill is available through `mvgl:recalculate-badges` (optionally `--user=<id>`); it does not infer awards for previously cleared statuses or invent historical earned dates. Rollback disables the badge while retaining earned awards. Verification passed: 125 focused Pest tests / 945 assertions, 19 browser tests, Pint, PHPStan, frontend build, and diff checks. The dev preview was checked against deployed file hashes and the modal was confirmed by jimmyb. Font Awesome kit 1.0.46 includes the new status icon. The merged release will now be deployed to dev first, then production, with backups, the scoped badge migration, release manifests, and served-asset verification. No bulk badge backfill is included in deployment.
Member

Deployment completed after merge to exact master revision ce7907a448d84f13b33aa84cc714e78119d86d7d.

  • Dev was deployed and verified first, then production. Both release manifests identify the same revision and have matching Composer lockfile and Vite manifest hashes. All 448 payload files and the served CSS/JavaScript hashes were verified on each host.
  • Production migration 2026_10_14_120000_enable_first_status_badge succeeded; it was already applied on dev. First Status is enabled on both. No unrelated migration or bulk badge backfill ran.
  • Home/profile HTTP checks passed; unauthenticated profile settings redirect to login. Live mobile profiles display the updated comment icon with the agreed spacing, hide owner-only editing from guests, and have no JavaScript runtime errors. The authenticated owner modal was previously verified with browser tests and confirmed by jimmyb.
  • The exact merged tree passed 128 focused Pest tests / 957 assertions, Pint, PHPStan, and the frontend build. The unchanged frontend build also has the previously passing 19 browser regression tests.
  • Environment files, storage, credentials, and each host's existing dev-dependency mode were preserved. Source, vendor/cache, previous manifests, and the pre-migration badge state were backed up privately on each host. Rollback scripts are retained under /home/mvgldev/issue-36-merged-release/ and /home/mvgl/issue-36-merged-release/.

Issue closeout is complete: all checklist items checked, status/done applied, issue closed, PR #967 merged, and both environments deployed.

Deployment completed after merge to exact master revision `ce7907a448d84f13b33aa84cc714e78119d86d7d`. - Dev was deployed and verified first, then production. Both release manifests identify the same revision and have matching Composer lockfile and Vite manifest hashes. All 448 payload files and the served CSS/JavaScript hashes were verified on each host. - Production migration `2026_10_14_120000_enable_first_status_badge` succeeded; it was already applied on dev. First Status is enabled on both. No unrelated migration or bulk badge backfill ran. - Home/profile HTTP checks passed; unauthenticated profile settings redirect to login. Live mobile profiles display the updated comment icon with the agreed spacing, hide owner-only editing from guests, and have no JavaScript runtime errors. The authenticated owner modal was previously verified with browser tests and confirmed by jimmyb. - The exact merged tree passed 128 focused Pest tests / 957 assertions, Pint, PHPStan, and the frontend build. The unchanged frontend build also has the previously passing 19 browser regression tests. - Environment files, storage, credentials, and each host's existing dev-dependency mode were preserved. Source, vendor/cache, previous manifests, and the pre-migration badge state were backed up privately on each host. Rollback scripts are retained under `/home/mvgldev/issue-36-merged-release/` and `/home/mvgl/issue-36-merged-release/`. Issue closeout is complete: all checklist items checked, status/done applied, issue closed, PR #967 merged, and both environments deployed.
Sign in to join this conversation.
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MyVideoGameList/myvideogamelist.com#36
No description provided.