Files
Viktor Miller 369870ef00 docs: add comprehensive CLAUDE.md for future AI assistance
Add detailed documentation covering plugin architecture, subsystems, workflows, and development practices. Includes GSD workflow requirement for all code changes.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-23 23:10:44 +09:00

278 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Digital Dabei Job Manager is a WordPress plugin providing a closed job board for "digital dabei Hamburg". External organizations (providers) self-register and manage job listings. Mentors (existing subscribers) view and apply to jobs. All jobs require admin moderation before publication.
**Core principle**: Every job goes through admin approval before mentors see it. The moderation flow is the trust layer protecting mentors from spam.
## Development Environment
- **Platform**: Local WP (WordPress development environment)
- **WordPress**: 6.0+, PHP 7.4+
- **Required Plugins**: ACF Pro, Formidable Forms Pro, Elementor Pro
- **Email**: WP Mail SMTP on production; disabled in Local WP dev environment
## Development Workflow with GSD
**IMPORTANT**: Use `/gsd` commands for all code-related work in this repository.
The GSD (Get Stuff Done) workflow provides:
- Structured planning and execution phases
- Automatic verification of changes
- State management across sessions
- Parallel execution when possible
Common commands:
- `/gsd:progress` - Check current state and next steps
- `/gsd:plan-phase` - Plan implementation for a phase
- `/gsd:execute-phase` - Execute all plans in a phase
- `/gsd:help` - View all available GSD commands
## Architecture
### Plugin Entry Point
The plugin follows WordPress singleton pattern with class-based initialization:
1. `ddhh-job-manager.php` - Main plugin file that:
- Loads Action Scheduler vendor library **first** (required for async operations)
- Defines constants (DDHH_JM_VERSION, DDHH_JM_PLUGIN_DIR, etc.)
- Requires all class files from `includes/`
- Initializes via `DDHH_JM_Job_Manager::get_instance()` on `plugins_loaded` hook
2. `includes/class-ddhh-job-manager.php` - Singleton orchestrator that initializes all subsystems via `init_hooks()`
### Core Subsystems
The plugin is organized into focused class files in `includes/`:
**Foundation Layer**:
- `class-post-types.php` - Registers `job_offer` CPT with custom capabilities
- `class-roles.php` - Manages `ddhh_provider` role with restricted capabilities
- `class-acf-fields.php` - Programmatically registers ACF field groups for job metadata
- `class-activator.php` / `class-deactivator.php` - Plugin lifecycle hooks
**User Management**:
- `class-formidable.php` - Integration layer for all Formidable Forms (registration, job submission, edit, deactivation, application). Uses form keys like 'provider_registration', 'job_submission', etc.
- `class-access-control.php` - Blocks providers from WP-Admin, enforces login requirements on job archives
- `class-user-preferences.php` - Manages mentor opt-in preferences for job notifications
**Job Workflows**:
- `class-dashboard.php` - Provides `[ddhh_provider_dashboard]` shortcode displaying provider's jobs
- `class-pages.php` - Creates/manages plugin pages (dashboard, login) via option storage
- `class-archive.php` - Filters job queries to show only published jobs to appropriate users
- `class-template.php` - Handles single job display and contact form modal
**Notifications & Async Processing**:
- `class-notifications.php` - Email system triggered by WordPress hooks (`ddhh_job_submitted`, `transition_post_status`, `frm_after_create_entry`)
- `class-scheduler.php` - Action Scheduler wrapper for async batch email processing (chunks of 50 users)
**Admin Experience**:
- `class-admin-ui.php` - Enhances admin screens with custom columns, quick links, status indicators
### Custom Roles & Capabilities
**ddhh_provider role**: Restricted role for external organizations
- Can create/edit/delete only their own `job_offer` posts
- Cannot access WP-Admin (redirected to frontend dashboard)
- Can edit their own profile (`profile.php` access allowed)
**Capability mapping** (in `class-post-types.php`):
- `edit_job_offer` - Owner can edit their own jobs
- `delete_job_offer` - Owner can delete their own jobs
- `read_job_offer` - Users can read published jobs
- Standard WordPress `map_meta_cap` filter enforces ownership
### Formidable Forms Integration
The plugin uses 5 Formidable forms, identified by form keys:
1. **provider_registration** (F1) - Creates user with `ddhh_provider` role, auto-login
2. **job_submission** (F2) - Creates `job_offer` post with `pending` status, maps ACF fields
3. **job_edit** (F3) - Updates existing job (ownership validated), preserves submission date
4. **job_deactivation** (F4) - Sets status to `draft`, captures deactivation reason
5. **job_application** (F5) - Mentor applies to job, emails provider contact address
**Form hooks** (`class-formidable.php`):
- Registration: `frm_after_create_entry` → auto-login → redirect to dashboard
- Job submission: `frm_after_create_entry` → fires `ddhh_job_submitted` action → admin notification
- Job edit: `frm_after_update_entry` → fires `ddhh_job_edited` action → admin notification
- Application: `frm_after_create_entry` → emails provider's contact email from ACF field
### Email Notification System
**Immediate notifications** (`class-notifications.php`):
- Admin receives email on job submission with edit/view links
- Admin receives email on job edit with change summary
- Admin receives email on deactivation with reason
- Provider receives email when mentor applies (via Formidable)
**Async batch notifications** (`class-scheduler.php`):
- Mentor notification on job publish uses Action Scheduler
- Users are queried for `ddhh_jm_notification_optin` meta
- Batched into groups of 50 to prevent email provider limits
- Each batch scheduled as separate `ddhh_jm_send_mentor_notification_batch` action
### Access Control Layers
1. **WP-Admin lockout**: Providers redirected to dashboard unless accessing `profile.php` or AJAX
2. **Dashboard protection**: `template_redirect` hook checks user role, redirects non-providers
3. **Archive protection**: Jobs require login; only `publish` status shown to mentors
4. **Single job protection**: Login required to view job details
5. **Ownership validation**: Forms validate current user owns the job before editing/deactivation
### Template System
**Frontend templates** (`templates/`):
- `provider-dashboard.php` - Displays provider's jobs in table format with status badges and action links
**Elementor integration**:
- Job archive uses Elementor Loop Grid (no custom template file)
- Job detail page uses Elementor single post template with ACF dynamic tags
- Contact form modal injected via `the_content` filter in `class-template.php`
### Job Lifecycle
```
Provider submits → pending → Admin reviews → publish → Mentors see + notified
Admin can reject → trash
Provider deactivates → draft (with reason stored in meta)
```
**Status hooks**:
- `ddhh_job_submitted` - Fired after new job metadata saved (form entry ID passed)
- `ddhh_job_edited` - Fired after job update metadata saved (form entry ID passed)
- `transition_post_status` - Used for publish detection and deactivation detection
### ACF Field Groups
Programmatically registered in `class-acf-fields.php`:
- **Job Details**: `job_location`, `job_type`, `job_deadline` (date picker), `contact_email`
- **Deactivation**: `deactivation_reason`, `deactivation_date`
- **Metadata**: `submission_date` (preserved during edits)
All fields support German labels matching site language.
## Development Workflow
### Testing Locally
Since email is disabled in Local WP, test email functionality by:
1. Checking Action Scheduler status: WP Admin → Tools → Scheduled Actions
2. Monitoring logs: `error_log()` calls throughout notification classes
3. Using a plugin like WP Mail Logging to capture emails during dev
### Working with Forms
Formidable forms are managed through the Formidable UI. When referencing forms in code:
- Use form keys (e.g., 'job_submission') not IDs
- Form ID lookup happens via `FrmForm::getOne('form_key')`
- Field IDs are stored in form configuration, not hardcoded
### Modifying Email Templates
Email templates are inline in `class-notifications.php`:
- Admin emails use `wp_mail()` with HTML content
- Mentor notification emails use `wp_mail()` with plain text
- All emails include job title, provider name, and relevant links
- Date formatting: Use `get_field()` for ACF dates, format with German locale
### Adding New Notifications
1. Identify triggering event (form submission, status change, custom action)
2. Add notification method to `class-notifications.php`
3. Hook into appropriate action in `setup_hooks()`
4. For batch processing, use `DDHH_JM_Scheduler::schedule_mentor_notification_batch()`
## Common Tasks
### Debugging Action Scheduler
```bash
# View scheduled actions in WP CLI
wp action-scheduler list --status=pending
wp action-scheduler list --status=failed
# Run pending actions manually
wp action-scheduler run --batch-size=10
# Clean up old actions
wp action-scheduler clean --days=90
```
### Checking Provider Permissions
Providers should NOT be able to:
- Access WP-Admin (except profile.php)
- Edit other providers' jobs
- Publish jobs directly (must be pending)
- View unpublished jobs by other providers
### Verifying Job Moderation Flow
1. Log in as provider → Submit job → Should create `pending` post
2. Admin receives email with job details and moderation links
3. Admin publishes job → Opted-in mentors receive notification (async batches)
4. Provider sees published job in dashboard
5. Mentors can view and apply to job
### Date Field Handling
Job deadlines use ACF date picker:
- Format conversion in Formidable forms: Slashes auto-converted to dots for display
- Before submission: Dots converted back to ISO format (YYYY-MM-DD)
- Display: Use `get_field('job_deadline')` returns 'Ymd', format with `date_i18n()`
- Validation: Date fields are optional (empty string is valid)
### Logo Auto-Cropping
Featured images (logos) auto-crop to 200×200px on upload:
- Handled by `class-post-types.php` registering 'job-logo' image size
- Uses WordPress `add_image_size()` with hard crop enabled
- Images uploaded via Formidable forms trigger standard WP media processing
## Project State
**Currently**: Phase 6 (Email Notifications) is mostly complete. Phase 7 (Testing & Polish) is next.
**What's working**:
- Provider registration and authentication
- Job submission, editing, deactivation workflows
- Admin moderation and notifications
- Mentor job browsing and applications
- Opt-in preferences for mentor notifications
- Action Scheduler integration for async processing
**What's pending**:
- Phase 6.3: Async batch email processing on job publish (implementation in progress)
- Phase 7: End-to-end testing and production deployment prep
**Documentation**: See `.planning/` for detailed project documentation:
- `PROJECT.md` - Requirements and context
- `ROADMAP.md` - Phase breakdown and progress
- `STATE.md` - Current work and blockers
- `phases/` - Detailed plans and summaries for each phase
## Code Standards
- **WordPress Coding Standards**: Follow WordPress PHP coding standards
- **Text Domain**: Use `ddhh-job-manager` for all translatable strings
- **German Language**: All user-facing text in German
- **Security**: Validate ownership, escape output, verify nonces in forms
- **Hook Naming**: Use `ddhh_jm_` prefix for custom actions/filters
- **Class Naming**: Use `DDHH_JM_` prefix, one class per file
- **Static Methods**: Use static methods for classes that don't maintain state
- **Direct Exit**: Always include `defined( 'ABSPATH' ) || exit;` at top of PHP files
## Critical Files to Review Before Major Changes
- `ddhh-job-manager.php` - Plugin initialization order matters (Action Scheduler first)
- `class-ddhh-job-manager.php` - Hook registration sequence
- `class-formidable.php` - Form IDs and field mappings
- `class-notifications.php` - Email templates and triggering logic
- `class-access-control.php` - Security boundaries for providers
- `class-post-types.php` - Capability mapping for `job_offer` posts