docs(03): create phase 3 plans
Phase 3: Job Management Core - 4 plans created - 8 total tasks defined - Ready for execution Plans: - 03-01: Job submission form (Formidable + ACF) - 03-02: Job edit form with ownership validation - 03-03: Admin email notification on submission - 03-04: Admin moderation UI enhancements Parallelization: - Wave 1: 03-01, 03-02, 03-04 (independent) - Wave 2: 03-03 (depends on 03-01)
This commit is contained in:
248
.planning/phases/03-job-management-core/03-02-PLAN.md
Normal file
248
.planning/phases/03-job-management-core/03-02-PLAN.md
Normal file
@@ -0,0 +1,248 @@
|
||||
---
|
||||
phase: 03-job-management-core
|
||||
plan: 02
|
||||
type: execute
|
||||
depends_on: []
|
||||
files_modified: [includes/class-formidable.php, templates/provider-dashboard.php]
|
||||
---
|
||||
|
||||
<objective>
|
||||
Create Formidable Forms job edit form with ownership validation to prevent providers from editing others' jobs.
|
||||
|
||||
Purpose: Enable providers to update their own job listings. Security is critical - providers must only edit jobs they own.
|
||||
Output: Functional job edit form with strict ownership checks, pre-populated with existing job data.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/01-foundation-setup/01-03-SUMMARY.md
|
||||
@.planning/phases/02-provider-registration-auth/02-01-SUMMARY.md
|
||||
@includes/class-formidable.php
|
||||
@includes/class-acf-fields.php
|
||||
@includes/class-post-types.php
|
||||
@templates/provider-dashboard.php
|
||||
|
||||
**Tech stack available:** Formidable Forms Pro (with Update Post action), ACF Pro, job_offer CPT
|
||||
**Established patterns:** Programmatic Formidable form creation, ACF field mapping
|
||||
**Constraining decisions:**
|
||||
- Providers can only edit their own jobs (security requirement)
|
||||
- German labels for all form fields
|
||||
- ACF fields: job_location, job_type, job_deadline, job_contact_email, job_logo
|
||||
- Edit link in dashboard table (established in 02-03)
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create job edit form with ownership validation</name>
|
||||
<files>includes/class-formidable.php</files>
|
||||
<action>
|
||||
Add `create_job_edit_form()` method to DDHH_JM_Formidable class. Programmatically create Formidable form with key 'job_edit' containing:
|
||||
|
||||
**Form Fields (identical to submission form):**
|
||||
1. job_title (text, required) - "Stellentitel"
|
||||
2. job_description (textarea, required) - "Stellenbeschreibung"
|
||||
3. job_location (text, required) - "Standort"
|
||||
4. job_type (select, required) - "Art" with choices: Vollzeit, Teilzeit, Ehrenamt
|
||||
5. job_deadline (date, optional) - "Bewerbungsfrist" (format: d.m.Y)
|
||||
6. job_contact_email (email, required) - "Kontakt-E-Mail"
|
||||
7. job_logo (file upload, optional) - "Logo" (accept: image/jpeg, image/png, max: 2MB)
|
||||
|
||||
**Form Configuration:**
|
||||
- Edit mode: Load data from post ID passed via URL parameter (e.g., ?job_id=123)
|
||||
- Form action: "Update Post" (not Create Post)
|
||||
- Update target: Post ID from URL parameter
|
||||
- Field pre-population: Load existing values from post and ACF fields
|
||||
|
||||
**Form Actions:**
|
||||
- Update Post action configured to:
|
||||
- Post ID source: URL parameter 'job_id'
|
||||
- Post type: 'job_offer'
|
||||
- Post title: mapped to job_title field
|
||||
- Post content: mapped to job_description field
|
||||
- Custom field mappings (same as submission form):
|
||||
- job_location → meta:job_location
|
||||
- job_type → meta:job_type
|
||||
- job_deadline → meta:job_deadline
|
||||
- job_contact_email → meta:job_contact_email
|
||||
- job_logo → meta:job_logo
|
||||
|
||||
**Ownership Validation Hook:**
|
||||
Create `validate_job_ownership()` method that hooks into `frm_validate_entry` filter:
|
||||
- Check if job_id URL parameter exists
|
||||
- Verify post_type is 'job_offer'
|
||||
- Verify post_author matches current user ID
|
||||
- If validation fails: add Formidable error "Sie haben keine Berechtigung, dieses Stellenangebot zu bearbeiten."
|
||||
- CRITICAL security check - prevents URL parameter tampering
|
||||
|
||||
**Form Settings:**
|
||||
- Submit button text: "Änderungen speichern"
|
||||
- Success message: "Ihre Änderungen wurden gespeichert!"
|
||||
- Success action: Redirect to provider dashboard (/anbieter-dashboard/)
|
||||
|
||||
Add `get_job_edit_form_id()` helper method.
|
||||
|
||||
AVOID trusting URL parameters without ownership validation.
|
||||
WHY: Security risk - malicious providers could edit others' jobs by changing URL parameter.
|
||||
</action>
|
||||
<verify>
|
||||
1. Form exists: Check Formidable admin for form with key 'job_edit'
|
||||
2. Ownership validation: Check `validate_job_ownership()` method exists and hooks into `frm_validate_entry`
|
||||
3. Update action: Form should have "Update Post" action, not "Create Post"
|
||||
4. PHP syntax: php -l includes/class-formidable.php (no errors)
|
||||
</verify>
|
||||
<done>
|
||||
- Edit form created with key 'job_edit'
|
||||
- All fields present and pre-populate from existing post
|
||||
- Update Post action configured
|
||||
- Ownership validation hook implemented
|
||||
- No PHP syntax errors
|
||||
</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Update dashboard edit links to use edit form</name>
|
||||
<files>templates/provider-dashboard.php</files>
|
||||
<action>
|
||||
Update the "Edit" action link in the dashboard job listings table to point to the edit form.
|
||||
|
||||
**Current state:** Edit link likely points to WP edit post screen (providers can't access)
|
||||
**New state:** Edit link points to edit form on dashboard with job_id parameter
|
||||
|
||||
**Implementation:**
|
||||
Update the edit link generation in the jobs table:
|
||||
```php
|
||||
// OLD (if exists):
|
||||
$edit_url = get_edit_post_link( $job->ID );
|
||||
|
||||
// NEW:
|
||||
$edit_url = add_query_arg(
|
||||
array(
|
||||
'action' => 'edit_job',
|
||||
'job_id' => $job->ID
|
||||
),
|
||||
get_permalink( get_option( 'ddhh_jm_dashboard_page_id' ) )
|
||||
);
|
||||
```
|
||||
|
||||
Add form display logic before or after the listings table:
|
||||
```php
|
||||
// Check if we're in edit mode
|
||||
if ( isset( $_GET['action'] ) && $_GET['action'] === 'edit_job' && isset( $_GET['job_id'] ) ) {
|
||||
$job_id = absint( $_GET['job_id'] );
|
||||
$form_id = DDHH_JM_Formidable::get_job_edit_form_id();
|
||||
|
||||
if ( $form_id ) {
|
||||
echo '<div class="ddhh-job-edit-section">';
|
||||
echo '<h2>Stellenangebot bearbeiten</h2>';
|
||||
echo '<p><a href="' . get_permalink() . '">← Zurück zur Übersicht</a></p>';
|
||||
echo do_shortcode( "[formidable id={$form_id}]" );
|
||||
echo '</div>';
|
||||
|
||||
// Don't show listings table when editing
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Show normal dashboard (submission form + listings) if not editing
|
||||
```
|
||||
|
||||
AVOID displaying both edit form and listings simultaneously - show one or the other.
|
||||
WHY: Confusing UX, wastes screen space, makes page too long.
|
||||
</action>
|
||||
<verify>
|
||||
1. Edit links updated to use ?action=edit_job&job_id=X format
|
||||
2. Edit form displays when clicking edit link
|
||||
3. Listings table hidden when editing
|
||||
4. Back link present to return to dashboard
|
||||
5. php -l templates/provider-dashboard.php (no errors)
|
||||
</verify>
|
||||
<done>
|
||||
- Edit links point to edit form with job_id parameter
|
||||
- Edit form displays on dashboard when action=edit_job
|
||||
- Listings hidden during edit mode
|
||||
- Back navigation link present
|
||||
- No PHP syntax errors
|
||||
</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] Form 'job_edit' exists in Formidable Forms
|
||||
- [ ] Ownership validation hook implemented in `frm_validate_entry`
|
||||
- [ ] Edit form pre-populates with existing job data
|
||||
- [ ] Edit links in dashboard table work correctly
|
||||
- [ ] Providers cannot edit others' jobs (security validated)
|
||||
- [ ] No PHP syntax errors in modified files
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- Job edit form functional with ownership checks
|
||||
- Dashboard integrates edit form properly
|
||||
- Security validated - only own jobs editable
|
||||
- Ready for Plan 03-03 (notifications)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/03-job-management-core/03-02-SUMMARY.md` with:
|
||||
|
||||
---
|
||||
phase: 03-job-management-core
|
||||
plan: 02
|
||||
subsystem: job-editing
|
||||
tags: [formidable, job-editing, post-update, security, ownership]
|
||||
requires: [01-03, 02-03]
|
||||
provides: [job-edit-form, ownership-validation]
|
||||
affects: []
|
||||
tech-stack:
|
||||
added: [formidable-update-post]
|
||||
patterns: [ownership-validation, pre-populated-forms]
|
||||
key-files:
|
||||
modified: [includes/class-formidable.php, templates/provider-dashboard.php]
|
||||
key-decisions:
|
||||
- Edit form validates ownership via frm_validate_entry hook
|
||||
- Dashboard shows edit form OR listings, not both simultaneously
|
||||
- Edit mode triggered by URL parameter action=edit_job
|
||||
issues-created: []
|
||||
---
|
||||
|
||||
# Phase 3 Plan 2: Job Edit Form Summary
|
||||
|
||||
**[Substantive one-liner - what shipped]**
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- [Key outcomes including security validation]
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `includes/class-formidable.php` - [description]
|
||||
- `templates/provider-dashboard.php` - [description]
|
||||
|
||||
## Security Implementation
|
||||
|
||||
[Details of ownership validation hook and how it prevents unauthorized edits]
|
||||
|
||||
## Decisions Made
|
||||
|
||||
[Implementation choices, or "None"]
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
[Problems and resolutions, or "None"]
|
||||
|
||||
## Next Step
|
||||
|
||||
Ready for 03-03-PLAN.md (admin notifications) or 03-04-PLAN.md (admin UI) - both can run in parallel
|
||||
</output>
|
||||
Reference in New Issue
Block a user