Skip to content

Catalogus van productie naar staging

Eefje beheert de catalogus sinds 2026-09-04 op productie. Wat ze daar verandert, komt niet vanzelf op staging. Met scripts/catalogus-prod-naar-staging.sh zet je de catalogus van productie af en toe op staging, zodat je daar met dezelfde producten, kleuren, maten, bedrukvlakken en prijzen test.

Alleen Ivar voert dit uit, vanaf zijn Mac. Het script schrijft niets naar productie: daar leest het alleen.

Wat gaat mee en wat niet

Gaat mee Gaat niet mee
Producten, varianten, kleuren, kleurgroepen, maten, kleurfoto's, tweekleur-combinaties, bedrukvlakken Bestellingen, klanten, accounts, adressen
Categorieën, merken Ontwerpen en uploads van klanten (designs/ in de bucket)
Prijsregels, staffels, aanbiedingen, kortingscodes, decoratiemethodes SiteSettings en pagina's (alleen met --met-instellingen)
Lettertypes, tekstkleuren, sjablonen, clipart
Personalisatiesjablonen en flock- en garenkleuren (via dumpdata/loaddata, alleen bij --clear of --wis-testgegevens) Personalisatie bij een merge zonder --clear
Foto's in products/, categories/, brands/, variants/, fonts/, clipart/, templates/ Wat alleen op staging staat, blijft bij een merge staan; met --clear gaat de catalogus van staging weg

De lijst met modellen staat in ALLOWED_MODELS in backend/apps/products/management/commands/_base.py; zie ook de seed-data-handleiding.

SiteSettings bevat de schakelaars, verzendkosten en de standaardbedrukmethode. Op staging staan functies vaak aan om te testen. Daarom laat het script SiteSettings en pagina's standaard staan. Wil je ze ook gelijktrekken, gebruik dan --met-instellingen.

Eenmalig: rclone voor de foto's

De foto's staan in DigitalOcean Spaces (ams3): freeze-production-media en freeze-staging-media, elk met de map media/. Het script kopieert ze met rclone vanaf je Mac. Daarvoor heb je twee remotes nodig:

  • prod-media: een Spaces-sleutel die freeze-production-media mag lezen. Maak er liever een nieuwe, alleen-lezen sleutel voor dan de sleutel van de webshop te hergebruiken.
  • staging-media: een Spaces-sleutel die freeze-staging-media mag lezen en schrijven.
brew install rclone
rclone config create prod-media s3 provider=DigitalOcean endpoint=ams3.digitaloceanspaces.com env_auth=false
rclone config create staging-media s3 provider=DigitalOcean endpoint=ams3.digitaloceanspaces.com env_auth=false

Vul daarna de sleutels in met rclone config (kies de remote, dan Edit), of zet ze per run als omgevingsvariabelen (RCLONE_CONFIG_PROD_MEDIA_ACCESS_KEY_ID, RCLONE_CONFIG_PROD_MEDIA_SECRET_ACCESS_KEY, en hetzelfde voor STAGING_MEDIA), bijvoorbeeld uit 1Password met op run. Controleer:

rclone lsf --dirs-only prod-media:freeze-production-media/media/
rclone lsf --dirs-only staging-media:freeze-staging-media/media/

Met sleutels per bucket werkt rclone lsd prod-media: (alle buckets) niet; noem altijd de bucket.

Je hebt ook de SSH-aliassen freeze-prod en freeze-staging nodig (gebruiker deploy).

Uitvoeren

Zet eerst de paden naar de media, in hetzelfde terminalvenster:

export CATALOGUS_MEDIA_BRON=prod-media:freeze-production-media/media CATALOGUS_MEDIA_DOEL=staging-media:freeze-staging-media/media

1. Proefdraaien

Exporteert op productie, toont hoeveel records er meegaan en laat rclone zien welke foto's het zou kopiëren. Op staging verandert niets.

scripts/catalogus-prod-naar-staging.sh --dry-run

2. Proefimport

Staging en productie maken sinds de migratie allebei zelf records aan. Daardoor staan dezelfde dingen vaak onder verschillende ID's: het testproduct SYNTHETICS-TEST, prijsstaffels, bedrukvlakken. Een merge op ID botst daarop (zo gezien op 2026-11-06: 2 producten, 4 bedrukvlakken, 1 decoratiemethode en 107 prijsstaffels). Vervang de catalogus daarom in zijn geheel, en doe eerst een proef. Die voert het wissen en de import echt uit op staging, in een transactie die altijd wordt teruggedraaid:

scripts/catalogus-prod-naar-staging.sh --wis-testgegevens --proef-import

Eindigt hij met "Proefimport geslaagd en teruggedraaid", dan gaat de echte run ook goed.

3. Echt draaien

scripts/catalogus-prod-naar-staging.sh --wis-testgegevens

Het script vraagt om bevestiging en doet dan:

  1. Export op productie: export_seed_data --skip-images --skip site_settings --skip pages en dumpdata van de personalisatiesjablonen en -kleuren (die kent export_seed_data niet), in de backend-container, als tar naar je Mac. Alleen lezen.
  2. Foto's: rclone copy per catalogusmap, met --s3-acl public-read, want staging toont de foto's rechtstreeks uit de bucket. copy, geen sync: wat alleen op staging staat, blijft staan.
  3. Backup op staging: backup_database --no-notifications. Mislukt die, dan stopt het script vóór de import. Met --geen-backup sla je hem over.
  4. Import op staging. Met --clear of --wis-testgegevens draait vervang.py (zit in het script) in één transactie: eerst de testgegevens weg (alleen met --wis-testgegevens), dan import_seed_data --clear, dan het aantal producten tellen. Klopt dat niet, of brak Postgres de transactie af, dan wordt alles teruggedraaid, ook het wissen. Zonder die opties: import_seed_data in mode merge, waarbij een record met hetzelfde ID wordt bijgewerkt en een nieuw record aangemaakt.
  5. QA-testgegevens: seed_staging_data, zodat de @qa-test.nl-gebruikers en qa--producten er weer zijn.

Opties

Optie Wat het doet
--dry-run Exporteren en tonen, rclone met --dry-run, geen backup en geen import
--zonder-media Alleen de database, geen foto's (dan zijn de media-paden niet nodig)
--met-instellingen Ook SiteSettings en pagina's van productie overnemen
--clear De catalogus op staging vervangen in plaats van samenvoegen; lukt niet zolang er testbestellingen zijn
--wis-testgegevens Als --clear, maar eerst alle bestellingen (met betalingen en facturen), offertes, Informer-boekingen en personalisatiesjablonen op staging weg. Via de catalogus verdwijnen ook opgeslagen ontwerpen en winkelwagens
--proef-import Met --clear of --wis-testgegevens: wissen en importeren in een transactie die altijd wordt teruggedraaid. Geen foto's, backup of seed
--geen-backup Geen backup op staging vooraf
--ja Niet om bevestiging vragen

PROD_SSH en STAGING_SSH overschrijven de SSH-aliassen. Het script weigert een staging-alias met prod erin, en een media-doel met production of prod-media erin.

Controleren

Op staging.freezedesign.nl:

  • Een paar producten die Eefje onlangs op productie heeft aangepast, zien er op staging hetzelfde uit (naam, prijs, kleuren, maten)
  • De productfoto's laden
  • De Designer opent op een product en toont de bedrukvlakken
  • De QA-testproducten (qa-…) staan er nog

Als de import fouten geeft

import_seed_data vangt fouten per record op en meldt ze alleen als waarschuwing (⚠️ Error importing record: …). Op Postgres breekt één fout de hele transactie af: dan is er niets opgeslagen, terwijl de import toch "klaar" meldt. Het script let daarom op die waarschuwingen en stopt met een foutmelding.

De oorzaak is bijna altijd een record dat op staging en productie een andere ID heeft maar dezelfde unieke waarde (slug, SKU, methode + oppervlak). Daarom is --wis-testgegevens de gewone manier van draaien, met eerst --proef-import.

  • Merge (zonder --clear): de transactie is teruggedraaid, de catalogus op staging is ongewijzigd. Draai opnieuw met --wis-testgegevens.
  • Met --clear of --wis-testgegevens: wissen en importeren zitten in één transactie (vervang.py). Mislukt de import, dan is ook het wissen teruggedraaid. De backup van stap 3 is dan niet nodig. Hij staat er wel, voor het geval dat (zie Disaster Recovery, Restore Procedure).

--clear zonder --wis-testgegevens mislukt zolang er op staging bestellingen of offertes naar producten verwijzen (OrderItem.product, OrderGroup.product, QuoteItem.product zijn PROTECT), of een personalisatiesjabloon naar een lettertype (PersonalizationTemplate.font). Ook dan wordt alles teruggedraaid.

Hoe vaak

Wanneer je op staging iets test dat van de echte catalogus afhangt, of als Eefje grote wijzigingen op productie heeft gedaan. Niet automatisch op een schema: een run kan testgegevens op staging overschrijven, en daar wil je bij zijn.