From 054adb721a9c6e26eba45beb1813b64ffc9cf537 Mon Sep 17 00:00:00 2001 From: Viktor Miller Date: Wed, 14 Jan 2026 19:12:07 +0900 Subject: [PATCH] docs(02): create phase 2 plans Phase 02: Provider Registration & Auth - 4 plans created - 8 total tasks defined - Ready for execution Plans: - 02-01: Formidable registration form with auto-login - 02-02: Combined login/registration page - 02-03: Provider dashboard template - 02-04: Access control and redirects --- .../02-01-PLAN.md | 141 +++++++++++++++++ .../02-02-PLAN.md | 141 +++++++++++++++++ .../02-03-PLAN.md | 148 ++++++++++++++++++ .../02-04-PLAN.md | 134 ++++++++++++++++ 4 files changed, 564 insertions(+) create mode 100644 .planning/phases/02-provider-registration-auth/02-01-PLAN.md create mode 100644 .planning/phases/02-provider-registration-auth/02-02-PLAN.md create mode 100644 .planning/phases/02-provider-registration-auth/02-03-PLAN.md create mode 100644 .planning/phases/02-provider-registration-auth/02-04-PLAN.md diff --git a/.planning/phases/02-provider-registration-auth/02-01-PLAN.md b/.planning/phases/02-provider-registration-auth/02-01-PLAN.md new file mode 100644 index 0000000..cb6dcf7 --- /dev/null +++ b/.planning/phases/02-provider-registration-auth/02-01-PLAN.md @@ -0,0 +1,141 @@ +--- +phase: 02-provider-registration-auth +plan: 01 +type: execute +depends_on: [] +files_modified: [includes/class-formidable.php] +--- + + +Create Formidable Forms registration form with auto-login and provider role assignment. + +Purpose: Enable external organizations to self-register as providers without admin intervention. +Output: Working registration form (F1) that creates WordPress users with ddhh_provider role and logs them in automatically. + + + +~/.claude/get-shit-done/workflows/execute-plan.md +./summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/01-foundation-setup/01-03-SUMMARY.md + +**From Phase 1:** +- Provider role `ddhh_provider` exists with capabilities: read, edit_job_offers, delete_job_offers, upload_files +- Role explicitly denies: publish_job_offers, edit_others_job_offers, edit_posts, edit_pages +- German UI required (v1) + +**Tech stack:** Formidable Forms Pro with Registration Add-on available + + + + + + Task 1: Create Formidable registration form + N/A (Formidable forms stored in WP database) + +Create Formidable form via WordPress admin: +- Form name: "Provider Registration" (Anbieter-Registrierung) +- Fields (all required): + 1. organization_name (text) - Label: "Organisationsname" + 2. contact_person (text) - Label: "Ansprechperson" + 3. email (email) - Label: "E-Mail" + 4. password (password) - Label: "Passwort" + 5. password_confirm (password) - Label: "Passwort bestätigen" +- German field labels per PROJECT.md +- Email field: unique validation (WordPress user_email must be unique) +- Password fields: min 8 characters, must match + +Create helper class `includes/class-formidable.php` with static method get_registration_form_id() that returns the form ID (for use in shortcodes). + +DO NOT use Formidable's default English labels - all labels must be German. + + Form appears in Formidable Forms list, fields have German labels, email validation set to unique + Registration form created with 5 fields, all required, German labels, email uniqueness enforced + + + + Task 2: Configure auto-login and role assignment + includes/class-formidable.php + +In class-formidable.php, create static method setup_registration_hooks(): + +Hook into Formidable's `frm_after_create_entry` action: +- Check if form_id matches registration form +- Extract email and password from entry +- Create WordPress user with wp_insert_user(): + - user_login: email prefix (before @) + - user_email: email from form + - user_pass: password from form + - role: 'ddhh_provider' (from Phase 1) + - display_name: contact_person from form +- Store organization_name as user meta 'ddhh_org_name' +- Auto-login user with wp_set_auth_cookie($user_id, true) +- Prevent duplicate submissions: check if email exists before creating user + +Hook this to 'init' action in main class. + +DO NOT assign 'subscriber' role - only 'ddhh_provider' role from Phase 1. +DO NOT send WordPress default registration email - providers should be logged in immediately. + + Create test user via form, check user appears in WP users with ddhh_provider role, auto-login occurs (user is logged in after submission) + Form submission creates user with ddhh_provider role, auto-logs in user, stores org name as meta, no duplicate users created + + + + + +Before declaring plan complete: +- [ ] Registration form exists in Formidable with German labels +- [ ] Email field enforces uniqueness +- [ ] Form submission creates WordPress user with ddhh_provider role +- [ ] User is automatically logged in after registration +- [ ] Organization name stored as user meta +- [ ] No duplicate users created on re-submission + + + + +- All tasks completed +- Form functional and creates users +- Auto-login works +- Role assignment correct (ddhh_provider) +- Ready for 02-02 (registration page integration) + + + +After completion, create `.planning/phases/02-provider-registration-auth/02-01-SUMMARY.md`: + +# Phase 2 Plan 1: Provider Registration Form Summary + +**Formidable registration form with auto-login and provider role assignment** + +## Accomplishments + +- Registration form with 5 fields (German labels) +- Email uniqueness validation +- Auto-login after successful registration +- ddhh_provider role assignment +- Organization name storage in user meta + +## Files Created/Modified + +- Form created in WordPress database (Formidable) +- `includes/class-formidable.php` - Registration hooks and user creation + +## Decisions Made + +[Document any implementation choices or deviations] + +## Issues Encountered + +[Problems and resolutions, or "None"] + +## Next Step + +Ready for 02-02-PLAN.md (can run in parallel with 02-03) + diff --git a/.planning/phases/02-provider-registration-auth/02-02-PLAN.md b/.planning/phases/02-provider-registration-auth/02-02-PLAN.md new file mode 100644 index 0000000..482a80f --- /dev/null +++ b/.planning/phases/02-provider-registration-auth/02-02-PLAN.md @@ -0,0 +1,141 @@ +--- +phase: 02-provider-registration-auth +plan: 02 +type: execute +depends_on: ["02-01"] +files_modified: [includes/class-pages.php] +--- + + +Create combined login/registration page with Formidable shortcodes. + +Purpose: Provide single entry point for providers to register or log in. +Output: WordPress page with registration form and login form in tabbed or stacked view. + + + +~/.claude/get-shit-done/workflows/execute-plan.md +./summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/phases/02-provider-registration-auth/02-01-SUMMARY.md + +**From 02-01:** +- Registration form exists with ID accessible via DDHH_JM_Formidable::get_registration_form_id() +- Form creates users with ddhh_provider role and auto-logs in + +**Requirements:** +- German UI (v1) +- Combined login/registration view +- Match existing Elementor site style + + + + + + Task 1: Create login/registration page + includes/class-pages.php + +Create `includes/class-pages.php` with static method create_provider_pages(): + +Use wp_insert_post() to create page "Anbieter Login": +- post_title: 'Anbieter Login' +- post_name: 'anbieter-login' +- post_status: 'publish' +- post_type: 'page' +- post_content: Two-section layout with: + 1. Registration section with heading "Neu registrieren" and Formidable shortcode [formidable id={registration_form_id}] + 2. Login section with heading "Bereits registriert?" and WordPress default login form wp_login_form() + +Store page ID in option 'ddhh_jm_login_page_id' for later reference. + +Hook create_provider_pages() to plugin activation (call in Activator class). + +Check if page already exists (by post_name) before creating to avoid duplicates on re-activation. + +DO NOT create separate pages for login vs registration - combine in one page per PROJECT.md. + + Page "Anbieter Login" exists at /anbieter-login/, displays registration form and login form + Page created, accessible, shows both registration and login forms, German headings + + + + Task 2: Style combined view for consistency + includes/class-pages.php + +Add basic styling to make login/registration sections visually distinct: + +In post_content, wrap sections in div.ddhh-auth-container with: +- Registration section: div.ddhh-register-section +- Login section: div.ddhh-login-section + +Add simple CSS (inline in page or via enqueued stylesheet): +- Two-column layout on desktop (50/50 split) +- Stacked on mobile +- Visual separator (border or background color difference) +- Headings styled consistently + +Match Elementor site colors if possible (check if theme provides CSS variables). + +DO NOT over-style - keep it minimal and functional for now. Phase 7 will polish UI. + + Page displays cleanly on desktop (side-by-side) and mobile (stacked), forms readable and usable + Combined view styled, responsive, visually clear separation between register and login sections + + + + + +Before declaring plan complete: +- [ ] Page "Anbieter Login" exists and is published +- [ ] Registration form displays via shortcode +- [ ] Login form displays via wp_login_form() +- [ ] Layout responsive (desktop: side-by-side, mobile: stacked) +- [ ] German headings used +- [ ] Page accessible at /anbieter-login/ + + + + +- All tasks completed +- Combined login/registration page functional +- Both forms display and work +- Responsive layout +- Ready for Phase 3 (job submission forms) + + + +After completion, create `.planning/phases/02-provider-registration-auth/02-02-SUMMARY.md`: + +# Phase 2 Plan 2: Login/Registration Page Summary + +**Combined login/registration page with responsive layout** + +## Accomplishments + +- WordPress page "Anbieter Login" created programmatically +- Registration form integrated via Formidable shortcode +- WordPress login form integrated +- Responsive two-column/stacked layout +- German headings + +## Files Created/Modified + +- `includes/class-pages.php` - Page creation and layout +- `includes/class-activator.php` - Hook create_provider_pages() + +## Decisions Made + +[Document layout choices, styling approach] + +## Issues Encountered + +[Problems and resolutions, or "None"] + +## Next Step + +Ready for 02-04-PLAN.md (sequential after 02-03 completes) + diff --git a/.planning/phases/02-provider-registration-auth/02-03-PLAN.md b/.planning/phases/02-provider-registration-auth/02-03-PLAN.md new file mode 100644 index 0000000..c9c8263 --- /dev/null +++ b/.planning/phases/02-provider-registration-auth/02-03-PLAN.md @@ -0,0 +1,148 @@ +--- +phase: 02-provider-registration-auth +plan: 03 +type: execute +depends_on: [] +files_modified: [includes/class-dashboard.php, templates/provider-dashboard.php] +--- + + +Create provider dashboard template that lists user's own job_offer posts. + +Purpose: Give providers a central view of their published job listings. +Output: Dashboard page accessible at /anbieter-dashboard/ showing provider's jobs with edit/view links. + + + +~/.claude/get-shit-done/workflows/execute-plan.md +./summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/phases/01-foundation-setup/01-02-SUMMARY.md +@.planning/phases/01-foundation-setup/01-03-SUMMARY.md + +**From Phase 1:** +- Custom post type `job_offer` exists with custom capabilities +- Providers have edit_job_offers capability (own posts only) +- ACF fields available: job_location, job_type, job_deadline, job_contact_email, job_logo + +**Requirements:** +- German UI +- List only current user's job_offer posts +- Show edit and view links +- Simple table layout + + + + + + Task 1: Create dashboard template + templates/provider-dashboard.php, includes/class-dashboard.php + +Create `templates/provider-dashboard.php`: +- Check if user is logged in and has ddhh_provider role (else show error message) +- Query current user's job_offer posts using WP_Query: + - post_type: 'job_offer' + - author: get_current_user_id() + - post_status: ['publish', 'pending', 'draft'] + - orderby: 'date' + - order: 'DESC' +- Display results in HTML table with columns: + 1. Title (job post title) + 2. Status (Veröffentlicht / Ausstehend / Entwurf) + 3. Location (ACF field job_location) + 4. Type (ACF field job_type) + 5. Actions (Bearbeiten link to edit screen, Ansehen link to public view if published) +- German labels for all headings +- If no jobs, show message "Sie haben noch keine Stellenangebote erstellt." + +Create `includes/class-dashboard.php` with static method get_template(): +- Returns path to templates/provider-dashboard.php +- Handles template loading with load_template() + +DO NOT use wp-admin edit links - providers should not access WP-Admin. Use frontend edit approach or direct edit_post_link() which WordPress handles based on capabilities. + + Template file exists, displays current user's jobs in table format, German labels present + Dashboard template created, queries user's posts correctly, displays in table with German labels + + + + Task 2: Create dashboard page and shortcode + includes/class-dashboard.php, includes/class-pages.php + +In class-pages.php create_provider_pages(), add second page creation: +- post_title: 'Anbieter Dashboard' +- post_name: 'anbieter-dashboard' +- post_content: [ddhh_provider_dashboard] shortcode +- Store page ID in option 'ddhh_jm_dashboard_page_id' + +In class-dashboard.php, register shortcode 'ddhh_provider_dashboard': +- Shortcode handler loads templates/provider-dashboard.php +- Returns output buffered content + +Check page doesn't already exist before creating. + +Hook shortcode registration to 'init' action in main class. + + Dashboard page exists at /anbieter-dashboard/, shortcode renders template, table displays user's jobs + Dashboard page created, shortcode functional, displays job list for logged-in provider + + + + + +Before declaring plan complete: +- [ ] Dashboard template queries only current user's job_offer posts +- [ ] Table displays with German column headings +- [ ] Edit and View links present for each job +- [ ] Status displayed in German (Veröffentlicht/Ausstehend/Entwurf) +- [ ] Empty state message shows when no jobs exist +- [ ] Page accessible at /anbieter-dashboard/ + + + + +- All tasks completed +- Dashboard functional for providers +- Queries scoped to current user +- German UI throughout +- Ready for 02-04 (access control) + + + +After completion, create `.planning/phases/02-provider-registration-auth/02-03-SUMMARY.md`: + +# Phase 2 Plan 3: Provider Dashboard Summary + +**Dashboard template displaying provider's own job listings** + +## Accomplishments + +- Dashboard template with WP_Query for current user's jobs +- Table layout with German column headings +- Status display (Veröffentlicht/Ausstehend/Entwurf) +- Edit and View links for each job +- Shortcode integration +- Dashboard page created at /anbieter-dashboard/ + +## Files Created/Modified + +- `templates/provider-dashboard.php` - Dashboard template +- `includes/class-dashboard.php` - Shortcode and template loader +- `includes/class-pages.php` - Added dashboard page creation + +## Decisions Made + +[Document query approach, template structure] + +## Issues Encountered + +[Problems and resolutions, or "None"] + +## Next Step + +Ready for 02-04-PLAN.md + diff --git a/.planning/phases/02-provider-registration-auth/02-04-PLAN.md b/.planning/phases/02-provider-registration-auth/02-04-PLAN.md new file mode 100644 index 0000000..f5b4e7e --- /dev/null +++ b/.planning/phases/02-provider-registration-auth/02-04-PLAN.md @@ -0,0 +1,134 @@ +--- +phase: 02-provider-registration-auth +plan: 04 +type: execute +depends_on: ["02-03"] +files_modified: [includes/class-access-control.php] +--- + + +Implement access control and redirects for provider role. + +Purpose: Prevent providers from accessing WP-Admin (except profile) and protect dashboard page. +Output: Access control hooks that enforce provider restrictions per PROJECT.md requirements. + + + +~/.claude/get-shit-done/workflows/execute-plan.md +./summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/phases/01-foundation-setup/01-03-SUMMARY.md +@.planning/phases/02-provider-registration-auth/02-03-SUMMARY.md + +**From PROJECT.md:** +- Constraint: "Providers: restricted capabilities, no WP-Admin access except profile" +- Core value: Admin moderation is the trust layer + +**From Phase 1:** +- Provider role `ddhh_provider` exists with no admin capabilities + +**From 02-03:** +- Dashboard page exists at /anbieter-dashboard/ + + + + + + Task 1: Redirect providers away from WP-Admin + includes/class-access-control.php + +Create `includes/class-access-control.php` with static method setup_hooks(): + +Hook into 'admin_init' action: +- Check if current user has role 'ddhh_provider' (use wp_get_current_user()->roles) +- If ddhh_provider AND not accessing profile.php or admin-ajax.php: + - Get dashboard page URL: get_permalink(get_option('ddhh_jm_dashboard_page_id')) + - Redirect using wp_redirect($dashboard_url) and exit +- Allow profile.php (providers can edit their profile) +- Allow admin-ajax.php (needed for AJAX requests from frontend) + +Hook this to 'init' action in main class. + +DO NOT block all admin access - allow profile.php so providers can change their password and email. +DO NOT redirect on AJAX requests (admin-ajax.php must remain accessible). + + Provider user accessing wp-admin/ gets redirected to /anbieter-dashboard/, but wp-admin/profile.php remains accessible + WP-Admin redirect implemented, profile access preserved, dashboard redirect functional + + + + Task 2: Protect dashboard page (logged-in providers only) + includes/class-access-control.php + +In class-access-control.php, add static method protect_dashboard(): + +Hook into 'template_redirect' action: +- Check if current page is dashboard page (using get_option('ddhh_jm_dashboard_page_id')) +- If yes: + - Check if user is logged in: is_user_logged_in() + - Check if user has ddhh_provider role + - If NOT logged in OR NOT ddhh_provider: redirect to login page (get_option('ddhh_jm_login_page_id')) + +This ensures only logged-in providers can access the dashboard. + +DO NOT use wp_die() - use wp_redirect() to login page with a friendly redirect flow. + + Non-logged-in users accessing /anbieter-dashboard/ get redirected to /anbieter-login/, logged-in providers see dashboard + Dashboard protected, only providers can access, redirects to login page if unauthorized + + + + + +Before declaring plan complete: +- [ ] Provider accessing wp-admin/ gets redirected to dashboard +- [ ] Provider CAN access wp-admin/profile.php +- [ ] Non-logged-in users accessing dashboard get redirected to login +- [ ] Logged-in providers CAN access dashboard +- [ ] Admin users are not affected by redirects + + + + +- All tasks completed +- Provider role properly restricted from WP-Admin +- Dashboard protected and accessible only to providers +- Profile access preserved for providers +- Phase 2 complete - ready for Phase 3 (job submission forms) + + + +After completion, create `.planning/phases/02-provider-registration-auth/02-04-SUMMARY.md`: + +# Phase 2 Plan 4: Access Control & Redirects Summary + +**Access control enforcing provider restrictions and dashboard protection** + +## Accomplishments + +- WP-Admin redirect for providers (except profile.php) +- Dashboard page protection (logged-in providers only) +- Login redirect for unauthorized dashboard access +- Profile access preserved for providers + +## Files Created/Modified + +- `includes/class-access-control.php` - Redirect hooks and protection logic +- `includes/class-ddhh-job-manager.php` - Hook access control setup + +## Decisions Made + +[Document redirect approach, exceptions made] + +## Issues Encountered + +[Problems and resolutions, or "None"] + +## Next Step + +Phase 2 complete. Ready for Phase 3 (Job Management Core). +