            import pyarrow as pa
            import pyarrow.parquet as pq
            from io import StringIO
            rows=list(csv.DictReader(StringIO(data['csv'])))
            schema=pa.schema([pa.field('id',pa.string()),pa.field('units',pa.int64()),pa.field('active',pa.bool_()),pa.field('observed_at',pa.timestamp('us',tz='UTC'))])
            parsed=[{'id':r['id'],'units':int(r['units']) if r['units'] else None,'active':{'true':True,'false':False,'':None}[r['active']],'observed_at':datetime.fromisoformat(r['observed_at'].replace('Z','+00:00')).astimezone(timezone.utc) if r['observed_at'] else None} for r in rows]
            table=pa.Table.from_pylist(parsed,schema=schema);pq.write_table(table,folder/'typed.parquet');artifacts.append('typed.parquet');back=pq.read_table(folder/'typed.parquet');values=back.to_pylist()
            check('Parquet原生schema回读一致',back.schema==schema);check('空整数没有变浮点NaN',values[1]['units'] is None and values[2]['units']==0);check('false与缺失不同',values[0]['active'] is False and values[2]['active'] is None);check('带时区时间统一UTC且瞬间相等',values[0]['observed_at']==values[1]['observed_at']);result={'schema':str(back.schema),'rows':values}
