docs(10): document post-release fixes phase

Add Phase 10 GSD documentation for three critical bugs found during
manual testing: form submit 404 (reserved query vars), handler init
timing, and missing CPT detail meta box. Update ROADMAP and STATE
tracking files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 22:37:25 +09:00
parent 64caccc5c1
commit 39f94a6b2e
3 changed files with 195 additions and 11 deletions

View File

@@ -19,6 +19,7 @@ None
- [x] **Phase 7: Captcha & Validation** - reCAPTCHA v2/v3, hCaptcha, inline validation, i18n
- [x] **Phase 8: Bug Fixes & Legacy Parity** - Session bug fix, additional work sections, Sonstiges free text
- [x] **Phase 9: Internationalization** - i18n with gettext, German/English translation files
- [x] **Phase 10: Post-Release Fixes** - Form submit 404, handler timing, CPT meta box
## Phase Details
@@ -117,6 +118,16 @@ Plans:
- [x] 09-01: i18n infrastructure, text domain loading, and admin/infrastructure string wrapping
- [x] 09-02: Form-facing string wrapping, JS localization, email locale forcing, translation files
### Phase 10: Post-Release Fixes
**Goal**: Fix three critical bugs found during manual testing: 404 on form submit (reserved query vars), form handler not firing (init timing), empty CPT entries (missing meta box)
**Depends on**: Phase 9
**Research**: None (bugs identified through manual testing)
**Plans**: 1/1 complete
**Status**: Complete
Plans:
- [x] 10-01: Fix form submit 404, handler init timing, and add CPT detail meta box
## Progress
| Phase | Plans Complete | Status | Completed |
@@ -130,3 +141,4 @@ Plans:
| 7. Captcha & Validation | 1/1 | Complete | 2026-01-16 |
| 8. Bug Fixes & Legacy Parity | 2/2 | Complete | 2026-02-06 |
| 9. Internationalization | 2/2 | Complete | 2026-02-07 |
| 10. Post-Release Fixes | 1/1 | Complete | 2026-02-07 |

View File

@@ -5,23 +5,23 @@
See: .planning/PROJECT.md (updated 2026-01-16)
**Core value:** Email format identical to legacy — office staff workflow depends on the exact HTML table structure.
**Current focus:** Gap closure phases 8-9 (audit fixes before v1.0 completion)
**Current focus:** Post-v1.0 bug fixes (manual testing discoveries)
## Current Position
Phase: 9 of 9 (Internationalization)
Plan: 2 of 2 complete
Phase: 10 of 10 (Post-Release Fixes)
Plan: 1 of 1 complete
Status: Phase complete ✓
Last activity: 2026-02-06Completed 09-02-PLAN.md (form strings and translation files)
Last activity: 2026-02-07Fixed form submit 404, handler timing, CPT meta box
Progress: ██████████ 100% (10/10 plans)
Progress: ██████████ 100% (11/11 plans)
## Performance Metrics
**Velocity:**
- Total plans completed: 10
- Average duration: ~22 min per plan
- Total execution time: ~4 hours
- Total plans completed: 11
- Average duration: ~24 min per plan
- Total execution time: ~4.5 hours
**By Phase:**
@@ -36,10 +36,12 @@ Progress: ██████████ 100% (10/10 plans)
| 7 | 1 | Captcha verification and inline validation |
| 8 | 2/2 | Bug fixes & legacy parity (gap closure) |
| 9 | 2/2 | Internationalization (gap closure) ✓ |
| 10 | 1/1 | Post-release fixes (manual testing bugs) ✓ |
**Overall Trend:**
- Phases 1-7 completed successfully
- Milestone audit found 4 gaps requiring phases 8-9
- Manual testing found 3 runtime bugs requiring phase 10
- No blockers encountered
## Accumulated Context
@@ -67,6 +69,9 @@ Recent decisions affecting current work:
| 9-02 | Force German locale for email generation via switch_to_locale() | Email content must ALWAYS be German for office staff workflow |
| 9-02 | Email subject and static content NOT wrapped in gettext | Email format must match legacy exactly - subject and static strings stay hardcoded German |
| 9-02 | wp_localize_script() for JS validation messages | WordPress-native approach, handles locale selection and caching automatically |
| 10 | Rename day/month/year fields to umzug_day/umzug_month/umzug_year | WordPress reserved query vars caused 404 on form POST |
| 10 | Move handler instantiation to init_hooks() | init callback too late for handler's own init hook |
| 10 | Add CPT submission details meta box | No way to view stored submission data in admin |
### Deferred Issues
@@ -80,7 +85,7 @@ None.
## Session Continuity
Last session: 2026-02-06T14:58:08Z
Stopped at: Completed 09-02-PLAN.md (form strings and translation files) - PHASE 9 COMPLETE ✓
Last session: 2026-02-07
Stopped at: Documented phase 10 post-release fixes - PHASE 10 COMPLETE ✓
Resume file: None
Next up: All phases complete! Plugin ready for v1.0 release.
Next up: All phases complete! Plugin shipped and working end-to-end.

View File

@@ -0,0 +1,167 @@
---
phase: 10
plan: 01
type: summary
subsystem: bugfix
tags: [bugfix, form-submission, reserved-query-vars, init-timing, meta-box, standalone-template, cpt]
requires: [09-02]
provides:
- "Working form submission on standalone page (no 404)"
- "Form handler fires reliably via init_hooks() timing fix"
- "CPT detail meta box showing submission data in admin"
- "Standalone template fallback via shortcode detection"
affects: []
tech-stack:
added: []
patterns:
- "Prefix form fields to avoid WordPress reserved query vars"
- "Instantiate handlers in init_hooks() not inside init callback"
- "Shortcode content detection for template fallback"
key-files:
created:
- "templates/form-page.php"
modified:
- "umzugsliste.php"
- "includes/class-form-handler.php"
- "includes/class-date-helpers.php"
- "includes/class-email-generator.php"
- "includes/class-cpt.php"
- "includes/class-settings.php"
- "includes/class-shortcode.php"
- "includes/class-captcha.php"
- "assets/css/form.css"
- "assets/js/form.js"
- "languages/siegel-umzugsliste-de_DE.po"
- "languages/siegel-umzugsliste-de_DE.mo"
- "languages/siegel-umzugsliste.pot"
decisions:
- id: prefix-date-fields
choice: "Rename day/month/year form fields to umzug_day/umzug_month/umzug_year"
rationale: "WordPress registers day, month, year as public query variables. POST data with these names causes WP to interpret the request as a date archive, returning a 404 instead of processing the form."
- id: handler-init-timing
choice: "Move form handler instantiation from init callback to init_hooks()"
rationale: "Instantiating inside an init callback meant the handler's own init hook registered too late (after init had already fired). Moving to init_hooks() ensures handle_submission registers before init fires."
- id: template-fallback
choice: "Detect [umzugsliste] shortcode in page content when form_page_id option is unset"
rationale: "Allows standalone template to work even when the settings page hasn't been configured, improving first-run experience."
- id: cpt-meta-box
choice: "Add submission details meta box to CPT entries"
rationale: "Previously CPT entries stored data but had no way to view it in admin. Meta box shows addresses, furniture details, additional work, and status."
metrics:
duration: "~55 min (across 2 commits)"
completed: "2026-02-07"
---
# Phase 10 Plan 01: Post-Release Fixes Summary
**Fixed three critical bugs discovered during manual testing of the standalone form page: 404 on submit, form handler not firing, and empty CPT entries**
## Performance
- **Duration:** ~55 min (across 2 sessions)
- **Completed:** 2026-02-07
- **Commits:** 2 (`c0021be`, `64caccc`)
- **Files modified:** 14 (first commit), 9 (second commit)
## Context
After the v1.0 milestone audit passed (9/9 requirements, 10/10 integration, 5/5 flows), manual testing of the standalone form page revealed three critical issues that prevented actual form submission from working end-to-end.
## Bug Fixes
### Bug 1: 404 on Form Submit
**Problem:** Submitting the form on the standalone page returned a WordPress 404 page instead of processing the submission.
**Root Cause:** The form used `day`, `month`, and `year` as field names. WordPress registers these as [public query variables](https://developer.wordpress.org/reference/classes/wp/parse_request/) — when present in POST data, WordPress interpreted the request as a date archive query, which matched no posts and returned 404.
**Fix:** Renamed all date fields to `umzug_day`, `umzug_month`, `umzug_year` across form renderer, form handler, date helpers, and email generator. The `umzug_` prefix avoids collision with any WordPress reserved query vars.
**Files:** `class-form-renderer.php`, `class-form-handler.php`, `class-date-helpers.php`, `class-email-generator.php`
### Bug 2: Form Handler Not Firing
**Problem:** Even after fixing the 404, the form handler's `handle_submission()` method never executed.
**Root Cause:** `Umzugsliste_Form_Handler` was instantiated inside an `add_action('init', ...)` callback in `umzugsliste.php`. The handler's constructor registered its own `init` hook for `handle_submission`, but by the time the constructor ran (during `init`), WordPress had already started firing `init` callbacks — so the handler's hook registered too late.
**Fix:** Moved form handler instantiation to `init_hooks()` method which runs during plugin bootstrap, before `init` fires. This ensures `handle_submission` is registered on `init` at the correct time.
**File:** `umzugsliste.php`
### Bug 3: Empty CPT Entries in Admin
**Problem:** CPT submission entries were stored in the database but showed no data when viewed in the WordPress admin.
**Root Cause:** No meta box existed to display the stored post meta fields.
**Fix:** Added `Umzugsliste_CPT::add_meta_boxes()` method that registers a "Submission Details" meta box. The `render_meta_box()` callback displays:
- Moving date and addresses (from/to)
- Furniture items with quantities and cbm values per room
- Additional work sections (Montage, Schrank, etc.)
- Submission status and timestamps
All meta box strings include German translations in the .po/.mo files.
**File:** `includes/class-cpt.php`, `languages/siegel-umzugsliste-de_DE.po`, `languages/siegel-umzugsliste-de_DE.mo`
## Additional Improvements (Commit `c0021be`)
These were bundled with the standalone form page feature in the first commit:
- **Standalone form page template** (`templates/form-page.php`) — Bypasses theme, renders form in a clean layout
- **Admin setting for form page** — `form_page_id` option with auto-creation on plugin activation
- **Standalone template fallback** — Detects `[umzugsliste]` shortcode in page content when `form_page_id` is unset
- **reCAPTCHA v3 double-submission fix** — Prevented duplicate token requests
- **jQuery dependency removed** — Form JS is now vanilla JavaScript
- **Form CSS/JS overhaul** — Improved responsive layout and interaction patterns
## Decisions Made
**Prefix date fields with `umzug_`:**
- Avoids all WordPress reserved query variables
- Consistent naming convention for plugin-specific fields
- Minimal code change (find-and-replace across 4 files)
**Handler instantiation timing:**
- Move to `init_hooks()` instead of inside `init` callback
- Follows WordPress best practice: register hooks during plugin load, not inside other hooks
**Template fallback via shortcode detection:**
- `has_shortcode(get_post()->post_content, 'umzugsliste')` as fallback
- Works without settings configuration for better first-run experience
**CPT meta box for submission details:**
- Read-only display (no editing of submitted data)
- German translations for all field labels
- Grouped display: addresses, furniture by room, additional work, status
## Commits
1. **`c0021be`** — `feat: add standalone form page, close all audit gaps, pass v1.0 milestone`
- Standalone template, admin setting, CSS/JS overhaul, reCAPTCHA fix
- 14 files changed, 2191 insertions, 1202 deletions
2. **`64caccc`** — `fix: resolve form submission issues and add CPT detail view`
- Date field renaming, handler timing fix, template fallback, meta box
- 9 files changed, 261 insertions, 23 deletions
## Deviations from Plan
N/A — This phase documents bugs found and fixed during manual testing, not a pre-planned phase.
## Lessons Learned
1. **Always check WordPress reserved query vars** when naming form fields. The full list is in `WP::$public_query_vars` and includes common words like `day`, `month`, `year`, `name`, `page`, `author`, `search`, `tag`.
2. **Don't register hooks inside hook callbacks** unless you understand the timing. Instantiating a class inside `init` that itself hooks into `init` will miss the current `init` cycle.
3. **Automated audits don't catch runtime bugs.** The v1.0 audit checked code structure and integration points, but the 404 and timing bugs only surfaced during actual form submission testing.
## Next Steps
No follow-up work required. All three bugs are resolved and the standalone form page works end-to-end.
---
*Phase: 10-post-release-fixes*
*Completed: 2026-02-07*