docs(05): create phase plan
Phase 05: Mentor Job Board - 3 plans created (parallel-ready) - 5 total tasks defined - Ready for execution Plans: - 05-01: Archive access control and query setup - 05-02: Job application form with provider notification - 05-03: Logo auto-crop to 200x200px All plans independent (depends_on: []), can execute in parallel.
This commit is contained in:
115
.planning/phases/05-mentor-job-board/05-01-PLAN.md
Normal file
115
.planning/phases/05-mentor-job-board/05-01-PLAN.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
phase: 05-mentor-job-board
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
depends_on: []
|
||||||
|
files_modified: [includes/class-access-control.php, includes/class-archive.php]
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Protect job archive from public access and configure published jobs query for Elementor template.
|
||||||
|
|
||||||
|
Purpose: Ensure only logged-in users (mentors/subscribers) can browse jobs, while providing query setup that Elementor templates will use.
|
||||||
|
Output: Protected archive with access control, query configuration helper for Elementor.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
~/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
./summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
|
||||||
|
# Prior work this plan builds on:
|
||||||
|
@.planning/phases/01-foundation-setup/01-02-SUMMARY.md
|
||||||
|
@.planning/phases/02-provider-registration-auth/02-04-SUMMARY.md
|
||||||
|
|
||||||
|
# Source files:
|
||||||
|
@includes/class-access-control.php
|
||||||
|
@includes/class-post-types.php
|
||||||
|
|
||||||
|
**Tech stack available:** template_redirect hook, WP_Query filters, is_user_logged_in()
|
||||||
|
**Established patterns:**
|
||||||
|
- Access control via template_redirect hook (Phase 02-04)
|
||||||
|
- Custom post type with archive slug 'jobangebote' (Phase 01-02)
|
||||||
|
- Role-based redirects to login page (Phase 02-04)
|
||||||
|
|
||||||
|
**Constraining decisions:**
|
||||||
|
- Phase 01-02: Archive slug is 'jobangebote', supports has_archive
|
||||||
|
- Phase 02-04: Access control uses template_redirect, redirects to /anbieter-login/
|
||||||
|
- PROJECT.md: Protected job archive (logged-in mentors only), Elementor Pro theme integration
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Add archive access control to existing access control class</name>
|
||||||
|
<files>includes/class-access-control.php</files>
|
||||||
|
<action>Add method protect_job_archive() that hooks template_redirect (priority 10). Check if current page is job_offer archive (is_post_type_archive('job_offer')). If yes and user NOT logged in, redirect to /anbieter-login/ with wp_safe_redirect. Register hook in existing setup_hooks() method following established pattern from protect_provider_dashboard(). This ensures mentors (subscribers) can browse jobs but public cannot access archive.</action>
|
||||||
|
<verify>Check class-access-control.php contains protect_job_archive() method. Verify hook registered in setup_hooks(). Confirm redirect logic uses is_post_type_archive() and is_user_logged_in().</verify>
|
||||||
|
<done>Archive protection method exists, hook registered, redirect logic matches provider dashboard pattern</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Create archive query helper class for Elementor integration</name>
|
||||||
|
<files>includes/class-archive.php, includes/class-ddhh-job-manager.php, ddhh-job-manager.php</files>
|
||||||
|
<action>Create new includes/class-archive.php with class DDHH_JM_Archive. Add static method setup_hooks() that registers pre_get_posts filter (priority 10). In filter callback modify_archive_query($query), check if is job_offer archive AND is main query: set post_status='publish', orderby='date', order='DESC', posts_per_page=-1 (show all published jobs). This ensures Elementor Loop Grid displays only published jobs sorted by newest first. Initialize class in class-ddhh-job-manager.php following existing pattern (DDHH_JM_Notifications::setup_hooks()). Add file_exists check and require_once in main plugin file ddhh-job-manager.php following established pattern.</action>
|
||||||
|
<verify>Check includes/class-archive.php exists with DDHH_JM_Archive class. Verify pre_get_posts filter registered. Confirm query modification only affects job_offer archives. Verify class initialized in main class and required in main plugin file.</verify>
|
||||||
|
<done>Archive query class created, filter modifies only job archives to show published posts sorted by date, class properly initialized and required</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] Archive access control method exists in class-access-control.php
|
||||||
|
- [ ] Archive query helper class exists in includes/class-archive.php
|
||||||
|
- [ ] Both hooks registered (template_redirect and pre_get_posts)
|
||||||
|
- [ ] Redirect targets /anbieter-login/ for consistency
|
||||||
|
- [ ] Query modification only affects job_offer post type archives
|
||||||
|
- [ ] Classes properly initialized following established patterns
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
|
||||||
|
- Archive protected from public access (redirect to login)
|
||||||
|
- Logged-in users can access /jobangebote/ archive
|
||||||
|
- Query helper ensures only published jobs shown in archive
|
||||||
|
- Jobs sorted by date (newest first)
|
||||||
|
- Elementor Loop Grid can use default archive query
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/05-mentor-job-board/05-01-SUMMARY.md`:
|
||||||
|
|
||||||
|
# Phase 5 Plan 1: Archive Access Control Summary
|
||||||
|
|
||||||
|
**[Substantive one-liner - what shipped, not "phase complete"]**
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- [Key outcome 1]
|
||||||
|
- [Key outcome 2]
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `includes/class-access-control.php` - Description
|
||||||
|
- `includes/class-archive.php` - Description
|
||||||
|
- `includes/class-ddhh-job-manager.php` - Description
|
||||||
|
- `ddhh-job-manager.php` - Description
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
[Key decisions and rationale, or "None"]
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
[Problems and resolutions, or "None"]
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
Ready for parallel execution with 05-02 and 05-03 (independent plans).
|
||||||
|
</output>
|
||||||
121
.planning/phases/05-mentor-job-board/05-02-PLAN.md
Normal file
121
.planning/phases/05-mentor-job-board/05-02-PLAN.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
---
|
||||||
|
phase: 05-mentor-job-board
|
||||||
|
plan: 02
|
||||||
|
type: execute
|
||||||
|
depends_on: []
|
||||||
|
files_modified: [includes/class-formidable.php, includes/class-notifications.php]
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Create job application form for mentors with email notification to provider, enabling mentor-to-provider direct contact.
|
||||||
|
|
||||||
|
Purpose: Allow mentors to express interest in jobs by submitting application with name, email, message. Provider receives email with applicant details and can respond directly.
|
||||||
|
Output: Formidable application form with email notification to job contact email.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
~/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
./summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
|
||||||
|
# Prior work this plan builds on:
|
||||||
|
@.planning/phases/02-provider-registration-auth/02-01-SUMMARY.md
|
||||||
|
@.planning/phases/03-job-management-core/03-01-SUMMARY.md
|
||||||
|
@.planning/phases/03-job-management-core/03-03-SUMMARY.md
|
||||||
|
@.planning/phases/04-job-deactivation-system/04-02-SUMMARY.md
|
||||||
|
|
||||||
|
# Source files:
|
||||||
|
@includes/class-formidable.php
|
||||||
|
@includes/class-notifications.php
|
||||||
|
@includes/class-acf-fields.php
|
||||||
|
|
||||||
|
**Tech stack available:** formidable-forms, wp_mail, get_field() for ACF fields
|
||||||
|
**Established patterns:**
|
||||||
|
- Programmatic Formidable form creation with duplicate prevention via form key (Phase 02-01, 03-01)
|
||||||
|
- Email notifications using wp_mail with German templates (Phase 03-03, 04-02)
|
||||||
|
- Success redirect after form submission (Phase 03-01)
|
||||||
|
- ACF field access for job metadata (job_contact_email, job_logo, etc.)
|
||||||
|
|
||||||
|
**Constraining decisions:**
|
||||||
|
- Phase 02-01: Formidable forms created programmatically, check for existing via form key
|
||||||
|
- Phase 03-03: Email templates in German with job context
|
||||||
|
- Phase 03-03: Error logging for wp_mail failures
|
||||||
|
- Phase 01-03: Job contact email stored in ACF field 'job_contact_email'
|
||||||
|
- PROJECT.md: Job detail page with apply button → popup form → email to provider
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Create job application form in Formidable class</name>
|
||||||
|
<files>includes/class-formidable.php</files>
|
||||||
|
<action>Add create_job_application_form() method following established pattern from create_job_submission_form(). Check for existing form by key 'job_application' to prevent duplicates. Include 4 fields: (1) applicant_name text (required, German label "Name"), (2) applicant_email email (required, German label "E-Mail", pre-fill with current_user email if logged in via default_value), (3) applicant_message textarea (required, German label "Nachricht", description "Warum interessieren Sie sich für diese Stelle?"), (4) hidden field job_id for post identification. Form title: "Jetzt bewerben". Submit button: "Bewerbung absenden". Success message: "Ihre Bewerbung wurde versendet. Der Anbieter wird sich bei Ihnen melden." No success redirect (stays on detail page). Add form action hook to trigger email notification (see Task 2). Add get_job_application_form_id() helper following established pattern. Register form creation in setup_registration_hooks().</action>
|
||||||
|
<verify>Check class-formidable.php contains create_job_application_form() and get_job_application_form_id() methods. Verify form configured with 4 fields (name, email, message, job_id). Confirm email pre-fill logic for logged-in users.</verify>
|
||||||
|
<done>Application form created programmatically, fields include applicant details and job_id, form ID getter exists, pre-fill logic for logged-in users</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Add application notification method to notifications class</name>
|
||||||
|
<files>includes/class-notifications.php</files>
|
||||||
|
<action>Add send_provider_application_notification() method following pattern from send_admin_new_job_notification(). Hook to frm_after_create_entry (Formidable form submission hook) with form_id check matching job_application form. Extract entry fields: applicant_name, applicant_email, applicant_message, job_id. Get job post: get_post($job_id). Extract job details: job_title (post_title), job_location (get_field), job_type (get_field). Get provider contact email: get_field('job_contact_email', $job_id) - this is where application goes. Email subject: "Neue Bewerbung für: {job_title}". Email body (German): "Sie haben eine neue Bewerbung für Ihr Stellenangebot erhalten.\\n\\nStelle: {job_title}\\nStandort: {job_location}\\nArt: {job_type}\\n\\n--- Bewerber ---\\nName: {applicant_name}\\nE-Mail: {applicant_email}\\n\\nNachricht:\\n{applicant_message}\\n\\n---\\nBitte antworten Sie direkt an {applicant_email}.\\n\\nDiese E-Mail wurde automatisch gesendet." Send to provider contact email (from ACF field). Include error_log if job_contact_email missing or wp_mail fails. Register hook in setup_hooks() method following existing pattern.</action>
|
||||||
|
<verify>Check includes/class-notifications.php contains send_provider_application_notification() method. Verify hook registered for frm_after_create_entry with form ID check. Confirm email includes all applicant details and job context. Verify email sent to ACF field job_contact_email.</verify>
|
||||||
|
<done>Application notification method exists, hook registered for Formidable submissions, email includes applicant info and job details, sent to provider contact email from ACF field</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] Application form exists with key 'job_application'
|
||||||
|
- [ ] Form has 4 fields: applicant_name, applicant_email, applicant_message, job_id
|
||||||
|
- [ ] Email pre-fills current user email for logged-in mentors
|
||||||
|
- [ ] Application notification hook registered for form submissions
|
||||||
|
- [ ] Email sent to provider contact email (ACF field job_contact_email)
|
||||||
|
- [ ] Email includes applicant details and job context
|
||||||
|
- [ ] Error logging handles missing contact email or wp_mail failures
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
|
||||||
|
- Application form created programmatically in class-formidable.php
|
||||||
|
- Form includes applicant details (name, email, message) and hidden job_id
|
||||||
|
- Form submission triggers email to provider contact email
|
||||||
|
- Email includes full context (applicant info + job details)
|
||||||
|
- Logged-in mentors have email pre-filled for convenience
|
||||||
|
- Provider can reply directly to applicant email
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/05-mentor-job-board/05-02-SUMMARY.md`:
|
||||||
|
|
||||||
|
# Phase 5 Plan 2: Job Application Form Summary
|
||||||
|
|
||||||
|
**[Substantive one-liner - what shipped, not "phase complete"]**
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- [Key outcome 1]
|
||||||
|
- [Key outcome 2]
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `includes/class-formidable.php` - Description
|
||||||
|
- `includes/class-notifications.php` - Description
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
[Key decisions and rationale, or "None"]
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
[Problems and resolutions, or "None"]
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
Ready for parallel execution with 05-01 and 05-03 (independent plans).
|
||||||
|
</output>
|
||||||
103
.planning/phases/05-mentor-job-board/05-03-PLAN.md
Normal file
103
.planning/phases/05-mentor-job-board/05-03-PLAN.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
phase: 05-mentor-job-board
|
||||||
|
plan: 03
|
||||||
|
type: execute
|
||||||
|
depends_on: []
|
||||||
|
files_modified: [includes/class-post-types.php]
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Automatically crop uploaded job logos to 200x200px square for consistent display across archive and detail pages.
|
||||||
|
|
||||||
|
Purpose: Ensure all job logos display at consistent size regardless of upload dimensions, preventing layout issues in Elementor templates.
|
||||||
|
Output: WordPress image size registration that auto-generates 200x200px cropped version on upload.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
~/.claude/get-shit-done/workflows/execute-plan.md
|
||||||
|
./summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
|
||||||
|
# Prior work this plan builds on:
|
||||||
|
@.planning/phases/01-foundation-setup/01-02-SUMMARY.md
|
||||||
|
@.planning/phases/01-foundation-setup/01-03-SUMMARY.md
|
||||||
|
|
||||||
|
# Source files:
|
||||||
|
@includes/class-post-types.php
|
||||||
|
@includes/class-acf-fields.php
|
||||||
|
|
||||||
|
**Tech stack available:** add_image_size() WordPress function, ACF image field with return_format='id'
|
||||||
|
**Established patterns:**
|
||||||
|
- ACF image field returns attachment ID (Phase 01-03: job_logo with return_format='id')
|
||||||
|
- Singleton pattern for post types class (Phase 01-02)
|
||||||
|
- Image sizes available via wp_get_attachment_image_src()
|
||||||
|
|
||||||
|
**Constraining decisions:**
|
||||||
|
- Phase 01-03: Logo field returns image ID, not URL, enabling access to all registered sizes
|
||||||
|
- Phase 01-03: Logo field optional (required=0) so not all jobs have logos
|
||||||
|
- PROJECT.md: Logo auto-crop to 200x200px for consistent display
|
||||||
|
- ROADMAP.md Phase 5: Logo upload and auto-crop to 200x200px
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Register 200x200px cropped image size for job logos</name>
|
||||||
|
<files>includes/class-post-types.php</files>
|
||||||
|
<action>Add static method register_image_sizes() to DDHH_JM_Post_Types class. Inside method, call add_image_size('job-logo', 200, 200, true) - width 200, height 200, hard crop true (ensures square crop from center). Hook method to after_setup_theme action (priority 10) - this is standard WordPress timing for image size registration. Register hook in existing init() method or create new setup_hooks() method following singleton pattern if init() doesn't exist. This ensures WordPress automatically generates 200x200px version when logos uploaded via ACF field. Elementor templates can then request this size via wp_get_attachment_image() or wp_get_attachment_image_src() using size 'job-logo'.</action>
|
||||||
|
<verify>Check class-post-types.php contains register_image_sizes() method. Verify add_image_size called with parameters: 'job-logo', 200, 200, true. Confirm hook registered for after_setup_theme. Check method called from init() or setup_hooks().</verify>
|
||||||
|
<done>Image size 'job-logo' registered with 200x200px hard crop, hook properly registered for after_setup_theme, method integrated into class initialization</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] Image size 'job-logo' registered via add_image_size()
|
||||||
|
- [ ] Dimensions are 200x200px with hard crop enabled
|
||||||
|
- [ ] Hook registered for after_setup_theme action
|
||||||
|
- [ ] Method properly called from class initialization
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
|
||||||
|
- WordPress image size 'job-logo' registered and available
|
||||||
|
- Uploaded logos auto-generate 200x200px cropped version
|
||||||
|
- Size accessible via standard WordPress image functions
|
||||||
|
- Elementor templates can use 'job-logo' size for consistent display
|
||||||
|
- Phase 5 complete - mentor job board fully functional
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/05-mentor-job-board/05-03-SUMMARY.md`:
|
||||||
|
|
||||||
|
# Phase 5 Plan 3: Logo Auto-Crop Summary
|
||||||
|
|
||||||
|
**[Substantive one-liner - what shipped, not "phase complete"]**
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- [Key outcome 1]
|
||||||
|
- [Key outcome 2]
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `includes/class-post-types.php` - Description
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
[Key decisions and rationale, or "None"]
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
[Problems and resolutions, or "None"]
|
||||||
|
|
||||||
|
## Next Step
|
||||||
|
|
||||||
|
Phase 5 complete. Ready for Phase 6: Email Notifications (mentor opt-in and async processing).
|
||||||
|
</output>
|
||||||
Reference in New Issue
Block a user