--- phase: 01-foundation-setup plan: 03 type: execute depends_on: [] files_modified: [includes/class-roles.php, includes/class-acf-fields.php] --- Register custom role `ddhh_provider` with restricted capabilities and ACF field groups for job_offer CPT. Purpose: Define provider permissions and job listing data structure. Output: Provider role with correct capabilities, ACF fields for job metadata. ~/.claude/get-shit-done/workflows/execute-plan.md ./summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md **From PROJECT.md:** - ACF fields: job_location (text), job_type (select), job_deadline (date), job_contact_email (email), job_logo (image), job_deactivation_reason (textarea - internal) - Providers: restricted capabilities, no WP-Admin access except profile **Tech stack:** ACF Pro available Task 1: Register ddhh_provider role with restricted capabilities includes/class-roles.php Create `DDHH_JM_Roles` class with static add_roles() method. Register role 'ddhh_provider' with add_role(): - Display name: 'Anbieter' (German for Provider) - Capabilities: - read: true (basic WordPress access) - edit_job_offers: true (can edit own job_offers) - publish_job_offers: false (jobs go to pending, admin publishes) - delete_job_offers: true (can delete own) - upload_files: true (needed for logo upload) - Explicitly DENY: - edit_others_job_offers: false (cannot edit others' jobs) - edit_posts: false (no access to regular posts) - edit_pages: false (no access to pages) - manage_categories: false (no admin functions) Hook add_roles() to activation (via Activator class), not 'init' (roles persist in DB). Also create static remove_roles() method for deactivation cleanup. DO NOT give 'edit_posts' capability — this would grant access to regular blog posts. Role appears in WordPress users > Add New > Role dropdown ddhh_provider role registered with correct capabilities for job management only Task 2: Register ACF field group for job_offer metadata includes/class-acf-fields.php Create `DDHH_JM_ACF_Fields` class with static register_fields() method. Use acf_add_local_field_group() to register field group: - Title: 'Job Details' - Location: post_type == 'job_offer' - Position: 'normal' - Style: 'default' Fields: 1. job_location (type: text, label: 'Standort', required: true) 2. job_type (type: select, label: 'Art', choices: ['vollzeit' => 'Vollzeit', 'teilzeit' => 'Teilzeit', 'ehrenamt' => 'Ehrenamt'], required: true) 3. job_deadline (type: date_picker, label: 'Bewerbungsfrist', return_format: 'Y-m-d', required: false) 4. job_contact_email (type: email, label: 'Kontakt-E-Mail', required: true) 5. job_logo (type: image, label: 'Logo', return_format: 'id', preview_size: 'thumbnail', required: false) 6. job_deactivation_reason (type: textarea, label: 'Deaktivierungsgrund (intern)', rows: 3, required: false, conditional_logic: show only when post_status != 'publish') Hook register_fields() to 'acf/init' action. Use acf_add_local_field_group() not acf_register_field_group() — local fields are code-defined, not DB-stored. ACF fields appear on job_offer edit screen in WordPress admin ACF field group registered with all required metadata fields Before declaring plan complete: - [ ] Provider role exists with correct capabilities - [ ] Provider CANNOT edit regular posts/pages - [ ] Provider CAN upload files (for logos) - [ ] ACF fields appear on job_offer edit screen - [ ] All required fields marked as required - All tasks completed - Provider role restricts access appropriately - ACF fields capture all job metadata - Ready for Formidable form integration in Phase 2 After completion, create `.planning/phases/01-foundation-setup/01-03-SUMMARY.md`: # Phase 1 Plan 3: Roles & Fields Summary **Provider role and ACF field group for job metadata registered** ## Accomplishments - Custom role 'ddhh_provider' with job-only capabilities - ACF field group with 6 metadata fields - Proper capability restrictions (no posts/pages access) - Logo upload support ## Files Created/Modified - `includes/class-roles.php` - Role registration and cleanup - `includes/class-acf-fields.php` - ACF field group definition ## Decisions Made - Jobs submit to 'pending' status (admin approval required) - German field labels: Standort, Art, Bewerbungsfrist, etc. - Logo as image ID (not URL) for better media library integration - Deactivation reason field conditional on non-published status ## Issues Encountered None ## Next Step Phase 1 complete — all 3 plans done. Ready for Phase 2.