Files
2026-05-05 22:36:55 +02:00

6.5 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, started, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration started completed
01-contact-attachments 01 forms
php
mysql
uploads
contact-forms
Persistent public attachment links for file-enabled contact forms
Automatic `contact_messages.attachments` schema upgrade
50 MB upload limit with matching UI copy
contact-forms
database
uploads
added patterns
Direct PDO schema self-upgrade for external contact database
Dedicated public upload directory outside `temp/`
created modified
plugins/special-actions-middle.php
templates_user/pages/page-contact-v9.php
templates_user/modal/modal.php
.paul/codebase/db_schema.md
.paul/codebase/tech_changelog.md
Store attachment links in one `contact_messages.attachments` column as JSON.
Use public links under `/uploads/contact-attachments/YYYY/mm/`.
Restrict uploads to an extension allowlist and 50 MB per file.
Contact form files are persisted once and the same stored file path is used for email attachment delivery.
~20min 2026-05-05T22:11:41+02:00 2026-05-05T22:33:44+02:00

Phase 1 Plan 01: Contact Attachments Summary

File-enabled contact forms now persist uploaded files outside temp/ and store public links in the contact submission row.

Performance

Metric Value
Duration ~20 min
Started 2026-05-05T22:11:41+02:00
Completed 2026-05-05T22:33:44+02:00
Tasks 3 completed
Files modified 5 implementation/docs files plus PAUL state files

Acceptance Criteria Results

Criterion Status Notes
AC-1: Persistent Attachment Links Pass Production test confirmed latest contact_messages row contains a JSON attachment link and the public PDF URL returns HTTP 200.
AC-2: Automatic Database Upgrade Pass ensureContactMessagesAttachmentsColumn() creates attachments TEXT NULL when missing and tolerates duplicate-column races.
AC-3: Upload Restrictions Pass Backend allowlist and 50 MB limit added; invalid uploads stop before partial DB save/email.
AC-4: Form Limit Information Pass Current contact page and modal state 50 MB and allowed types; fileuploader config uses matching limit/extensions.

Accomplishments

  • Added reusable contact attachment upload handling in plugins/special-actions-middle.php.
  • Replaced targeted temp/ upload loops for /kontakt/ file-enabled handlers and modal-contact-form.
  • Added automatic schema evolution for contact_messages.attachments.
  • Updated visible upload guidance and client-side validation to match server rules.
  • Verified a real production submission with attachment saved correctly.

Task Commits

No git commit was created during UNIFY. The worktree had extensive pre-existing unrelated changes, including modified files touched by this phase, so committing would risk bundling user work. Commit intentionally deferred.

Files Created/Modified

File Change Purpose
plugins/special-actions-middle.php Modified Upload persistence helper, schema self-upgrade, attachment links passed to saveContactData().
templates_user/pages/page-contact-v9.php Modified Upload copy and fileuploader limit/extensions for current contact page.
templates_user/modal/modal.php Modified Upload copy and fileuploader limit/extensions for modal form.
.paul/codebase/db_schema.md Modified Documented external contact_messages schema and attachments column.
.paul/codebase/tech_changelog.md Modified Recorded technical change for future context.
.paul/changelog/2026-05-05.md Created Human-readable PAUL changelog entry.
.paul/STATE.md Modified Loop and phase state closure.
.paul/ROADMAP.md Modified Phase marked complete.
.paul/PROJECT.md Modified Requirement moved into shipped/validated context.

Decisions Made

Decision Rationale Impact
Store public links in one column User chose one-column storage; simplest production migration. attachments stores JSON array of public paths.
Dedicated public upload folder temp/ is cleaned automatically. New uploads go to /uploads/contact-attachments/YYYY/mm/.
Restrict uploads to allowlist + 50 MB User requested restrictions and visible limit. Server and UI now enforce aligned rules.
Defer landing page upload persistence Request scoped to /kontakt/ and modal. send-contact-landing still uses legacy temp flow and is documented as deferred.
Skip automatic git commit Dirty worktree contained pre-existing unrelated/user changes. No accidental commit of unrelated work; manual commit can be made later.

Deviations from Plan

Summary

Type Count Impact
Deferred 1 Landing page handler remains legacy because it is outside requested scope.
Transition deviation 1 Git commit skipped to avoid bundling pre-existing dirty worktree changes.

Auto-fixed Issues

1. Duplicate-column race tolerance

  • Found during: Task 1 review
  • Issue: Two simultaneous first submissions could both try to add attachments.
  • Fix: Duplicate-column PDO errors are tolerated after the second request loses the race.
  • Files: plugins/special-actions-middle.php
  • Verification: php -l plugins/special-actions-middle.php

Deferred Items

  • Landing page attachment persistence can be planned separately if send-contact-landing should also retain uploads outside temp/.

Issues Encountered

Issue Resolution
Direct DB access from local machine failed because mysql8 is internal and external DB access is denied. Used a short-lived FTP-uploaded diagnostic script on the production webroot, then deleted it.
Initial diagnostic file_exists() check was false due hosting DOCUMENT_ROOT behavior. Verified the public URL returns HTTP 200 and FTP confirms the file exists at the expected path.

Next Phase Readiness

Ready:

  • /kontakt/ file-enabled forms and modal now retain uploaded attachments.
  • Database schema self-upgrade is in place.
  • Public upload directory pattern is established.

Concerns:

  • The project still has broader security concerns documented in .paul/codebase/concerns.md.
  • The landing page upload flow still uses temp/ if that page remains business-critical.

Blockers:

  • None for this phase.

Phase: 01-contact-attachments, Plan: 01 Completed: 2026-05-05