Andrea redesign: Step 7, cutover substeps 5–8¶
Justin authorized merge and production cutover on September 27, 2026, after reviewing the production-image rehearsal. The old preparation handoff remains the source for the original backup and rollback image IDs.
This is a completed release record, not a procedure to rerun. The one-time cutover, configuration-transform and collection-relabel helpers have been removed from the active tree. They remain in Git at the exact deployed release. Use the normal deployment runbook for later releases and the redesign story for the narrative overview.
Release boundary¶
Deploy only the portfolio and storefront. Keep the existing Medusa image,
PostgreSQL, Redis, Garage, credentials, media URLs, accounts, carts and volumes.
No migration, bootstrap, reseed, payment processing, account enablement or
legacy-bookmark compatibility is part of this cutover. The conservative
all-apps plan is intentionally narrowed to avoid rebuilding the backend for
maintenance-script-only changes.
The already configured store WhatsApp destination is reused for architecture
and landing contact links. Neither destination nor inquiry email is invented
or printed. The private environment changes only the apex storefront URL,
empty basePath, /guanza asset prefix and missing architecture contact setting.
Staging and privileged cutover¶
The two configuration-preparation scripts produce new files rather than editing the live settings. They reject an unexpected environment or apex configuration. Nginx changes preserve the existing Certbot TLS settings, security/privacy headers, robots policy, and API/Admin/media virtual hosts byte-for-byte outside the apex locations. Both frontend images must be built against the staged private environment and tagged with the exact merged commit before cutover.
For later releases, capture a private backup with capture-production-backup.sh --capture and verify
its off-server copy before switching applications. Avoid concurrent catalog
editing. The PostgreSQL restore check remains isolated; Garage full recovery
is not rehearsed. Never restore a database just to roll back frontend code.
The VPS deployment user requires interactive sudo for Nginx. Do not bypass
that requirement through Docker, weaken permissions, or ask for a password in
chat. The operator ran scripts/cutover-redesign.sh interactively in the exact
uploaded release directory with these arguments (historical command):
bash scripts/cutover-redesign.sh \
/opt/andreaweb/shared/redesign-production-COMMIT12.env \
/opt/andreaweb/shared/backups/EXACT_REFRESHED_BACKUP \
FULL_MERGED_COMMIT
The helper authenticates before live writes, checks the backup/current-release identity, validates Nginx before reload, replaces only the two prebuilt frontends, verifies loopback/public routes, and records each application's actual release. An error during the switch restores the old frontends, environment and Nginx; it does not touch commerce data. A brief interruption while replacing the two applications and reloading Nginx is possible.
cutover-redesign.sh is a one-time transition helper, not the ongoing
deployment entry point. Now that the route/environment contract is installed,
future releases use the normal scripts/deploy-ovh.sh plan / apply workflow.
Do not rerun this helper with the pre-cutover backup or old configuration. It
has now been removed from the active tree; Git history retains the cutover
procedure. Keep the private rollback artifacts separately.
For current read-only verification, run node scripts/check-release.mjs --production and
check product images, guest-cart/language continuity and contact redirects in
a browser. Do not send real inquiries or place an order as a smoke test.
Separate collection maintenance¶
apps/backend/src/scripts/relabel-origenes.ts was an explicit Medusa-module
maintenance operation, not a migration or startup action. It changes only the
existing guanza collection's title to Orígenes, rejects unexpected titles,
and verifies that the ID, handle and product assignments stayed the same.
It did not create a duplicate collection. It ran once using the existing backend
image with the reviewed script mounted read-only for medusa exec, preserving
the normal production configuration without starting another backend server.
It is retired now that the title-only operation is complete.
Andrea should select Orígenes in Medusa's Collection field for these pieces,
or Piezas Intervenidas for the separate artist-reimagined collection. The internal
guanza handle remains an intentional compatibility/data contract, not a
collection Andrea needs to recreate. Clearly marked samples remain removable
through Admin.
Dependency triage / remaining risk¶
The full portfolio audit exposed react-server-dom-webpack 19.2.6, which was
incorrectly outside the earlier --omit=dev audit's coverage: the portfolio
ships its development dependencies and uses the RSC runtime. Before promotion,
React, React DOM and the matching server-components package are patched together
to 19.2.8 for GHSA-wx67-qw84-cm4g.
An --omit=dev result alone is not an audit of this portfolio runtime image.
Other bundled toolchain findings remain separately recorded; do not call the
portfolio's full dependency tree clean. The deployment uses vinext start,
not the development server, and runs on Linux with no public build/upload tool.
The backend still reports 69 high and 11 moderate production audit findings,
propagated through seven underlying dependency groups. Its package/lockfile
and running image are unchanged by this frontend cutover. Inspection found
Admin authentication registered before the upload-specific Multer middleware;
an unauthenticated POST to the live /admin/uploads returned 401. The examined
Medusa UUID request-ID path uses v4, not the affected buffer-taking v3/v5/v6
functions. These limited checks do not prove all findings unreachable.
Multer, lodash, qs, CSV import, Ajv and logging dependency findings need a separate patch/test pass; no crafted exploit requests were sent to production. The frontend redesign neither exposes account controls nor adds backend upload routes. Retaining the old backend is risk containment, not a security waiver or a claim that the entire stack/OS images are security-cleared. See the original release-preparation handoff and upstream advisories for the audit details.
Execution status¶
Live and verified on September 27, 2026. The exact application
release is 0f56ca8156ef96068bd0ded5fa5b833c9e4c742f, uploaded to
/opt/andreaweb/releases/0f56ca8156ef. Later documentation-only commits do not
change these built artifacts or the deployment identity.
- Portfolio image:
sha256:719c1ec8f5a5a59c7218f6ff0d65bacf8524aa99009a1507ace3bca05217d1a5. - Storefront image:
sha256:2f8b72aaa5abe64b3e492cc13e1d4ee51e416d9b744875bebb258d4d0bd6dee9. - Both images are tagged
0f56ca8156ef. The portfolio image's RSC package was checked directly and is 19.2.8; storefront runtime/full-install audits are zero. - Private candidate environment:
/opt/andreaweb/shared/redesign-production-0f56ca8156ef.env(0600). - Staged, reviewed Nginx site:
/opt/andreaweb/shared/redesign-nginx-0f56ca8156ef.conf. - Refreshed private backup:
/opt/andreaweb/shared/backups/redesign-20260927T192130Z-ucS3UQ. - Verified off-server copy:
/home/justin/.local/state/andreaweb/backups/redesign-20260927T192130Z-ucS3UQ.
Checks passed: 22 portfolio tests, 41 storefront tests, three cutover transformation tests, lint (12 existing portfolio image warnings), backend maintenance-script build, formatter, and shell syntax. The refreshed PostgreSQL dump restored successfully with 15 products in an isolated temporary container; checksums passed on the VPS and the off-server copy. No database was restored over live data. Garage full restore remains untested.
The exact staged images were started temporarily on loopback-only ports 3300
and 3400 with the real production configuration/catalog. Read-only checks passed
for /, English architecture, Guanza, Orígenes, English Piezas Intervenidas, cart and
a real image from media.andreazambrano.co; no local-only media URLs appeared.
Those temporary containers were removed. All six original production services
remained healthy. No guest cart, account, order or inventory was changed by
these checks. The backend image/lockfile has no change from the old release.
The portfolio full audit remains at 20 findings (14 high, five moderate, one
low), versus zero with --omit=dev; its image includes tooling classified as
development dependencies, so record the full result too. The directly relevant
RSC finding was patched before staging. Broader toolchain and the unchanged
backend's 80 findings remain follow-up work, not a clean security attestation.
Completed operator action: Justin ran the following bounded switch in his own terminal, supplying interactive sudo there (never in chat). Nginx syntax validation and the helper's cutover verification succeeded:
ssh -t ovh "cd /opt/andreaweb/releases/0f56ca8156ef && bash scripts/cutover-redesign.sh /opt/andreaweb/shared/redesign-production-0f56ca8156ef.env /opt/andreaweb/shared/backups/redesign-20260927T192130Z-ucS3UQ 0f56ca8156ef96068bd0ded5fa5b833c9e4c742f"
The final checks confirmed:
/opt/andreaweb/currentresolves to/opt/andreaweb/releases/0f56ca8156ef. Web/storefront release markers contain the full deployed commit; Medusa's marker remainsaebdc81d8bda. Both frontend image IDs match the artifacts above; the existing Medusa image remainssha256:d2cd9165517cb098f63ca30cdc9500f05094a4b25efde4aef1439a916bc58b4b.- All six services are healthy. The mounted persistent volumes remain
andreaweb_postgres_data,andreaweb_redis_data,andreaweb_garage_dataandandreaweb_garage_meta. Service uptime changed during the operator's session; do not interpret frontend-only scope as proof that no other service restarted. - The title-only Medusa script ran successfully in a disposable execution
container using the existing backend image and read-only script mount.
Collection
pcol_01M20YRTCSXB92CAD32JJGD9WDis now Orígenes; its handle remainsguanza, and the script verified identical product assignments. Piezas Intervenidas remains a separate existing collection. The Store API lists 10 published products, including the four clearly marked samples; the earlier backup restore count of 15 includes the database's broader product records. check-redesign-release.mjs --productionpassed for both languages, landing, architecture, Guanza, both collections, carts, built assets, social images, API ownership and the missing-collection 404.- An isolated Chromium session loaded the live landing, architecture and real product/media URLs successfully. Desktop (1440 × 900) and phone-sized (390 × 844) landing screenshots were reviewed, with no horizontal overflow on the phone-sized page. The live Bowl page shows Orígenes, its actual media and purchase controls. No browser page errors were observed.
- A sample was added to a disposable guest cart. Switching Spanish to English preserved the same cart cookie, quantity and COP 80,000 price; item removal returned the cart to empty. Ordinary cart-link navigation was verified after initial test-selector/time-out issues. No account, order or payment was created.
- Same-origin contact and cart-inquiry POST checks returned 303 to
wa.me; redirects were not followed, and no message was sent. The cart email link rendered the existing configured destination and summary; no email was sent.
Cutover substeps 5–8 are complete. Final Andrea artwork/content approval, real-device/touch review and the separately recorded dependency remediation remain follow-up work; they are not implied by these bounded deployment checks.