An ecological consultancy hired me to digitise their reporting workflow. Field surveys, FFH pre-checks, monitoring protocols — nine different report templates, each with mandatory fields, a corporate letterhead, and case numbers that can't collide. The interesting requirement: field staff have to fill in the reports on site , but most of them don't have WordPress accounts. Seasonal hires, freelancers, interns. Creating a user, assigning capabilities, deactivating later — too much friction. So they need guest access. Per report. With the right scope. With a clean expiry. Here's how I built it without a cron job. The shape of the problem Each report instance lives in a custom table: CREATE TABLE fm_form_instances ( id BIGINT PRIMARY KEY , project_id BIGINT , template_id BIGINT , status VARCHAR ( 32 ), -- 'entwurf' | 'abgeschlossen' data_json LONGTEXT , ... ); Enter fullscreen mode Exit fullscreen mode The state machine is intentionally tiny: a report is either draft ( entwurf ) or completed ( abgeschlossen ).…