@@ -463,11 +463,20 @@ def build_export_payload(queryset):
463463 [_serialize_category (c ) for c in all_categories ]
464464 )
465465
466+ # Export all prefill sources so standalone sources and config changes
467+ # propagate independently of whether any form field referencing them was
468+ # included in the push/pull.
469+ prefill_sources_payload = [
470+ _serialize_prefill_source (ps )
471+ for ps in PrefillSource .objects .order_by ("order" , "name" )
472+ ]
473+
466474 return {
467475 "schema_version" : SYNC_SCHEMA_VERSION ,
468476 "exported_at" : django_tz .now ().isoformat (),
469477 "form_count" : qs .count (),
470478 "categories" : categories_payload ,
479+ "prefill_sources" : prefill_sources_payload ,
471480 "forms" : [serialize_form (f ) for f in qs ],
472481 }
473482
@@ -791,12 +800,15 @@ def import_payload(payload, conflict="update"):
791800 """
792801 category_cache = {}
793802
794- # ── 1. Upsert all categories from the top-level list first ────────────────
795- top_level_cats = payload .get ("categories" , [])
796- for cat_data in _topo_sort_categories (top_level_cats ):
803+ # ── 1. Upsert all categories (parents before children) ────────────────────
804+ for cat_data in _topo_sort_categories (payload .get ("categories" , [])):
797805 _get_or_create_category (cat_data , category_cache )
798806
799- # ── 2. Import forms (per-form category data is now a no-op cache hit) ─────
807+ # ── 2. Upsert all prefill sources ─────────────────────────────────────────
808+ for ps_data in payload .get ("prefill_sources" , []):
809+ _get_or_create_prefill_source (ps_data )
810+
811+ # ── 3. Import forms (category / prefill-source lookups are now cache hits) ─
800812 results = []
801813 for form_data in payload .get ("forms" , []):
802814 result = import_form (
0 commit comments