Files
bmp-website-2026/docs/client-feedback-deployment-readiness.md
2026-07-31 19:33:46 +02:00

12 KiB
Raw Blame History

Client feedback rollout: deployment readiness

Verification date: 2026-07-31

Decision

Tasks 117 are ready for a coordinated schema-changing deployment. Local code, CMS ownership, isolated database migrations, the full serial Vitest integration suite, the production webpack build, generated sitemaps, and public/draft behavior have been verified.

The rollout is not yet complete in production. Production is still serving revision 740e302c58f8, before Tasks 117, and the production-write gates listed below remain intentionally blocked. No production database, media, publication state, or deployment was changed during Task 18.

Commit sequence

The clean root worktree and this verification worktree both started at 07e9458aaf2796f5f48a69302acd26914032b879. The root main history contains exactly these 17 Task 117 commits after production revision 740e302c58f8:

Task Commit Subject
1 fec1bab2e521d38af9de3c7c3c315c0da91795e7 fix(cms): enforce public publication contract
2 b18bbbe36ad395cb26011d6032e06f460ded3f2a fix(cms): filter unpublished relationships
3 8dc17c0fea9420b2854a074d3924d4341147f04b fix(cms): remove unpublished content fallbacks
4 ab47571139a177339a002ff62336a61f7a44d4c6 refactor(cms): remove obsolete page fields
5 e3c47c4500150be0fb40caa6cb4ae2619f61789c feat(cms): add network page video upload
6 c2dc42f243e58c7cb81e2e23e2aa2e34110ca4fc feat(cms): add press contact image
7 ebecf66e6fcb8514d5206bfc80ad36f4c9939e4e fix(participation): repair process timeline
8 30efb4b36ee7c0187c0274f319679846287ae3cb feat(network): add responsive sponsor hierarchy
9 95037e99089837a64a4315f6d2a467e8e5be61f5 feat(cms): clarify sponsor ordering
10 adda9ddbd07a7bb04947c349a2117dd31879d190 fix(home): slow sponsor ticker
11 f465839af0e49fa5021272c0a85786a90a763589 fix(home): honor phase headline line breaks
12 5b62abf8d4b205d8603f3a0d34393d47d30412e8 fix(home): rebalance application form split
13 d7a720460f542fc6c34ad3bd46d2eb5be1e2be6e docs(home): verify application panel color
14 4bb265dac1b7862db1e468d63126a07e9eaa8aec fix(participation): clarify eligibility hierarchy
15 3c28f6ff9c53486b87c2d45ffb57e35bc5a025d7 fix(about): rebalance relevance section
16 0a19abd0b080095748f1de28dfe829da62316e96 fix(about): align facts and caption
17 07e9458aaf2796f5f48a69302acd26914032b879 fix(seo): correct sitemap routes

Task 18 is the single commit containing this report and the regression-test cleanup described below. Its exact hash is recorded in the Task 18 handoff because a commit cannot embed its own hash.

No Task 117 integration is missing, and no unrelated tracked changes were present at the start of Task 18.

Automated verification

All database-backed checks used copies of the current local content.db. The source database SHA-256 was fb7de5d9f1fcf3a7c27494efe7f3111cba4173bc986a38ea62c9cf6d5840425e and was never migrated or otherwise mutated.

Integration tests

  • Focused publication, relationship, sitemap, CMS-field, media, responsive section, timeline, sponsor, press, home, and about tests passed.

  • Complete serial suite against a freshly copied and migrated database: 21 files, 92 tests, all passed.

  • Serial command shape used to avoid SQLite parallel-write contention:

    DATABASE_URL=file:/absolute/path/to/isolated.db \
    PAYLOAD_SECRET=task18-isolated-verification \
    PAYLOAD_MIGRATING=true \
    SITE_URL=http://127.0.0.1:3100 \
    ./node_modules/.bin/vitest run \
      --config ./vitest.config.mts \
      --maxWorkers=1 \
      --no-file-parallelism \
      --hookTimeout=30000
    

PAYLOAD_MIGRATING=true is required for tests against an explicitly migrated database so Payload does not also attempt its development schema-push path.

Task 18 regression fix

tests/int/publication-contract.int.spec.ts created unique publication fixtures but deleted only their media record. A second run against the same isolated database therefore failed unique slug and stableId validation. Task 18 now deletes every created document before deleting the media record. The focused suite passed twice consecutively afterward, and the complete 92-test serial suite remained green.

Static and build checks

  • ./node_modules/.bin/tsc --noEmit --incremental false: passed.
  • payload generate:types: passed; src/payload-types.ts was byte-for-byte unchanged.
  • git diff --check: passed.
  • Task 18 changed-file Prettier check: passed.
  • Production webpack build against the migrated database: next build --webpack: passed and generated all expected application, Payload, preview, and sitemap routes.
  • Production-safe sitemap postbuild with NEXT_PUBLIC_SERVER_URL=https://srv1.bayerischer-mittelstandspreis.de: passed. Generated robots.txt and sitemap.xml contain only the canonical HTTPS origin.
  • Local generated and dynamic sitemap endpoints returned 200; /, the representative article, event, and winner URLs were present, no localhost or placeholder origin was present, and the unpublished Task 18 fixture was absent.

Migration verification

Initial status on the copied current database was 5 recorded migrations and 18 pending migrations. The isolated upgrade completed all pending migrations and ended with all 23 repository migrations recorded. PRAGMA integrity_check returned ok.

Every migration introduced by Tasks 117 was additionally verified through its own copied-database down/up cycle, with integrity checks after both directions:

  • 20260731_143000_remove_press_record_fallbacks
  • 20260731_160000_focused_payload_cleanup
  • 20260731_170000_netzwerk_greeting_video
  • 20260731_180000_press_contact_image
  • 20260731_190000_responsive_sponsor_hierarchy
  • 20260731_200000_home_phase_headline_line_break

All six targeted down/up cycles passed. The real content.db was never used as a migration target.

Browser verification

The production build was served locally against the isolated migrated database and the copied local media directory. Anonymous and authenticated preview checks used separate browser state.

Route and viewport matrix

The following routes were checked at approximately 1440, 1024, 768, and an exact 390 CSS pixels:

  • /
  • /teilnahme
  • /der-bmp
  • /netzwerk
  • /presse
  • /presse/events/nominierten-auswahl-2026
  • /presse/blog/goldene-bavaria
  • /preistraeger/agrarquant-gmbh

All 32 combinations rendered their expected CMS-owned heading and substantive main content with zero broken images. There was no page-level horizontal overflow except for the pre-existing event-detail issue below.

Specific checks also passed:

  • Homepage phase heading rendered the CMS newline as two lines.
  • Shared #bewerben section computed to rgb(36, 54, 106) (#24366A).
  • /teilnahme timeline advanced from 01 / 04 through 04 / 04; all four desktop/tablet steps were reachable, the 1024px section was 667px tall, and the next-section gap was 0. At 390px all four mobile headings rendered in document order, controls were hidden, and the next-section gap was 0.
  • Eligibility groups and the dates transition remained in the intended mobile scan order.
  • /der-bmp relevance layout was split on desktop; all three facts were centered and the image caption had a visible dark controlled background.
  • /netzwerk rendered tier bands with current counts 2 / 2 / 8 in authoritative order. With no Netzwerk video selected, no video action rendered.
  • /presse rendered the safe copy-only contact layout with no contact image selected.

Anonymous public versus authenticated preview

An isolated draft press article was created with slug task18-preview-fixture.

  • Anonymous direct browsing returned the 404 page and exposed neither the fixture title nor body.
  • After authenticating an isolated Payload user and entering through /next/preview, the same path rendered the draft title.
  • Publication and relationship integration tests independently prove this boundary for pages, winners, jury members, partners, events, and posts.

Read-only production smoke

No production login or write was performed. Browser and HTTP checks produced:

Production route Result
/ 200, expected main content, no broken images
/teilnahme 200, expected main content, no broken images
/der-bmp 200, expected main content, no broken images
/netzwerk 200, expected main content, no broken images
/presse 200, expected main content, no broken images
/presse/blog/goldene-bavaria 200, expected article detail
/presse/events/nominierten-auswahl-2026 404 before rollout
/preistraeger/agrarquant-gmbh 404 before rollout
/sitemap.xml 200
/pages-sitemap.xml 200
/posts-sitemap.xml 200
/robots.txt 200

The read-only VPS status script confirmed deployed revision 740e302c58f8, which is exactly the parent of Task 1. Further container/status output requires interactive server sudo and was not attempted.

The current production sitemap is therefore expectedly stale: it still emits /startseite, emits three /posts/<slug> URLs that each return 404, and has no event or winner detail entries. The corrected local sitemap cannot be judged live until the verified commit sequence is deployed.

Known tooling and pre-existing limitations

  • Repo-wide ESLint does not reach file evaluation because the current flat configuration throws Cannot redefine plugin "@typescript-eslint".
  • A rollout-wide Prettier audit reports 41 already-committed Task 117 files as nonconforming. Task 18's changed files pass Prettier; bulk reformatting was intentionally excluded from this release-verification commit.
  • The installed global pnpm is 11.9.0, while this repo requires pnpm ^9 or ^10. pnpm vps:status is blocked by the engine check; invoking the read-only script directly reached production and confirmed the revision.
  • The in-app browser enforces a 480px minimum CSS viewport. The exact 390px matrix was completed through the installed Chrome browser surface instead.
  • In-app navigation to local XML endpoints was blocked by the browser client; read-only HTTP checks verified all four sitemap/robots endpoints instead.
  • The representative event detail overflows horizontally at exactly 768px: the pre-existing EventDetail.tsx layout combines 80px side padding, a 64px gap, and a fixed 400px sidebar. Tasks 117 did not change this component, so Task 18 did not expand scope to redesign it. The same route has no overflow at 390, 1024, or 1440px.

Required production procedure and blocked gates

These actions are intentionally not performed by Task 18. They require explicit production-write coordination and a supported pnpm ^9 or ^10 runtime.

  1. Obtain explicit production-write authorization and identify the exact commit to deploy.

  2. Create the documented server-side SQLite backup:

    pnpm vps:backup-db
    
  3. Deploy the committed schema-changing rollout with migrations enabled:

    RUN_MIGRATIONS=1 pnpm deploy:vps
    

    Per docs/vps-deployment.md, this mode also creates a pre-migration database copy before pnpm payload migrate runs in the one-off app container.

  4. Confirm the deployed revision, container health, database/media state, and logs:

    pnpm vps:status
    
  5. Obtain the client-supplied Netzwerk video, upload/select it through Payload on the Netzwerk page, and verify that changing it does not affect the homepage video. No video asset was supplied in this task.

  6. Obtain the approved press-contact image, upload/select it with useful alt text through Payload on the Presse page, and verify the two-column desktop and stacked mobile layouts. No image asset was supplied in this task.

  7. Identify approved disposable production records before testing Unpublish and Republish. Record IDs and _status, verify anonymous list/detail removal, verify authenticated preview visibility, republish, and confirm restoration. No disposable record was approved in this task.

  8. Re-run the production route, sitemap, robots, media, responsive, and publication smoke matrix after deployment. In particular, every URL emitted by the corrected sitemap must return 200.

Blocked gates at handoff are therefore: client Netzwerk video, client press image, approved production unpublish record(s), supported deployment tooling, interactive server privileges where required, and explicit production-write authorization.