totals, unresolved = {}, []
def expand(node, multiplier=1):
    qty = node.get('quantity')
    if qty is None:
        unresolved.append(node['id'])
        return
    quantity = multiplier * qty
    if node.get('components'):
        for child in node['components']:
            expand(child, quantity)
    else:
        totals[node['id']] = totals.get(node['id'], 0) + quantity
expand(output['assembly'])
result = {'expanded': totals, 'missing_quantity': unresolved}
check('程序展开螺丝总数为8', totals.get('SCREW-M3') == 8)
check('缺失数量留待核对，不补成1', 'PAD-02' in unresolved and 'PAD-02' not in totals)
save_csv(folder / 'expanded-bom.csv', [{'id': key, 'quantity': value} for key, value in totals.items()])
