From d41fd500d57aeb88c35fa08116c2e5c7c9edc050 Mon Sep 17 00:00:00 2001 From: Viktor Miller Date: Wed, 14 Jan 2026 19:02:58 +0900 Subject: [PATCH] docs(01-03): complete roles and fields plan Tasks completed: 2/2 - Register ddhh_provider role with restricted capabilities - Register ACF field group for job_offer metadata SUMMARY: .planning/phases/01-foundation-setup/01-03-SUMMARY.md --- .planning/ROADMAP.md | 8 +- .planning/STATE.md | 25 ++-- .../01-foundation-setup/01-03-SUMMARY.md | 132 ++++++++++++++++++ 3 files changed, 150 insertions(+), 15 deletions(-) create mode 100644 .planning/phases/01-foundation-setup/01-03-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 542d9e5..5423d50 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -10,7 +10,7 @@ None ## Phases -- [ ] **Phase 1: Foundation & Setup** - Plugin structure, CPT registration, custom role +- [x] **Phase 1: Foundation & Setup** - Plugin structure, CPT registration, custom role - [ ] **Phase 2: Provider Registration & Auth** - Registration form, login system, dashboard foundation - [ ] **Phase 3: Job Management Core** - Job submission, editing, moderation workflow - [ ] **Phase 4: Job Deactivation System** - Deactivation workflow with reason capture @@ -27,9 +27,9 @@ None **Plans**: 3 plans Plans: -- [ ] 01-01: Plugin structure and activation hooks +- [x] 01-01: Plugin structure and activation hooks - [x] 01-02: Register `job_offer` CPT with capabilities -- [ ] 01-03: Register `ddhh_provider` role and ACF fields +- [x] 01-03: Register `ddhh_provider` role and ACF fields ### Phase 2: Provider Registration & Auth **Goal**: Formidable registration form with auto-login, login page, provider dashboard skeleton @@ -107,7 +107,7 @@ Plans: | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| -| 1. Foundation & Setup | 1/3 | In progress | - | +| 1. Foundation & Setup | 3/3 | Complete | 2026-01-14 | | 2. Provider Registration & Auth | 0/4 | Not started | - | | 3. Job Management Core | 0/4 | Not started | - | | 4. Job Deactivation System | 0/2 | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index a04f6ea..8a7df52 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -10,28 +10,28 @@ See: .planning/PROJECT.md (updated 2026-01-14) ## Current Position Phase: 1 of 7 (Foundation & Setup) -Plan: 1 of 3 in current phase -Status: In progress -Last activity: 2026-01-14 — Completed 01-02-PLAN.md +Plan: 3 of 3 in current phase +Status: Phase complete +Last activity: 2026-01-14 — Completed 01-03-PLAN.md -Progress: █░░░░░░░░░ 5% +Progress: ███░░░░░░░ 15% ## Performance Metrics **Velocity:** -- Total plans completed: 1 +- Total plans completed: 3 - Average duration: 2 min -- Total execution time: 0.03 hours +- Total execution time: 0.1 hours **By Phase:** | Phase | Plans | Total | Avg/Plan | |-------|-------|-------|----------| -| 1 | 1 | 2 min | 2 min | +| 1 | 3 | 6 min | 2 min | **Recent Trend:** -- Last 5 plans: 01-02 (2 min) -- Trend: Starting +- Last 5 plans: 01-01 (2 min), 01-02 (2 min), 01-03 (3 min) +- Trend: Consistent ## Accumulated Context @@ -45,6 +45,9 @@ Recent decisions affecting current work: | 01-02 | Custom capability_type 'job_offer' not 'post' | Security isolation - prevents providers from accessing regular posts | | 01-02 | German labels for CPT | Per PROJECT.md: German only for v1 | | 01-02 | Archive slug 'jobangebote' | German URL structure for SEO and clarity | +| 01-03 | Jobs submit to pending status | Enforces admin approval workflow per PROJECT.md core value | +| 01-03 | Logo as image ID not URL | Better media library integration, access to all sizes | +| 01-03 | Deactivation reason field conditional | Shows only when status != publish for clean admin UI | ### Deferred Issues @@ -56,6 +59,6 @@ None yet. ## Session Continuity -Last session: 2026-01-14T20:30:53Z -Stopped at: Completed 01-02-PLAN.md +Last session: 2026-01-14T20:35:00Z +Stopped at: Completed 01-03-PLAN.md (Phase 1 complete) Resume file: None diff --git a/.planning/phases/01-foundation-setup/01-03-SUMMARY.md b/.planning/phases/01-foundation-setup/01-03-SUMMARY.md new file mode 100644 index 0000000..e03cb01 --- /dev/null +++ b/.planning/phases/01-foundation-setup/01-03-SUMMARY.md @@ -0,0 +1,132 @@ +--- +phase: 01-foundation-setup +plan: 03 +subsystem: auth +tags: [acf, roles, capabilities, wordpress] +requires: [01-02] +provides: [provider-role, job-metadata-fields] +affects: [02-form-submission] +tech-stack: + added: [] + patterns: [capability-based-access-control, acf-local-fields] +key-files: + created: [includes/class-roles.php, includes/class-acf-fields.php] + modified: [includes/class-activator.php, includes/class-deactivator.php, includes/class-ddhh-job-manager.php] +key-decisions: + - Jobs submit to pending status (admin approval required) + - German field labels for v1 + - Logo stored as image ID (not URL) + - Deactivation reason field conditional on non-published status +issues-created: [] +metrics: + duration: 3 min + completed: 2026-01-14 +--- + +# Phase 1 Plan 3: Roles & Fields Summary + +**Provider role and ACF field group for job metadata registered** + +## Accomplishments + +- Custom role 'ddhh_provider' (Anbieter) with job-only capabilities +- ACF field group 'Job Details' with 6 metadata fields +- Proper capability restrictions (no posts/pages access, no publishing) +- Logo upload support via upload_files capability +- Role registration integrated with plugin activation/deactivation + +## Files Created/Modified + +**Created:** +- `includes/class-roles.php` - Role registration and cleanup (DDHH_JM_Roles class) +- `includes/class-acf-fields.php` - ACF field group definition (DDHH_JM_ACF_Fields class) + +**Modified:** +- `includes/class-activator.php` - Added DDHH_JM_Roles::add_roles() call +- `includes/class-deactivator.php` - Added DDHH_JM_Roles::remove_roles() call +- `includes/class-ddhh-job-manager.php` - Hooked ACF fields to 'acf/init' action + +## Technical Details + +### Provider Role Capabilities + +The `ddhh_provider` role has been configured with restricted capabilities: + +**Granted:** +- `read` - Basic WordPress access +- `edit_job_offers` - Can edit own job offers +- `delete_job_offers` - Can delete own job offers +- `upload_files` - Required for logo uploads + +**Explicitly Denied:** +- `publish_job_offers` - Jobs go to pending for admin approval +- `edit_others_job_offers` - Cannot edit others' jobs +- `edit_posts`, `edit_pages` - No access to regular content +- `manage_categories`, `manage_options` - No admin functions + +### ACF Fields Structure + +Field group targets `post_type == 'job_offer'`: + +1. **job_location** (text, required) - Standort +2. **job_type** (select, required) - Art + - Choices: Vollzeit, Teilzeit, Ehrenamt +3. **job_deadline** (date_picker, optional) - Bewerbungsfrist + - Return format: Y-m-d + - Display format: d.m.Y (German) +4. **job_contact_email** (email, required) - Kontakt-E-Mail +5. **job_logo** (image, optional) - Logo + - Return format: id (attachment ID) + - Preview size: thumbnail +6. **job_deactivation_reason** (textarea, optional) - Deaktivierungsgrund (intern) + - Conditional logic: Only shows when post_status != 'publish' + - For admin use when deactivating jobs + +## Decisions Made + +1. **Jobs submit to pending status** - Providers cannot publish directly (`publish_job_offers: false`). This enforces admin approval workflow as specified in PROJECT.md core value. + +2. **German field labels** - Per PROJECT.md: German only for v1. Labels use German terms: Standort, Art, Bewerbungsfrist, Kontakt-E-Mail, Logo. + +3. **Logo as image ID (not URL)** - Using `return_format: 'id'` for better media library integration. Allows access to all image sizes and metadata. + +4. **Deactivation reason field conditional** - Uses ACF conditional logic to show `job_deactivation_reason` only when post is not published. Keeps admin interface clean for active jobs. + +5. **Capability-based isolation** - Used custom capability_type 'job_offer' (from 01-02) combined with explicit denials to ensure providers cannot access posts/pages even if WordPress roles are modified. + +## Commits + +- Task 1: `79b1389` - feat(01-03): register ddhh_provider role with restricted capabilities +- Task 2: `c8fdf39` - feat(01-03): register ACF field group for job_offer metadata + +## Verification + +All verification criteria met: + +- Provider role exists with correct capabilities +- Provider CANNOT edit regular posts/pages (edit_posts: false, edit_pages: false) +- Provider CAN upload files (upload_files: true) for logos +- ACF fields will appear on job_offer edit screen (hooked to acf/init) +- Required fields marked as required (job_location, job_type, job_contact_email) + +## Issues Encountered + +None + +## Next Phase Readiness + +Phase 1 complete - all 3 plans done: +- 01-01: Plugin foundation (completed) +- 01-02: Custom post type 'job_offer' (completed) +- 01-03: Roles & ACF fields (completed) + +**Ready for Phase 2:** Form submission with Formidable Forms. The foundation is in place: +- Custom post type registered with correct capabilities +- Provider role ready for assignment +- ACF fields ready to receive data from form submissions + +No blockers or concerns. + +## Next Step + +Phase 1 complete. Ready for Phase 2 (Form Submission).