abdev/module-ager-sync (0.1.0)
Installation
{
"repositories": [{
"type": "composer",
"url": " "
}
]
}composer require abdev/module-ager-sync:0.1.0About this package
Abdev_AgerSync
Magento 2 integration scaffold for the AGER dropshipping XML/YML feed.
Confirmed AGER model
The feed was investigated against the supplied 152 MB catalog (~30k offers, ~200 categories):
group_id/ repeatedsku= product model in one color -> Magento configurable parent.offer id= unique size variation -> Magento simple child.Розмірis the canonical configurable dimension.- The only fields observed to vary inside one
group_idare size systems:РозмірМеждународный размерРазмер женских джинсовРазмер женской обувиРазмер женской одеждыРазмер мужских шортРазмер мужской обувиРазмер мужской одеждыРазмеры мужских джинсовРазмеры мужских рубашек
categoryId, description, picture set, price, oldprice and color were observed to be shared across variants in the same group.quantity_in_stockandavailableare variant-level inventory signals.
Current phase (0.1.0)
This module has a guarded Phase 2 catalog writer. Catalog writes are disabled by default and the current feed is plan-only until the operator explicitly enables the safety setting. It already provides:
- top-level Abdev Magento Admin menu item with branded icon;
- AGER Sync dashboard and System Configuration section;
- configurable feed URL, User-Agent and timeout;
- configurable cron (disabled by default);
- global debug mode + CLI
--debugoverride; - dedicated
var/log/abdev_ager_sync.log; - structured debug markers such as
[AGER:FEED_DOWNLOAD_START],[AGER:INSPECT_START], etc.; - streaming cURL download to
var/abdev/ager/ager.xml(no 152 MB response in PHP memory); XMLReaderstreaming parser;- per-offer normalization;
- streaming grouping by
group_idwith a non-contiguous-group safety guard; - group invariant validation (shared description/images/category/price/color, unique sizes/offers);
- declarative tracking tables for runs, parent mapping, variant mapping, category mapping;
- guarded configurable-parent/simple-child writer with
ager_group_id/ager_offer_ididentity; - configurable
ager_sizelinks, MSI stock, parent media, pricing, and complete-run missing reconciliation; - sync lock to prevent parallel jobs;
- data patch for AGER external IDs and size-system attributes;
- explicit
CatalogWriterInterfaceboundary for catalog persistence; abdev:ager:syncplan mode plus a full-feed, write-gated orchestration path.- live CLI synchronization progress with named stages, progress counts, remaining items, current group and errors;
- write-run tracking of invalid parent/variant groups for restart-safe retry.
Install
Copy the module to:
app/code/Abdev/AgerSync
Then:
bin/magento module:enable Abdev_AgerSync
bin/magento setup:upgrade
bin/magento cache:flush
In production mode also deploy static content as required by your deployment process.
Admin
- Left menu: Abdev -> AGER Sync
- Configuration: Stores -> Configuration -> Abdev -> AGER Sync
Cron is disabled by default.
CLI
Inspect configured remote feed:
bin/magento abdev:ager:feed:inspect
Inspect an already downloaded feed:
bin/magento abdev:ager:feed:inspect --file=/path/to/ager.xml
Fast development sample:
bin/magento abdev:ager:feed:inspect --file=/path/to/ager.xml --limit=500 --debug
Build a tracked sync plan:
bin/magento abdev:ager:sync --file=/path/to/ager.xml --debug
Force a read-only run, including when catalog writes are enabled:
bin/magento abdev:ager:sync --file=/path/to/ager.xml --dry-run --limit=500
During sync the CLI shows the current stage and a live progress bar. In decorated terminals it updates in place; in logs/piped output it emits throttled stage updates.
Show recent runs:
bin/magento abdev:ager:sync:status
Show runtime/config prerequisites:
bin/magento abdev:ager:debug:config
Debug philosophy
Debug is intentionally noisy only when enabled. Enable it either globally in Admin or temporarily for a CLI process with --debug.
The module logs structured probe markers to:
var/log/abdev_ager_sync.log
Full descriptions/raw XML are never written by probes. Payload sampling is separately disabled by default.
Phase 2 catalog writer design
CatalogWriterInterface is the write boundary. The implementation is decomposed into:
CatalogWriter
|- AttributeOptionResolver
|- CategorySynchronizer
|- ConfigurableParentSynchronizer
|- SimpleVariantSynchronizer
|- ConfigurableLinkSynchronizer
|- AttributeSetSynchronizer
|- InventorySync (MSI)
|- MediaSynchronizer
|- PricingMapper
|- MissingEntityReconciler
Recommended behavior:
- Parent SKU:
AGER-{group_id}(or store-specific configurable prefix policy). - Child SKU:
AGER-{offer_id}. - External identity is always
ager_group_id/ager_offer_id, never size text. - Configurable dimension:
ager_sizeonly. - Other size systems remain child-level metadata; do not add them as configurable dimensions.
- Parent owns name, description, category, images, color, brand, common params, price/oldprice.
- Child owns offer id, size-system values, qty, availability; child visibility = Not Visible Individually.
- Use SHA-256 normalized hashes from the tracking tables to skip unchanged parents/variants.
- After a successful complete run only, reconcile rows whose
last_seen_run_idis older according to Missing Product Policy. - Never disable products after a partial/failed feed run.
- Media should be imported once on the parent because the current feed repeats the same image set on all size variants.
- The writer must be idempotent and safe to restart after a failed batch.
Notes
The AGER server returned HTTP 403 for generic wget/curl in testing. The downloader therefore sends a browser-like User-Agent, Accept headers, Ukrainian Accept-Language and Referer: https://ager.ua/, all without loading the response body into memory.
AGER attribute filtering and migration
AGER behavior is centralized in Service/Mapping/AttributeMap::definitions(). Categorical parent fields and all size-system metadata are select/int candidates with layered-navigation flags; ager_size remains the only configurable super attribute. ager_group_id and ager_offer_id remain text identities. ager_composition remains text because the inspected catalog contains 311 compound percentage/material values.
Existing varchar data is migrated explicitly, never by changing only frontend_input:
bin/magento ager:attributes:migrate --dry-run
bin/magento ager:attributes:migrate --attribute=ager_brand --batch-size=500
Dry-run modifies no metadata, options, product values, or EAV rows. The real command is batch-based and restart-safe: it creates/reuses normalized options, writes int values, verifies them, then removes source varchar rows. Back up affected EAV tables first. It does not start normal sync, reindex, or cache cleanup; after approved completion run bin/magento indexer:reindex and bin/magento cache:clean.
Dependencies
Dependencies
| ID | Version |
|---|---|
| abdev/module-backend | ^1.0 |
| magento/framework | >=103.0 |
| magento/module-backend | >=102.0 |
| magento/module-catalog | >=104.0 |
| magento/module-config | >=101.0 |
| magento/module-configurable-product | >=100.4 |
| magento/module-cron | >=100.4 |
| magento/module-eav | >=102.1 |
| magento/module-inventory | >=1.2 |
| magento/module-inventory-api | >=1.2 |
| php | ^8.1 || ^8.2 || ^8.3 || ^8.4 || ^8.5 |