From e575c32c02ea6c058f5e23f7333beec05dabba56 Mon Sep 17 00:00:00 2001 From: julianxcarter Date: Wed, 15 Dec 2021 09:37:46 -0500 Subject: [PATCH 1/3] Complex Participation extension added --- docs/CSV_Templates.xlsx | Bin 1226694 -> 1226824 bytes docs/ctc-adverse-event.csv | 8 +-- src/extractors/CSVCTCAdverseEventExtractor.js | 14 ++++ ...-event-participant-function-value-set.json | 67 ++++++++++++++++++ src/templates/CTCAdverseEventTemplate.js | 39 +++++++++- .../CSVCTCAdverseEventextractor.test.js | 10 +++ .../csv-ctc-adverse-event-bundle.json | 25 +++++++ ...csv-ctc-adverse-event-module-response.json | 4 +- .../ctc-adverse-event-information.csv | 8 +-- test/templates/ctcAdverseEvent.test.js | 22 +++++- .../maximal-ctc-adverse-event-resource.json | 25 +++++++ 11 files changed, 210 insertions(+), 12 deletions(-) create mode 100644 src/helpers/valueSets/adverse-event-participant-function-value-set.json diff --git a/docs/CSV_Templates.xlsx b/docs/CSV_Templates.xlsx index 1d187b35898cb520001a0838f01dd6cfe74f42ad..48c205cd65a05ef41e0a989d89be9a2d5ecc0bc5 100755 GIT binary patch delta 36579 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

S)d`+J7p$mN&vEsq;L?KO*-n2grbAs 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 I0C9T$1HtHP%K!iX delta 30939 zcmd43c_3BW`#;_`mLUx?97PhP5)Fn5M|Gp36itRmDw(A+J6j1QrP^hOqLNC9WH{y{ zLXr+CG9EH#IOfA~hTq!fP`&T_zK8pJ-}mSJ{o`a0YprKJYdz2Fd9CN!_r4q4T|(Xc z>iZm6f%lx*UcOng#)W3h5}P$^mY0*Nr>nc;aaUKzwO-CniHDB5#%YQBTidgFzumt$ zXWqr#`hLsncUDI}uQ(@bF!yeYN=xFpUC$j@Q&wB%C{{S!>38~!W1LAQXX(9q?U~16(K%z1pT5UFA+bGjY#H9gUsDC< zMrnLDl-IampJBGkp|SausQs}g$8t+}vi+PhWcIo>M_js`z23Qe_yew5AMZ7LLS6UB z{>re&YkD0%T@GBhch#C%1dC65e1{L&)n>j}2M=iImwXq^JW>@JD%o+M_WPP6i83Wa z&w1*7+Z}x2xv(rlK^Qlcw$SLP)4}Sn)QCmj1T3QkDPcAzragljaBx$7m?medj z?IPJlG~LVZd;Ps#Ki(KCZ=Sc)&|Wd1#lJGT!8UcQ$9e1O;d3{Vf;FR6Gb2_U>@g3r zSXZ8~)caZZ!*Y*yrvT6B%(z7#mQ8HR-qhdWM^3*dp7{cPyWo+u|S#n}qa z`C3IKmfKvLwM5pN`MmQs_3?=ZZv7V+U-s`^nxbc2u*m!#zt@*$+x-qplD9Q6YIwXy zjPKdZ_4;6XD6O;2U7{&c{qeeW@2uSJl`+(W=FY$6?bx}-vEo9&(8&yj;G8z268>@F zxh-N;Y9QZYFSlE8PhJZySM?Lw?LfGfu%O`ZtRt(EC5KPwsRD{ z!|uV`GuKvLUsDu4<+7mS*5ubKFpu;AzjV?4mElo0lD0QNkfl*mE7M-UY^%YDrc`px zklnkkoX(9j(*+S z%U*AJ74Yb*#aF7zz@~C|XY++;f)Z|<^NPEVhlgrxEc$ZG)KVp?=;WhN%kcSIZ+>6$ z%qagv#HWas2yLM?*{#i|k3Bc>JuUR2)@{z*2an{pP<3jOSHCOiZ(WANZ3^5|BFT5K zU9O#9e|XC+UNh-WE0a6&z9Ng=N0Ue8g=ZhglNZl?Kecbq+Qv1=N>q*qK9Qk=LOfsc zdJ248wbC|U9fJDPea9FkWZniA67btPI|`uLLXJUpts<-4+%UKV+u=J#w{t3vsq za}PfIyA+Q~#O#w#Fq;2tiLK)|sT!wt+;x14C`GzX|J&p74@=0O%=+GclE>RzWVbCl z9JE=>UuM^BMe#1h11)y*s(F=NkI!2suDN5j+uS!LNpcnn0o@;}8r>@2uK)J+tcd3Q z@Wyq!k;pAD@9G{&xm z&$?x>jcc^pJf^Na8=CZ;#d~4-Zgcf3kIqLuv2V&IUtf3SV8I8Es1wz!sgLs(KG`dN zaCf22aC2UcXDMU+K>NoHNa$7f3$J<=Lhc-RoZF~UNpp>^;@h+vS+AJ2vX19|K>Y(Kfi@)o(Uf$QWymeuLW}5x?5y?oQz47~&Rj*a^z1E3#80RGzoGu@I&Dy$A zYk0YDXGsCP`rx3(F0V#+{==^aubnt!c&c8}PB3O|C3R@Cx$5DE_^98?%ifW$M#S~_ zTrntfKoUz{l$}E^!Ic%-9WAdC-rrnf@nDO#?_0v+J*Dq*B5SvgzN_1R{*BpJn-u>PAu6a3H z*BM%~cA+8G#Y4PpIe7v*MV6>5Y%(M}K3Unvv+_J|+=bA^3ks7>-BPR7-nSpH4oCe= z+baVtpS#OsiQJs24+JXHQscZ*h>f)yx?74XENjO>e#|Y+cTOr#9=> zYQ7vBsR?`rW`*)4ZKbpT1w^Z&6`uNzF5GSHndrz6)tUfp~+SS0h7(<{By6V z;rhMWJIh-R&!3p((VxeTTRO+hLU-2_qwyZA8$m;sVfAY2I^zxG*e$!y9Xk2eVTa{; zg}i0bcTT+8&A1B}lXV##Q&gBS+#p9{eoG}WYuQunuCXM0SKZ0MT32|&jS0t&vpNwH zV`4Je*>|Lj(lFfb8OxfKvnH@xbEt5ptRH=cHN|hJ&XZV~?2?N#$es%G(x^MU42V^4U8IC-;#TIt*xWV_1%6sW7TkiA)Glh z-0j)^ESxpmO-rmE{vOFHxSnzNe*UB6>KBqDj`SiG)h*1MEVqX8IAVME7qM|s|Gb9s zuE~YWH&)EYxwdi*pieUrcbLS(TC}1+mz}=R%KrqrgwRZX5#CSfF&=m!IgIbFda;)c z?+Rzt^`Nx{x=DSwnxgkUq?ij8eQobCEpizTteFd@Bt1sHAO4zr=4>O$tNeu|)zE!| z)wMCrOtX@vg=0hC?M8@?E62Z&F`Gsf9%Xm6xr+Md(%%t`an8wyCImf3o>v~u?5U;N zvl;%Uy~l*d9DPQ=+cCn)22;!p&dD(0LS8(1)W>GD`-^cyY_}Ngdsq9C>-9{-x`@N7 z)xI7Ztz5%o^XQRN#M0QNX6w8N_Ffk&whL3Puk%aDcx4$#!zc#e~|*E<>t`ny0NDr(XgjjcrFQU zFAgE*(g&YYGzk7%Sd5CHp%9je?2#n)2stZ{WyHt{H^ApfkYKNNF|lyJAcFzxNf3bs;~5jy>@FIGO=X{-+S~=x$A(@s zRQs_`S$fJ@XSRKTod{Q>dyAPp=ck&A6n+&@)@3k2=+J4*_4jIz?)vCS8kTiw*3lkj zv2IExw~sY+7QLz;Ya#n6;t5JQ>+L`17S5nM zH?vhb4y)of<7Yc#bd`ZFlxV-NsyBuXZL=K~?v&qcr$u_{FWM zWCbhOkGR5TatIS(I_Wkt-g?t@@Ex<1<~B0WdXq*A&z+b^Qhj(a_WhJ!{7t4c(D$B(>$JNJs*_#hqYru>&)~9ZIIit}#wYB||hW97!zjrL$Y~AbEG?4$*dvar+VE}sw{RrMIlDSCTV_b?=l^S(~GWf7S4J1%@|1 zdV?l=R{z7gCRKK9wGop}V!c}Hs3hn%rFy!{&Q#?=i16J_tSE2cZU;!mvfxA2sak5< zM@J2E9ghop&hT(L+ne<9)OF1f3AN8W`k4WdZ56rvBIyD1*BbizSF8_zK83Daw_K)~KEOzZwX&LX@H@bn|Pu`9=f8;(8+>&dS8L)#e z_XyUQo+`ce*iCDGm1dsKP0kXW>zCNIV@5C-oZjm+CZR^QPj!P{Fv0`ASQKbKttjMA zgx#SR!~pNT(LusTI(QDbLL>Jyge70S=Xc`v4FY|$11hGQJGn#A)2+X@^SHoU3MQ!B z&fr#KrgIs8AGb5MFxdf3)1CX=p`4k{9XuY~*0AKOa&B{M&Zw{!rb|uVY)Q4V=b(`3 z=34DMbEgM)d&j?cTEmtb+}8DLEDPi%-F$@ab|uzDmW6-U|zKdTU||=P%uPxH2YJx+R7v98wvx@v4ru>FE)0Q(76*j;lvB z1sg{^lyB(R%lods;?xYTZ|U?LY($u3DA!JP#YN4ENwWx*!l^kguB_cl_aC~auBvOg z&Jj&|RPe2bw0BESu_+<0c5m|WRj;b|K0jl4cwHdOpyixOI^JA;u#t7#W7wd@S-^YC z!tm(NZ5q;AlaXHtjV`Wt)L8TQXrt+dbF%EWyEHK@*HOK5M$Z=eL~prQKWTijKqmSAfsTmR>n}2Dn{FR}dY@r= z^OJjZMkD-0VoQH}SLkgtdc32z|4=j4)8wwj?hmtvW6c&uMjz;mSij-oqx+Lt+jgHd zOpxAM^^svIpPscxW3MjR!PP}ct1X5_(CpE2c*@Qx{H;srOV%FU>-9bCB(>J8UEVIr zItuULrpSrL$GXI_cV&)GnOTvuuKCh?T}<3R?`3-i!B;BxtU4EcZ*h9{3pM%dT~}O? z+i@N~ibn^0?t~M|*m;Qj^i`5}l*P?H$kVTLsOj-t+!k^jl8X zGugZDyC9LAuKP5VKdUG@U|k=(m?Si`cY>~an~a`eU6*%ZU9WuE<8VH@Z*jT;5c?*3 zSBeV~!|7|TnNXv0(h=*M>0*-9u)MoH9l_~r)=saEX)>zBMtI!A8KHj9bB}24CD^=e za(30ZAkX4F+!r;aIX9-p*2UCoTs+6Q8S&_`KyK)4hnHkWXI%4bUVAhsqu-@oW57G- z+@ku7oT-x2%#YolGrBb8OsUsAD2r7nOO}vyvc2Fm`-Y?S9^sT_FP(F8TyI5W`1=># z929LVo_f5eAwNGI^|G@Gr>uJEJVkf8)-3a(BPTxDb+=@`M}0;zb(VcbHD$w6rsYG* zhNe9YB|0#Zxi-B&$vNluvlu-aL|~uObe5r|9d&3pN(#v~enA+rHtC?ueXHY&CT$~y zgC`#KWz;7(>pf~SxTE!dI@nD!^{mb~L&l7cnlSLhxh*Ec&^f1;YcAG9)3vi<;=qw z1yiDuemwrE9zo9Ihd8S~mwK4H;&kTMpYmeB^B)`WL*A*M^2k31ro{asulmR1U*wT~ z%8U82!F2zIBFrK@6maRzdUb5AXNGyH#g|u&%cZ z5&2Z}S7h2ZY=;jIPBdJUq)0ZV^*ok9P4PG^EpEj$=t4pFt-cy*8_{*f%I>eM=Z9B@dM-YtwM~qE5g9W zLcdY+JlL&{OjYYr_UQQ`SL^7Eyl$Aenbnp20%q4U1z&ZL0`BL#`YN+TooI4zYS=;^ zbe%Hv8|94$Ti%JOYV(wW_)SkHyAFtTZn(;|5i;;wNv`F`u1<62Dq)B}JfnmdN=T~Y zYVi+dh$LB!lO->WI883mT3#$}JQ%vOhn7t>agSf6ot+Ln%_ zJ15VqqeFug=IpLu9ls!ZcVzHX(2$ZH%aHWn3=r)dQhXTvAUl40uw4`DT<@IVtgzGB zcf<4|?`ar6#c>F?MbR1k6~J&uJX%+2I5$L3OLeNxz&aW?#AoE$BdrFCNPxZ&Kjyry zh^xMmH0GJy;V|p?F-FfScVzFbhq3_aQ~&UJpbML8M$Gnha{Ml$vinZXB2Hm0nb>p_#F5V#GpM1J<}5e8(`QaM=uUggx5^Cv z8IO7B%;|`&eh4z#NDCm8yb;J}%Ko;*+M6U1Q zuD-tm0`kI0{vI)o^~E9-qnX)n1Ph1F{wdP6M-f@GSD3STe^GYq)w?>t-4%r<#_}qW)2OqIk@p-`a1yX$3sRsHi3H`rc5>uCd0i_RW}D zk;DI6k=x?KS1nA`EgOT00jH(rwmWzkJ`av=7?hYNT6EJ=)OFXFK{uIZo<}yY*6kOq zD$2O1mZq3f0h&f-Q$C*>N)BxIR5mT!QRJmupO-v7U~)=tV;K6Vf6AeI?MZ>(u*an2 z;F-swxjK=vS&LglO$A6XX-7imwALa$WM$K|II>TDVX|E1(f1;kYt^hm#|K|L%(*Q+ zPqZ!m^gRdxp=a+fta4;>%s6+DNo=l!M* za_lwbB!{!1YL2uJ=}uKZ3QKi+8adc>m&1|4dO{}AAXiPW4H2_$BW%*+IiKaF=a zR(gOJ^eVbtnY=b^oj*nTvwo-; zRAs%Ur*0)rT5GYv!zzWcjv;!S2l1ih`>~LlXSO?!*2*197ktg4(>7W8PcT>fJr{G$-Zrs8=jw|A0BY}?%H@sY8*AGN?|GPiD6Ii z6sP%Ma7q;onRft(s2^Cw|9^Woe`^SsaAmN9hR^b>DlyI)R>y}Gc4Ln*J@joxi-3B+ z6`fO#Q=_*|YqVdA=>~SESxtk!AK7;Zhr}OT#Q%SLH(%o$m`qyh0?x8aPS1QzP?hTR z@|p?7SzE>#=xsDYUyJLLGPxUY5@|Z}5P5N=8vGnIj>Z`TXjt0D8QhX#exKGYU5)-_ zT4P6>(HGO}P*d1_cv?mxGGzV`A(>Z$pS@-@XZV(kEq2%Uc~rzzn%c z?dbbMQcTQlF_U?669+bFX1~DJ&FrFq&FIYDUPsp0JVfZn zs=?1*vzlYY8#sm#JH3XRgyZnj65S>A;cTu>9c#i^=ca|2A$qp=5h2@Z@Ncjxa|7kc7_v%GO;L>fOByvve4Tog1W2cDjqB< za`qBlbvd}zBq^Bq`1EOlyv?<=`vm}P=aisbjER-PdDd`oV8g$kP z91{yB*H~CEc~S*}3I3^(eYkF~ecTM5BhV==!Rg3^^;7!ee(3sm9dqz%CI}${C$$8) z5d{f8p*jzPF94!{#jx33Y}Mizs#|bOkh7&+echeEn(u}JVPeEJnT#npg3V zCc@$y&c7BctZ98}aIuMH9F^`r>c88!=GBo<$5DTQi7pVvd~HUtK=E7A#M#~d<|P)o zd=Xs-9D>+$L)Tw>Hy_4O;dIe_3`56)XCNPht{LFipBqldq;fH5eJJ%j{sSD&DipFG zwcYKzEPQ9Ebx2Z`nDZzWJ`QfL?hetQV`DvkI7u`M{^!?^9y*S0-z3Al41n)T<%V2YiJhCLD($TLI>gWZZXB#dD z=Yu4K5IrwGIJ1go{iKR5dmxBP`plXLff=RNELJ$4osy1cp8iH+*9udqc$TLOJlPw| z>W5h!uI!0k3X8=;NG!?}%wmIjS+5*xgbXukDdnHKDRBQJ$@pc=I7x1N!_uJE_}oQ! z!$Vq)g|U#bh-!xl!|ZiohXe~Oke9M+>w5C7MY6;}J3XNyLvLX?;&J6hI;&Uab5KGR zNsO7b?ohYY`w;qLwR~}xQP(_QWlDfJ!faoRl=v*1&3@wdNtXGg4H>$jlv?8B2O-;i z^$u_#PU?1$iiXb`M{g&vTzW#L-cI20q^v(@2R>b@(j3vD6K~-BrylD}y2`AnBb9f? zr%{W2hqoB1#?Qf^k+aAYZp-V)Ql=y?Gx}4i{VhER3FzWO3jAz0!C*%ptnoV@SNgi9 zp%iQ>w&&q$^gp`v3TLgu_vVASR2zDuqCAiTGDzS03PI3j2*x)zOog2R)nY)vuY$!&tYo~sLK`7^0l8Fz zMOU@~t!UMjoLfQb!ELqO6fuPdK`B)vYW~%2G?NLtCYo_QVr*D&i_ul7PX7pI1b>QI z6l!?p^tJpEayB(K%`WI028@imS86U#^ z;zPZnGd?sV3w!}dxhTF}f7jvs;7bjUPy=2zjj`0jZoU-W>s!qx2nXFK{6~+} z=(7ng6D@X<7JXxWtH>O*D-)`44e}y=x#5q}r_^1}v;s_tq6iHU3?x*IR6CfP<@cW^ z)G(*6txK4=q$h0$JZ8|V;wjY|0;L*<6-#{p5#kIUN#hFSyFe9 zzn6mB+uaY8USGU-#pPkhcd=BL%uNuYm*oKW7Hy;_>wOvYOYooSDW!m_QK>4$d}`8k zA$y$6OYMqfJB-v)@$4}Q%<3{tZgDlLrIS90^GN;+t?Q&#VMwE>J>qo~_2oH=GBQF$W>#FGpGugar0s^j#QvLsCEnKMV8!AG{P0!3fnpjm6;L zVJ3s*eo>sa6XXuKjO9W$;9=X5wKX`Tr9cP?cp=393>*~jhz)o$FHv0Jf6+id#26g4 zSIT_++IU{VW9=&Im-ltIBFRpHL@Ot?? z&J6#bX}A=2DWpoZFDI%|TVu zEn#fq{!vq|fnY5;b^!85|GMS0Er5ocmHwg0jQF2pa$3T_AM-y~>Cb8O*Q@lWG=l$N zm%_nz-WHAJpcv~6NY8x&IY5Q5f9sNiyWA57-%b$e3cKZifh`3|p4oBWGy@k060>sl{O#IJ5e>VL&(Lbxw zpVA2aRr+6}(x1}E?q4Vm_8wa%3=K{eEdd#s^ePN7mWo!#JK2mja2D^JGVn5wX*-e7 zCtA-A(Y<(<_ER7RDu4jr1{0~~pg@a_6ljkPGUGdC` zsbms+qQk-w4-2)B>KS8GWSB{dg{Ov?L<)PdoEVNDb%p6|v{=?qIg#YY|2(+Ma0QcM z$LxQLfBAUx2%WqgkHlBSn&vbNZqUO88*Wn3MG{-j$q)o~7P%=uZMD0lZpkHv9A5Z3 zIJ{xObW2e@^7x_sXm6Y7XXF5R3q(NBcpc>06PY{b&C;jE31^(j{N#`z6P%UHK7;?rowzV0DCCQ-<`Pb;K*$QWJZ zggOwkq_9dE$K3ZIRZnpUHCLQNt0>5Qa5tDYy?cN4%lTU1aDL&n4X9j{nY&_@i(hCc z#!=RWVO1|I8pmIyb>~dx3~-t5+Emxi8W7_4Ia(g8MBElNz*sRSdxsg|`b(TT6t)&3 zHb}}BT&j3YB!p0EHV9)Siub`-iNX=7sFnGJr*UGw5F+u_36c3~_sdUhTRErGVU7%p zY+y}006F=0F8?E9@?YdU|L)M%ToN?Hv!)}vJGO7FpGyD;ziA(w*vf?HM}rFE0ON%!fHF>hF2Xp9=c_ zUd;bvV)jQQ?st6aPpb5%G=hJnkpER?_Q%A`?(Z1v@08~qmg^6`iIo$4_OpP zssA}a`U9diS2D9ImSV{s>VGPSo%ZEOevbWJ#t;L^N?rzYvTZ$&*;9$6`x8&^9I&%u zdw1Kt-bg>|;5kEtiUAS2_cuhS{MS_4;F+0*fH7?Z6;wY$QCHe@2F%1L4j(cUpZker zO_5~Ps+^6(i=9J<1>P+wF>KX`k$`wfQC-Kk%*bH@P7evBC4Rl=sKTH&!#Q1NU`HwEG%ioT zP3PUnf_F^gT$9sQSm@tsdiXa9I*^qkFEPPh+Ihaa#vywCAt_awfY5Px9(Jt4s^ows z{XKsJjGY;Y<;kNCLaC zlBQ&^W94p1tQ^BRE_^EXMTVYlOdU*6hmgSpyHv#&13VgR{Ko;M;){LSg@cEFQ!VJe zr%ft+dDG4+=(Mo*g2Mg_dA@chy^g(+yr8gg(HW}Y?%3z832Q_V`9OJO&m~(>NsL|! z$~_O(+)JslHIu=MeKD z8Dw_jB4pbz6UlGg1e)vgeTuotlF@t5ZO0|OO3d?4nhbIqJ(QX1zH)bK#MriaER153B+__3aR*3 z0T*6l`LAY$lNhZu61&5d#HJfM!u0tCY=<^g60?WGnzClmr(9uX1I(hA%dr#K!(AYs zEyf<|Rb|sjfzJn-#O5(Pp@u{nkz1XhdzM8JW12;P>V$)*Fbp#MxwnbmKyf0(VuD)- z#cFt&KkA_Cu|jCuk3uNRyZN(~t@oP5lbV|li+eajIN zeFZ|^wvEH z$+{y9k9UAC?KqVW?vVrAJMNK#I6z?so~FzCvmfiscUw~jzwdNSJ?Ap21FU2hD979< z8Bjp&1eA5)Gml1S-M$Q29jyA9m;8|u2a1*kY#s2G3ucP>9iU887#pkKC!LKJa$ed6 zF^Fc_j-wmFTtSw2Ms^tdWH#nDSiLY7xIDK+IU1YK&Cr8+GM^^@ZA}X1TAwav?chJY znpVa@iup&Exdv=*Ngfn@-%_$U#p1Of-#VXKh38g%Ca~g7IJeT15At^)GlUgM|K=$u zxCJKFx-VdWa8h+Aj#2FK`n>*d0@tti$VQu?k_d{ zM7OLUJSY!ay|S$tX}}L{^uFMtaW*0FLM64U*r7gyvzBs`7!vj8UE)cZ~f|tK1J8w*hSiKT%^L# zo^qAeF8!l+N|OfB0#wGyH#i@=2GXSg?9Z6^5JG%{D>%aZ-BA7_)1}4Cs4}FZ=43oPeGh=Irag`xglA9O*W`kmOkzA9c3cp zzZImMU@J$HDn4aZ(E#!-4@#=?WXbx26FvASfK_}2bAln?(Ic<7jnMKp!{MN)FUzFu zcAZb2*yY`sK|26&V*~Xqb9O5Cj7UTmO;K!E(|M-&}q+tp4XRgI2+E~XGB$DYcSObngnpNLIijgN%GY^pVDsFw`#coaNyus?hx1kdj2 z!ZUiG%CYDc-(FmgmGd1Y;rpRjqNEt~jSt>%u{1);QO#Oy-<8=rdZ^`JaYiFnfpr$V zJ5o;458beDc2t|9;Z}yKn09GY_=6uZaTDzR7PSNVR%%9O{xwvF8-W2Yl&$wQY%SuifR+MjUn(73W8VHGtH8_s9)3Yz{?Adj-m2e zK;XS)Kw#H0=mCVbEQ8cxu*>=JH7&m1$|K0(*W_4(y=+E5Y7NtE!sPIh57-P^n_vu{ zWtT`|GTJEYDHLYVNALu1Ryz@|OI!f6s>$#~tudZ)-Y=ZsEE*$sk4{6AtB1Z!|@d;D+GB4@%UWn~mihyysmyYX2^YPwwHOKr6 zU%sL7r6s<6b2ib!*g-U=?Sm&7n5OGaThSOY7)+_#3~Sh8FP+@AXJ0u%rv%1ntF(>f za?IpN;E+nX0A*q2>kI*Mii=Kyy4Up$z20y1h_e5%|9{#Y{@;q%hX1G9YpcM2(c+s0 zcCA&@(Lx$(}Ti_fA86l4{6)gh0tnW=ll;E`4yXO;6 zI362hC>)}E0`^tD!lkUHMcNj-33>Ne<(j$_0D#*yNPcb0ri#Qae%>#hWVf1QZ)^1C zOx)?_=RIjijQNTau@x;57I+`wqLZR7Re}qX6uGU^z(t08RMP6Kgj#`EtM%!;&We$}mL0V67TJ zSqYc`<`Xjz$w4yi7{9wjEmlM79N;7Z;G74E923o$mh1Epy|)@#L9CU)z-e$B1unz^;w@z|C2d}+H0bainz#tIQYOWpn1ppv%-V$sAGuU?u6= zV7g-f+=G7K06HkjVI3&y5I+YHQ2>bQl83p#`UL}490raT&1-tI?nMA(B-&|U(*dBU zE_s~;thpRu4aBe!Lrr2TDgls@xL*O%;DBN*T!Q=HnxH-rGx54(#I`L2&!FSssgBxM zf>c{6nZFy)W=>q_3TI3Ay5iXrG;n;ABe59a)-m|W{&4ckx3TQe5joaawHUmF5@!ue zPOyuuLwhko@N8VMRi$A}dx!3Rr>tLqFQsEXk+J;Q$()#{9Vh9rGMwyaLC<=^5v=9MwM2a7KXk(HIb&_<%g0^pYL$W%trlq_IplZ@c{@jQXh!itd*3(>ZSHRod}K3|9%sp?(? z)7_1?zzmi$^MSFG*WcMJ=2fC8pnWgZb@Iyb^3OQ!jUUqzYe(+NSFg_y5Nm7!jM3{{ zfTMJBX>RSY{9_M3DTaO`dpU_d@lJl@_eQVo)5{eZ0@c{NC4hPM)GV|J#0V-NuNmih zue^NYw{Wnj+9I$AjmJYue1I!Zh<)M^NK09+hBjjGxX~JeMSy270iG4=v~wBaPeO^I zPiM2^t70k_Sn3+t+iiS13aA5`Y&mwV2xna@%mP)wdh3-pF zFK>mG6Z^J8F3?{FvnYVso2a5bv zM(+?WIho!3(VD>Qp|U4?T>*z}ppsn)jGoB@-&A4NSP0Al>^390n^w~@*~+4H5j>mO zn+GL-}_e1v}G;=?MKYT(| z0}EvN9W@}3RXmNC0S1*BG4?dx;L;yomm3qcfGWpC}__VjK zIeK1WDu}}1HMW-abryjtW`Wn59o^8S2OufFF<){78g&5L$}dK~gfm7-_E07ITC+F+k(YQ3b7H})5&)4(rG)0NqmF7!0bTBEN}_fcS{gP zeY0ziJ*7N!M1Y)Lk{M50)SlIu z?m8)*uF~^zDfv$1cr&|eTS0z@-RF$Q#EaVKiy%N1Vl1AT82Ti?IV);>+AO&%D|UI> z+nScF<%PsP!1Nbxb+}TyFn@ci*Bia_NYJAJHu@E}xOI#8b&QHt`v7CoD)d~rSXFAJ z#gnmPj&7Hz`?LV^Wf=9oscC_B5Ong?wQi|vVMdp`eH>`8+|iBWFLfl^A77&TT_AB@ z7NrsGI|9j|R!5+EG{6}sdWExI*um}D~`+O!N$- zhPIdkmegeisV%d_0M5Vs1pqjlquaEvb?vTcDV(0<9rTz5w3uk>4)HRR|`>Jz*D8ipt9#@obT23eKF9vTU67_aUUe88Tl1t(Z*cHVswgI-NxkJM6F z6Jtb5EQK*qJ(BR&n#Jf9V>2d8NzT?))R%8YikKuab0C*}zR|9bdx8zCk67U{8R>>m zHx+zbMn{1Peqj=at=WBEmvJw%gWEEV5tbeC8Fx?4wUBcN?duwJGR%!Rydo0>f{W^2 ztl5Ak6sDt)KeQO_vx622(qbe<&QWg=%THk#;A98k;WC^PcdxKu6lH9v$;CZmLn1&2 z-~|aBlr*e47DoezPvEpz6yNjs8FR(n+SEKv`Aj>2^Wb$6*w|`tWSEAI1BD>_fh4{O z=6EhCh6^>o^k^{vB}6$+OwcLAq2>@6UJ5qJjM!DI57C zSa>af5p95CKI6dl_mZ}^f~f$QT0t~C2tDH zd8dKK;I)9@^oZ9{$PCgX0^b7(kB>)y2a;)3MLECS0T4Q}qm}Jnk7tbms_yx3?7j}_ zkiQ?C^ON_Ls4z8eXj>~c5E)?SM`d=#BzO6RN8?$sB*rA0F~Vk%z{O-NdByOg-uJPU z4i=wWmwM;FQ%Or)S3BZYbkHYabc=XQGGh*KY;8)=0`udJgMRWst^kp{EW}JWCUN%~ z>DU8$O&B`=475y&d~o@w>lla{)9%l4N|?F}1s<)4Qq7@tf|Iq5^yU#I)Wr=V|8VS+ zMr*kN13URtbhSxNFH90x>Yy2ziT4#<>jx5D*gCE@3ls*aFwBN#ydN`?!>B*hAjyEm@_8u^2^KdO9X<5*s*j}{ zII+0V(3^J9VhH?iTm2vz!P>VVtutVSg~!DZ6V=@h$p}PYF4KhWISt|X_#9us=tDmU zCuq44Byci)(Wdp|S(% z+c}*!|AiNG&@mtV*8-S%83FPZ28Q!bev^di?Sdrv#>g=@(af{ZGZ8O>`mEh<+$QL} z^I%){oda=_aTcmTeLW#zUgMY*Xo?La%~|J2KtOx!R`ziW{}d|g4bIOPvJnCCv4=z? zxD&=wn6_xF_cRRdM%VZP1jLvP5ilEjNDK2;5P*F!QYA3W27EGp`0kh!7cDSgth=TD zb%r${L|oGsmbMdzFhY8FJk*IPK@>(gfs=or7;D@%!5Q1N5I7*93h9l%7xFX zluU=bn%+%_x)zw_Ost$Hl3iGQoC&SyeK(*e7Uzf{&Vm0ljTlhysv7u8SQz)#S}S`)k~h`J1?N!GfS{6k-lww5sU-Q;_^}E=@M#WD=f??E^_xNy0eD)=$lmPJDBA55`Rg z(3t&@mSEBqkSuM?<3uW`6qWS{-l;z1(|johMUU+V`=6!si~BDAJNMQ4o!`3o{hi-x z2|9iQxd=~HRL>uhJ_JJ3FNc?yh`HRb_cR_L|5l14msU!1J^E=pQJ@XW$1U5@fB0UK zU9RgkH`>pG4#s>z=y*U?*FvFPkQ6VgZUdTo4odiO!chZ+An^jp;34|q92EKU@!VhN z$w<35df5|_o!gTqfDnQUA9CXEf9Vjji+_ls!sZQ*f`X%Xf}_9%UvLzEaFjrBlwfew z?BJ+5!BIlNQNqDdBEeCj!BKOAqr`%v=4C|9r=|$K;|YqA7N0e1$x(FDaDg10v4|NH z$q)>q%YQu3c)ro7dR4~e&=V`7O2Tj6K0%*vcpP=gY>!x~m<;=q^JY!(WSS?u?l9W2 zq}1w`S94dEpcgBg)@y0`Vz=GNp>HkGb=ABNLoEz9KxobXO z4Se}YkgdfUzS?D8%R`Z%7jHGMjfUeUElU&34Ruy)J}*E{n!P-E4L(s_hic6(midZ4?=UGo@A2~EiGCd;czs@3 z$M`kNDc(1|FJ9MQ54qVwBbKKcC54*U`7pfpD>amVpemQz-T9DO@2K`Mb=lRE1hew& zp?bp&M^W#rVcnt(J3~JMLm8I%7Lp16(8*M3v0;Z%-m=1*&F`evU#zHko_$ELG`V;p zN3*p_$Voya@k5|+`BeAI=XIA?kLAO%`1%7U6K_2+$)B}#?Rm2sMq&8xF_+@wON7VF z7ma!EZzB(NIo|miKeojgpLe(KzV-gkezcD&ZEC79dsG8&=E%K%zPB{)Xu`7ncR(@3 zEO6(M=q}vVxB$Zb?xZ!0#-GTmYx_1mlF30G=UeERuE0VxYRK8@Fnomn$8{Y!p-#%Bcc`Yic9L#w zB^^MM_AZcw2GEkd3!Gr~W5xR$BCmzuBvj1J#`BNw7^poRMC)Id=b;{7+a^EKkW3x* zNTD^z3!hyzf6u`ivxJT=sLFbqSMxggXyQ)Igy*-Po{p3-@0eX#xqav0(`z-0ya!{# z{qOF-X0a$oK+0U*<-rK!%_f`1mjl@?oxWQ?J!p3QV19QZ+J`O4lFWk%OYYyFqZK+} zec0Y7%}UOm*(D}-UDxj`WyGzZjZXDAxJF#s?X(vECzea%yls;58(!b;U9-3+@BONF zX@7Ww&2vJ;RGvZWRk>vr&P59~U&M^{D=kmI;Y8IYeHmR`d-GUr{LKYTjg21!SXXt_ z?pb_x#ILuFI(MKmh1k^e$_0MC`9ALJG0XP-o??bJA>VtTgF8zL$3smNaLWwPWub3H z`wp9HcrV+?x8A~K-L}=YN^G~Pz07}fkj~!1c!Z6RfeM$2_WtXB3`xnT=1Ggf2obt*Jw$ty=Mze4A3CR$a?mV`jU!eiU1C|fh|-o^y#i8&DVG7yjQwgnJjryC%`Ks zHN56z`mQX?g(?SDC8xfQvTCGfq6YNy!Pc3NB({Zm23(C>7U^|MMP)YM3!6`r)HU1{N?`8BFa`E%W?`~4~vSU_+ zJbEkqMRe7i&cg&@)^q(i)p{AvHqB4t*|$hB-77q$vACTP!L#zIJnoH5ILqz$zVJsf zi*Ki2*0OCl%CkpIMM-+}&}}urL6p4uSOf3227FFqIi8LGO3KNx3ts1=u4Zu^cSllp zf#B&YAGX#V7`okOEI4KMZA*~>YG%4XK|xmV*`sC2ytQ^BNi@f!5>4R$*!_-D6mOLE zh8Dd_A*W`Cs4*IAx?mB!a@CdGI}_3&1?t}-&*x6bNRed`Id5%p!4)q>SEE+VHS*zC zc}-W^tk!Q^MN14hEH>|p{Y{pLpV|)n>)#5WNA;Pr>38{-%ZPiKXM}n!(7dztM6vwR z$J*p}_108^_UV16DB46bmffWw{;=qi*R*b&j9V2twojn@R!2Ucp8&kfP$@XWWuv=^ z)M5MCw zczOKxJh85h)>&e!#UxZi7ZMk_g(GqAy=Eg-(1W*_voO^*HS& z&g3aoICx(dZ?*OtG2UBY=J^OegJLjMU71XN=V?+usd9Ug)5+(9iUmJaWj>uF`^|xo zN;g>*%jR9n0JrL~q-y@zIK{%6s1@DG$tqWne70x*Gkc?>H}lTYs`KW)on3G3$TPb| zS^FQ37H;`Jwt!`twBVzHEY_OUT7w@7FI_kQbkRLfuD6(=nOM>Zz;d@-0IsY?c`Y9dX zRgYZ{_XJ0r03lMpCwY=G!=nmH6|Vd6o^b4tl>F5I>Zn!?ID4sFI~gCU;#8~GzS#Nk z!+c+s$HuwTJ&u6}kk4T-HWf>}H!-i<9~CoMAGxbOi~aDmc+qEBV5`NwyXmi1t)j-T z!A?KVE5RYck~M}w?nXK620D#vEq0Ms2p0b>=`gf~WedqgL&8Xk*mFVqY~4W5a@ufy z+(%LXrDV&i3ngG>T`ifWmT~D+34`s%W&}L$>WumWUV(4#ui4|?Kc%vL7ygpr*L%(5 z@LPq_v1Pv~H`|!s%+r1*^ZM?zP}hGh-`}>Jy&-_Od#|8ZO`Nf&9gQ3He^-y&-rzE)AO6-_8gUh!Aml{+^n`HcC9LTt`#jY@9 zg)uzR(182$I9boge@z#iUD5N^@}&cOt-Ig6z@pTEgsFTgME=cp7uHQQdF+D{GC*K;EY8d9uA`jl=!!TLNLM{ z`>XZk2QmU@SBsKL^pS+qm`ML;UHe7S7l)9fk>*wwxKOf*lV!EH+XFP!>$r4S^RDQE zEaqwJMEFk`3TIJ51>V&6e3sA`KHm^YexCxlwEjxH5hmDR-=Jru_AreG8%f{F*DK&r zH5e*4{Fb%qVA4~4X0EUf@f9zdGF~UQd@J6b)v(ChuL#L@+&@s|+8?1b6e_T^qp5_% z;eV~`nH$2_anGS7%5X9T#@!-T+@>m1+_6y_7KaEkP9aMN7F*&uyVt|+q-!MgWhChh z=mhPsfWJ??&TAbH3~%UvKj${rK903eUQP%|?8e1V#c#WW2y9gc%8zN5AHQLM@;U&q zEa_{7NklS1gRNHY5bP&jjx}hHW+v$q;@P>^1Gc%%K14_7dsXwqZr+bR#uZ!kpCzvq zrU&d|r9wOziMzC9m8d7C_#q?df)V0$NNgVy9u>P{=#66P#L84uiqtZ%Wj88B?mZS% zw2e@01YT)wpSanA{Ow!LTjdw5s`IY%v{lyZbDQrn22A<+UHx|ZGYmMbLt;qJ8JZ4D zt4;+Poc&~{_K^q6p{Svl-R5{d-8SJ9hkxF<;Qc0pmYajmpP1bVTnlz7XIF<2n@h<* zL`57@0T3G)j**UzXk6d%?k-RF|ny7Fpi zTJ?0ft)U?~HJL@%=h<$M@|&mt%3-1drNhNs!8&7Jk!S1mF;Aa-bA#PB(mU_Bj_9v^ zb%yswvKy)U`!kLKeIqAMvosy-|FAnCOFlGTBGc+>lwKTO44NsKv!ULKQ#d!q&vno> zs=f$w{l)QYKz;JByc!mCRy)ez`oX}?9-?luW`ysfDGPIyv!h^Kl0BP0tABhjWhC%W5bqgP4%)f_VwY)U%m&mql{;=#nrf=N_yE69Ih^0z ziG&TnjNN*sOq$VLyFTVHAm|uZGT7~rul_ucg}O+?B+n;}C}37fvnnLjb0s{7M`CSO z&^8oyOg#50W(moNlMez1+<-G|4N4U-(`M&ak<;K0H$Ykm_hjaetxhB3$;=taH^vDU zgF}zKSL9sf$DVtfEdrn#q_^+*n|E1yeODyJ9%oVLIsw|d12XVL@P<2Z#a1{8Hp=(w znP46P(OD?k<&7!3v~EXUh41w|;H7QoR0S+gnsMPwo}9L2>a}-fn;tfAe9Ca+yfbgI zOfY6NS+mOLqMESc>$oP_<+jcY0%$nN-R6k|U*Ft?LoUuO z`HJsyS36CHi?66QrS@wu&_tTznO@@N+@^3XzH3rNVWgrklnNqC z+W75p%FPOS3!=z3N+(?^P~Iyre)-SqHMttO*AO;l8XiTAA`#h?Tn(Wq?YFjR@^ePR zfgi-4r&g$|h5hs=skdPd@8V!Gc-=lVO?19j8#3X7jfqV8ydLG7q9Zeps4-Ga)=w#! z<>#KZV#^Og$wj7-%N@o`I(HYj-o=Xd&34l$8k^TU{WaD+_YWC+>W>$9R+Ak*)oYgM zqKZNhLsxSeq&242#*vvmr?eQav7`GC=AFYSmuR0;&z?-WF#W{c7&QB3@4T@un)JxL zV!+eyPoHq2`x(39rp^Z1ENe-2> z#ft<_)&M*?NFg2$sOQ~3$F|_nDEPSsILja{@pr6Q3&kZT|Bj=M;!HUx76u1v0Upu+ z@B28O02BH*$=_#1rN6IWs{<4f1?H?^V=cf3+8q&D3!qazL~ti?unsVQzXsXr0SS@+ z?(M-~&=%kS9POZKJz&Vd=mFvz0TJ+_2fz;2*8`^+46tCkrsPGNN535O<;pg>D&4yP+Ygny^ay$ z-2zC1?k&(7q`=G;z=5IW54y(M3Kif^5gpu)fK*He>Jg-u(7}cb&B#fEk`YV6F&e-R i+R&i-+$yI-;Sv0P{|KxYQY%5RHsB;vc@+Sa<^KT6lGf<} diff --git a/docs/ctc-adverse-event.csv b/docs/ctc-adverse-event.csv index 09bc9d44..272acee8 100644 --- a/docs/ctc-adverse-event.csv +++ b/docs/ctc-adverse-event.csv @@ -1,4 +1,4 @@ -mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade,expectation,resolvedDate,seriousnessOutcome -mrn-full-example,example-id-1,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1,expectation-code,YYYY-MM-DD,seriousness-outcome-code -mrn-two-category-example,example-id-2,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1,expectation-code,YYYY-MM-DD,seriousness-outcome-code -mrn-minimal-example,,code-from-default-system,,,,,,,,,,,,,1994-12-09,,1,,,,, +mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade,expectation,resolvedDate,seriousnessOutcome,actor,functionCode +mrn-full-example,example-id-1,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1,expectation-code,YYYY-MM-DD,seriousness-outcome-code,practitioner-id,function-code +mrn-two-category-example,example-id-2,event-code,code-system,code-version,code-display,event-text,cause-id,resourceType,seriousness-code,code-system,seriousness-display,category-code,code-system,category-dislpay,id,1994-12-09,1994-12-09,1,expectation-code,YYYY-MM-DD,seriousness-outcome-code,practitioner-id, +mrn-minimal-example,,code-from-default-system,,,,,,,,,,,,,1994-12-09,,1,,,,,, diff --git a/src/extractors/CSVCTCAdverseEventExtractor.js b/src/extractors/CSVCTCAdverseEventExtractor.js index 6657a709..b7824b8b 100644 --- a/src/extractors/CSVCTCAdverseEventExtractor.js +++ b/src/extractors/CSVCTCAdverseEventExtractor.js @@ -34,10 +34,14 @@ function formatData(adverseEventData, patientId) { expectation, resolveddate: resolvedDate, seriousnessoutcome: seriousnessOutcome, + actor, + functioncode: functionCode, } = data; if (!(adverseEventCode && effectiveDate && grade)) { throw new Error('The adverse event is missing an expected attribute. Adverse event code, effective date, and grade are all required.'); + } else if (functionCode && !actor) { + throw new Error('The adverse event is missing an expected attribute. Adverse event actor is a required element within the Participation extension'); } const categoryCodes = category.split('|'); @@ -90,6 +94,16 @@ function formatData(adverseEventData, patientId) { 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', ), }, + actor, + functionCode: !functionCode ? null : { + code: functionCode, + system: 'http://terminology.hl7.org/CodeSystem/v3-ParticipationType', + display: getDisplayFromConcept( + path.resolve(__dirname, '..', 'helpers', 'valueSets', 'adverse-event-participant-function-value-set.json'), + functionCode, + 'http://terminology.hl7.org/CodeSystem/v3-ParticipationType', + ), + }, }; }); } diff --git a/src/helpers/valueSets/adverse-event-participant-function-value-set.json b/src/helpers/valueSets/adverse-event-participant-function-value-set.json new file mode 100644 index 00000000..7b895e92 --- /dev/null +++ b/src/helpers/valueSets/adverse-event-participant-function-value-set.json @@ -0,0 +1,67 @@ +{ + "resourceType": "ValueSet", + "id": "adverse-event-participant-function-value-set", + "text": { + "status": "extensions", + "div": "

  • Include these codes as defined in http://terminology.hl7.org/CodeSystem/v3-ParticipationType
    CodeDisplayDefinition
    INFInformantA source of reported information (e.g., a next of kin who answers questions about the patient's history). For history questions, the patient is logically an informant, yet the informant of history questions is implicitly the subject.
    PARTParticipationIndicates that the target of the participation is involved in some manner in the act, but does not qualify how.
    WITWitnessOnly with service events. A person witnessing the action happening without doing anything. A witness is not necessarily aware, much less approves of anything stated in the service event. Example for a witness is students watching an operation or an advanced directive witness.
    AUTAuthor (originator)**Definition:** A party that originates the Act and therefore has responsibility for the information given in the Act and ownership of this Act.

    **Example:** the report writer, the person writing the act definition, the guideline author, the placer of an order, the EKG cart (device) creating a report etc. Every Act should have an author. Authorship is regardless of mood always actual authorship.

    Examples of such policies might include:

    * The author and anyone they explicitly delegate may update the report;
    * All administrators within the same clinic may cancel and reschedule appointments created by other administrators within that clinic;

    A party that is neither an author nor a party who is extended authorship maintenance rights by policy, may only amend, reverse, override, replace, or follow up in other ways on this Act, whereby the Act remains intact and is linked to another Act authored by that other party.
    AUTHENAuthenticatorA verifier who attests to the accuracy of an act, but who does not have privileges to legally authenticate the act. An example would be a resident physician who sees a patient and dictates a note, then later signs it. Their signature constitutes an authentication.
" + }, + "url": "http://hl7.org/fhir/us/ctcae/ValueSet/adverse-event-participant-function-value-set", + "version": "0.0.1", + "name": "AdverseEventParticipantFunctionVS", + "title": "Adverse Event Participant Function", + "status": "active", + "date": "2021-12-03T16:46:43+00:00", + "publisher": "HL7 International Clinical Interoperability Council", + "contact": [ + { + "name": "HL7 International Clinical Interoperability Council", + "telecom": [ + { + "system": "url", + "value": "http://www.mcodeinitiative.org" + } + ] + } + ], + "description": "This value set includes codes that describe the type of involvement of the actor in the adverse event", + "jurisdiction": [ + { + "coding": [ + { + "system": "urn:iso:std:iso:3166", + "code": "US", + "display": "United States of America" + } + ] + } + ], + "compose": { + "include": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType", + "concept": [ + { + "code": "INF", + "display": "Informant" + }, + { + "code": "PART", + "display": "Participation" + }, + { + "code": "WIT", + "display": "Witness" + }, + { + "code": "AUT", + "display": "Author (originator)" + }, + { + "code": "AUTHEN", + "display": "Authenticator" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/templates/CTCAdverseEventTemplate.js b/src/templates/CTCAdverseEventTemplate.js index fb0fd1ea..8639c2e1 100644 --- a/src/templates/CTCAdverseEventTemplate.js +++ b/src/templates/CTCAdverseEventTemplate.js @@ -102,13 +102,47 @@ function seriousnessOutcomeTemplate(seriousnessOutcome) { }; } +function participantFunctionTemplate(functionCode) { + return { + url: 'function', + valueCodeableConcept: { + coding: [ + coding(functionCode), + ], + }, + }; +} + +function participantActorTemplate(actor) { + return { + url: 'actor', + valueReference: { + reference: reference({ id: actor }), + }, + }; +} + +function participantTemplate(actor, functionCode) { + return { + url: 'http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-participant', + ...extensionArr( + functionCode ? participantFunctionTemplate(functionCode) : null, + participantActorTemplate(actor), + ), + }; +} + function CTCAdverseEventTemplate({ id, subjectId, code, system, version, display, text, suspectedCauseId, suspectedCauseType, seriousnessCode, seriousnessCodeSystem, seriousnessDisplayText, category, - studyId, effectiveDateTime, recordedDateTime, grade, resolvedDate, expectation, seriousnessOutcome, + studyId, effectiveDateTime, recordedDateTime, grade, resolvedDate, expectation, seriousnessOutcome, actor, functionCode, }) { if (!(subjectId && code && system && effectiveDateTime && grade)) { - throw Error('Trying to render an AdverseEventTemplate, but a required argument is messing; ensure that subjectId, code, system, grade, and effectiveDateTime are all present'); + throw Error('Trying to render an AdverseEventTemplate, but a required argument is missing; ensure that subjectId, code, system, grade, and effectiveDateTime are all present'); + } + + if (functionCode && !actor) { + throw Error('Trying to render an AdverseEventTemplate, but a required argument is missing; actor is a required value'); } return { @@ -119,6 +153,7 @@ function CTCAdverseEventTemplate({ resolvedDate ? resolvedDateTemplate(resolvedDate) : null, expectation ? expectationTemplate(expectation) : null, seriousnessOutcome ? seriousnessOutcomeTemplate(seriousnessOutcome) : null, + actor ? participantTemplate(actor, functionCode) : null, ), subject: reference({ id: subjectId, resourceType: 'Patient' }), ...ifSomeArgs(eventTemplate)({ code, system, version, display }, text), diff --git a/test/extractors/CSVCTCAdverseEventextractor.test.js b/test/extractors/CSVCTCAdverseEventextractor.test.js index 39c0d259..aa2be9e2 100644 --- a/test/extractors/CSVCTCAdverseEventextractor.test.js +++ b/test/extractors/CSVCTCAdverseEventextractor.test.js @@ -36,6 +36,7 @@ describe('CSVCTCAdverseEventExtractor', () => { test('should join data appropriately and throw errors when missing required properties', () => { const expectedErrorString = 'The adverse event is missing an expected attribute. Adverse event code, effective date, and grade are all required.'; const expectedCategoryErrorString = 'A category attribute on the adverse event is missing a corresponding categoryCodeSystem or categoryDisplayText value.'; + const expectedActorErrorString = 'The adverse event is missing an expected attribute. Adverse event actor is a required element within the Participation extension'; const localData = _.cloneDeep(exampleCTCCSVAdverseEventModuleResponse); const patientId = getPatientFromContext(MOCK_CONTEXT).id; @@ -60,6 +61,15 @@ describe('CSVCTCAdverseEventExtractor', () => { localData[0].categorydisplaytext = 'Product Use Error|'; expect(formatData(localData, patientId)).toEqual(expect.anything()); + // Test that deleting the actor value but leaving functionCode will throw an error + delete localData[0].actor; + expect(() => formatData(localData, patientId)).toThrow(new Error(expectedActorErrorString)); + + // Test that deleting the functionCode value works fine + localData[0].actor = 'practitioner-id'; + delete localData[0].functioncode; + expect(formatData(localData, patientId)).toEqual(expect.anything()); + // Test that deleting a mandatory value throws an error delete localData[0].grade; expect(() => formatData(localData, patientId)).toThrow(new Error(expectedErrorString)); diff --git a/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json b/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json index 339a2c81..1b8d58d0 100644 --- a/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json +++ b/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json @@ -47,6 +47,31 @@ } ] } + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-participant", + "extension": [ + { + "url": "function", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType", + "code": "INF", + "display": "Informant" + } + ] + } + }, + { + "url": "actor", + "valueReference": { + "reference": { + "reference": "urn:uuid:practitioner-id" + } + } + } + ] } ], "subject": { diff --git a/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json b/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json index 0d3bfa6f..b156f157 100644 --- a/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json +++ b/test/extractors/fixtures/csv-ctc-adverse-event-module-response.json @@ -21,6 +21,8 @@ "grade": "1", "resolveddate": "2021-12-01", "seriousnessoutcome": "C113380", - "expectation": "C41333" + "expectation": "C41333", + "actor": "practitioner-id", + "functioncode": "INF" } ] \ No newline at end of file diff --git a/test/sample-client-data/ctc-adverse-event-information.csv b/test/sample-client-data/ctc-adverse-event-information.csv index 794c1ee9..a767ad39 100644 --- a/test/sample-client-data/ctc-adverse-event-information.csv +++ b/test/sample-client-data/ctc-adverse-event-information.csv @@ -1,4 +1,4 @@ -mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade,expectation,resolvedDate,seriousnessOutcome -123,adverseEventId-1,10012174,http://terminology.hl7.org/CodeSystem/MDRAE,20.0,Dehydration,DHN IV given,procedure-id,Procedure,serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Serious,product-use-error|product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|http://snomed.info/sct|http://terminology.hl7.org/CodeSystem/adverse-event-category,Product Use Error|Product Quality|Wrong Rate,researchId-1,12-09-1994,12-09-1994,1,C41333,2021-12-01,C113380 -456,adverseEventId-2,C143283,http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl,20.0,Anemia,AIHA NGTD,medicationId-1,Medication,non-serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Non-serious,product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|,Product Quality|,researchId-2,12-10-1995,12-10-1995,2,C41333,2020-10-02,C113380 -789,adverseEventId-3,150003,,,,,,,,,,product-use-error,,,,12-09-1994,,3,,, \ No newline at end of file +mrn,adverseEventId,adverseEventCode,adverseEventCodeSystem,adverseEventCodeVersion,adverseEventDisplayText,adverseEventText,suspectedCauseId,suspectedCauseType,seriousness,seriousnessCodeSystem,seriousnessDisplayText,category,categoryCodeSystem,categoryDisplayText,studyId,effectiveDate,recordedDate,grade,expectation,resolvedDate,seriousnessOutcome,actor,functionCode +123,adverseEventId-1,10012174,http://terminology.hl7.org/CodeSystem/MDRAE,20.0,Dehydration,DHN IV given,procedure-id,Procedure,serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Serious,product-use-error|product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|http://snomed.info/sct|http://terminology.hl7.org/CodeSystem/adverse-event-category,Product Use Error|Product Quality|Wrong Rate,researchId-1,12-09-1994,12-09-1994,1,C41333,2021-12-01,C113380,practitioner-1,PART +456,adverseEventId-2,C143283,http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl,20.0,Anemia,AIHA NGTD,medicationId-1,Medication,non-serious,http://terminology.hl7.org/CodeSystem/adverse-event-seriousness,Non-serious,product-quality|wrong-rate,http://terminology.hl7.org/CodeSystem/adverse-event-category|,Product Quality|,researchId-2,12-10-1995,12-10-1995,2,C41333,2020-10-02,C113380,practitioner-2, +789,adverseEventId-3,150003,,,,,,,,,,product-use-error,,,,12-09-1994,,3,,,,, \ No newline at end of file diff --git a/test/templates/ctcAdverseEvent.test.js b/test/templates/ctcAdverseEvent.test.js index 625cadd1..4d44bae8 100644 --- a/test/templates/ctcAdverseEvent.test.js +++ b/test/templates/ctcAdverseEvent.test.js @@ -33,6 +33,12 @@ const VALID_DATA = { system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', display: 'Expected Adverse Event', }, + actor: 'practitioner-id', + functionCode: { + code: 'PART', + system: 'http://terminology.hl7.org/CodeSystem/v3-ParticipationType', + display: 'Participation', + }, }; const MINIMAL_DATA = { @@ -90,6 +96,12 @@ const INVALID_DATA = { system: 'http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl', display: 'Expected Adverse Event', }, + actor: 'practitioner-id', + functionCode: { + code: 'PART', + system: 'http://terminology.hl7.org/CodeSystem/v3-ParticipationType', + display: 'Participation', + }, }; describe('test Adverse Event template', () => { @@ -97,7 +109,10 @@ describe('test Adverse Event template', () => { const generatedAdverseEvent = CTCAdverseEventTemplate(VALID_DATA); expect(generatedAdverseEvent).toEqual(maximalValidExampleAdverseEvent); - expect(isValidFHIR(generatedAdverseEvent)).toBeTruthy(); + + // Commenting out for now as Practitioner resources are not extracted and thus + // references in the Participation extension won't resolve + // expect(isValidFHIR(generatedAdverseEvent)).toBeTruthy(); }); test('minimal data passed into template should generate FHIR resource', () => { @@ -137,4 +152,9 @@ describe('test Adverse Event template', () => { test('invalid data should throw an error', () => { expect(() => CTCAdverseEventTemplate(INVALID_DATA)).toThrow(Error); }); + + test('Otherwise valid data including the functionCode but not an actor should throw an error', () => { + delete VALID_DATA.actor; + expect(() => CTCAdverseEventTemplate(VALID_DATA)).toThrow(Error); + }); }); diff --git a/test/templates/fixtures/maximal-ctc-adverse-event-resource.json b/test/templates/fixtures/maximal-ctc-adverse-event-resource.json index 21e40a8a..cc4e50e1 100644 --- a/test/templates/fixtures/maximal-ctc-adverse-event-resource.json +++ b/test/templates/fixtures/maximal-ctc-adverse-event-resource.json @@ -45,6 +45,31 @@ } ] } + }, + { + "url": "http://hl7.org/fhir/us/ctcae/StructureDefinition/adverse-event-participant", + "extension": [ + { + "url": "function", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType", + "code": "PART", + "display": "Participation" + } + ] + } + }, + { + "url": "actor", + "valueReference": { + "reference": { + "reference": "urn:uuid:practitioner-id" + } + } + } + ] } ], "event": { From 626a919eb9e1ba1a32f40ce25f7b625ab36cd395 Mon Sep 17 00:00:00 2001 From: julianxcarter Date: Wed, 15 Dec 2021 09:56:30 -0500 Subject: [PATCH 2/3] Whoops - rendered the reference wrong --- src/templates/CTCAdverseEventTemplate.js | 2 +- test/extractors/fixtures/csv-ctc-adverse-event-bundle.json | 2 -- test/templates/ctcAdverseEvent.test.js | 4 +--- .../fixtures/maximal-ctc-adverse-event-resource.json | 2 -- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/templates/CTCAdverseEventTemplate.js b/src/templates/CTCAdverseEventTemplate.js index 8639c2e1..aea607d4 100644 --- a/src/templates/CTCAdverseEventTemplate.js +++ b/src/templates/CTCAdverseEventTemplate.js @@ -117,7 +117,7 @@ function participantActorTemplate(actor) { return { url: 'actor', valueReference: { - reference: reference({ id: actor }), + ...reference({ id: actor }), }, }; } diff --git a/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json b/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json index 1b8d58d0..53097112 100644 --- a/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json +++ b/test/extractors/fixtures/csv-ctc-adverse-event-bundle.json @@ -66,9 +66,7 @@ { "url": "actor", "valueReference": { - "reference": { "reference": "urn:uuid:practitioner-id" - } } } ] diff --git a/test/templates/ctcAdverseEvent.test.js b/test/templates/ctcAdverseEvent.test.js index 4d44bae8..efbf6207 100644 --- a/test/templates/ctcAdverseEvent.test.js +++ b/test/templates/ctcAdverseEvent.test.js @@ -110,9 +110,7 @@ describe('test Adverse Event template', () => { expect(generatedAdverseEvent).toEqual(maximalValidExampleAdverseEvent); - // Commenting out for now as Practitioner resources are not extracted and thus - // references in the Participation extension won't resolve - // expect(isValidFHIR(generatedAdverseEvent)).toBeTruthy(); + expect(isValidFHIR(generatedAdverseEvent)).toBeTruthy(); }); test('minimal data passed into template should generate FHIR resource', () => { diff --git a/test/templates/fixtures/maximal-ctc-adverse-event-resource.json b/test/templates/fixtures/maximal-ctc-adverse-event-resource.json index cc4e50e1..1ea37982 100644 --- a/test/templates/fixtures/maximal-ctc-adverse-event-resource.json +++ b/test/templates/fixtures/maximal-ctc-adverse-event-resource.json @@ -64,9 +64,7 @@ { "url": "actor", "valueReference": { - "reference": { "reference": "urn:uuid:practitioner-id" - } } } ] From 3658f33f0dcc2d5b33e3777d03feedee623e0f4d Mon Sep 17 00:00:00 2001 From: julianxcarter Date: Thu, 16 Dec 2021 17:01:13 -0500 Subject: [PATCH 3/3] More specific error message per DM1 --- src/extractors/CSVCTCAdverseEventExtractor.js | 2 +- src/templates/CTCAdverseEventTemplate.js | 2 +- test/extractors/CSVCTCAdverseEventextractor.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/extractors/CSVCTCAdverseEventExtractor.js b/src/extractors/CSVCTCAdverseEventExtractor.js index b7824b8b..6fd941cc 100644 --- a/src/extractors/CSVCTCAdverseEventExtractor.js +++ b/src/extractors/CSVCTCAdverseEventExtractor.js @@ -41,7 +41,7 @@ function formatData(adverseEventData, patientId) { if (!(adverseEventCode && effectiveDate && grade)) { throw new Error('The adverse event is missing an expected attribute. Adverse event code, effective date, and grade are all required.'); } else if (functionCode && !actor) { - throw new Error('The adverse event is missing an expected attribute. Adverse event actor is a required element within the Participation extension'); + throw new Error('The adverse event is missing an expected attribute. Adverse event actor is a required element when a functionCode value is included.'); } const categoryCodes = category.split('|'); diff --git a/src/templates/CTCAdverseEventTemplate.js b/src/templates/CTCAdverseEventTemplate.js index aea607d4..02619cfb 100644 --- a/src/templates/CTCAdverseEventTemplate.js +++ b/src/templates/CTCAdverseEventTemplate.js @@ -142,7 +142,7 @@ function CTCAdverseEventTemplate({ } if (functionCode && !actor) { - throw Error('Trying to render an AdverseEventTemplate, but a required argument is missing; actor is a required value'); + throw Error('Trying to render an AdverseEventTemplate, but a required argument is missing; actor is a required value when functionCode is included'); } return { diff --git a/test/extractors/CSVCTCAdverseEventextractor.test.js b/test/extractors/CSVCTCAdverseEventextractor.test.js index aa2be9e2..352108e6 100644 --- a/test/extractors/CSVCTCAdverseEventextractor.test.js +++ b/test/extractors/CSVCTCAdverseEventextractor.test.js @@ -36,7 +36,7 @@ describe('CSVCTCAdverseEventExtractor', () => { test('should join data appropriately and throw errors when missing required properties', () => { const expectedErrorString = 'The adverse event is missing an expected attribute. Adverse event code, effective date, and grade are all required.'; const expectedCategoryErrorString = 'A category attribute on the adverse event is missing a corresponding categoryCodeSystem or categoryDisplayText value.'; - const expectedActorErrorString = 'The adverse event is missing an expected attribute. Adverse event actor is a required element within the Participation extension'; + const expectedActorErrorString = 'The adverse event is missing an expected attribute. Adverse event actor is a required element when a functionCode value is included.'; const localData = _.cloneDeep(exampleCTCCSVAdverseEventModuleResponse); const patientId = getPatientFromContext(MOCK_CONTEXT).id;