$category_names Noms des catégories de la boutique. * @param bool $display_live Affichage AGEC **réellement rendu** sur ≥1 produit publié * (vraie couverture, pas un booléen de réglage). * @param int $at_risk Produits avec allégation à risque (GreenwashingScan). * @return array Enregistrement persisté. */ public static function record( array $category_names, bool $display_live, int $at_risk = 0 ): array { $eval = Qualification::evaluate( $category_names, $display_live, $at_risk ); $fs = function_exists( 'agec_fs' ) ? agec_fs() : null; $consent = $fs && method_exists( $fs, 'is_tracking_allowed' ) ? (bool) $fs->is_tracking_allowed() : false; $previous = (array) get_option( Meta::OPTION_NSM, array() ); $record = array( 'pqas' => $eval['pqas'], 'qualified' => $eval['qualified'], 'filieres' => $eval['filieres'], 'at_risk' => $eval['at_risk'], 'display_live' => $eval['display_live'], 'consent' => $consent, 'updated_at' => gmdate( 'c' ), 'first_seen' => isset( $previous['first_seen'] ) && is_string( $previous['first_seen'] ) ? $previous['first_seen'] : gmdate( 'c' ), ); // Non autoloadée : lue ponctuellement (reporting), pas à chaque requête. update_option( Meta::OPTION_NSM, $record, false ); /** * Signal NSM : la boutique a terminé l'onboarding (PQAS mesurable). * * Couture de transport analytics (opt-in) sans toucher au cœur : un consommateur peut * lire `$record['consent']` avant toute transmission. Voir docs/adr/0007. * * @param array $record Qualification persistée. */ do_action( 'agec_ready_shop_qualified', $record ); return $record; } }