feat: configurable email alerts. Closes #217
Some checks failed
Build / Build-and-ng-test (pull_request) Successful in 4m42s
Build / Build-and-test-development (pull_request) Has been cancelled
Lighthouse Checks / lighthouse (pull_request) Has been cancelled

This commit is contained in:
2026-04-03 18:34:23 +01:00
parent 3be33186bc
commit 2ccf0d1100
5 changed files with 141 additions and 9 deletions

View File

@@ -0,0 +1,52 @@
/**
@file
@brief migration script to move from v7.0 to v7.6 of data controller
OPTIONAL CHANGE - upload additional data as placeholders for modifying the
default email message
**/
%let dclib=YOURDCLIB;
libname &dclib "/YOUR/DATACONTROLLER/LIBRARY/PATH";
proc sql;
insert into &dclib..mpe_config set
tx_from=%sysfunc(datetime())
,tx_to='31DEC9999:23:59:59'dt
,var_scope="DC_EMAIL"
,var_name="SUBMITTED_TEMPLATE"
,var_value='Dear user,'!!'0A'x!!'Please be advised that a change to table'
!!' &alert_lib..&alert_ds has been proposed by &from_user on the '
!!'&syshostname SAS server.'!!'0A'x!!'Reason provided: '
!!'%superq(SUBMITTED_TXT)'
!!'0A'x!!'This is an automated email by Data Controller for SAS. For '
!!'documentation, please visit https://docs.datacontroller.io'
,var_active=1
,var_desc='Template email, sent after submitting a change';
insert into &dclib..mpe_config set
tx_from=%sysfunc(datetime())
,tx_to='31DEC9999:23:59:59'dt
,var_scope="DC_EMAIL"
,var_name="APPROVED_TEMPLATE"
,var_value='Dear user,'!!'0A'x!!'Please be advised that a change to table'
!!' &alert_lib..&alert_ds has been approved by &from_user on the '
!!'&syshostname SAS server.'!!'0A'x!!'This is an automated email by Data'
!!' Controller for SAS. For documentation, please visit '
!!'https://docs.datacontroller.io'
,var_active=1
,var_desc='Template email, sent after approving a change';
insert into &dclib..mpe_config set
tx_from=%sysfunc(datetime())
,tx_to='31DEC9999:23:59:59'dt
,var_scope="DC_EMAIL"
,var_name="REJECTED_TEMPLATE"
,var_value='Dear user,'!!'0A'x!!'Please be advised that a change to table'
!!' &alert_lib..&alert_ds has been rejected by &from_user on the '
!!'&syshostname SAS server.'!!'0A'x!!'Reason provided: '
!!'%superq(REVIEW_REASON_TXT)'
!!'0A'x!!'This is an automated email by Data Controller for SAS. For '
!!'documentation, please visit https://docs.datacontroller.io'
,var_active=1
,var_desc='Template email, sent after rejecting a change';

View File

@@ -126,7 +126,13 @@ run;
filename __out email (&emails)
subject="Table &alert_lib..&alert_ds has been &alert_event";
filename __out "/tmp/test.txt";
data work.alertmessage;
set &mpelib..mpe_config;
where &dc_dttmtfmt. lt tx_to;
where also var_scope='DC_EMAIL' and var_name="&alert_event._TEMPLATE";
run;
%local SUBMITTED_TXT;
%if &alert_event=SUBMITTED %then %do;
data _null_;
@@ -136,30 +142,54 @@ filename __out email (&emails)
run;
data _null_;
File __out lrecl=32000;
length txt $2048;
%if %mf_getattrn(alertmessage,NLOBS)=0 %then %do;
put 'Dear user,';
put ' ';
put "Please be advised that a change to table &alert_lib..&alert_ds has "
"been proposed by &from_user on the '&syshostname' SAS server.";
"been proposed by &from_user on the &syshostname SAS server.";
put " ";
length txt $2048;
txt=symget('SUBMITTED_TXT');
put "Reason provided: " txt;
put " ";
put "This is an automated email by Data Controller for SAS. For "
"documentation, please visit https://docs.datacontroller.io";
%end;
%else %do;
/* take template from config table */
set work.alertmessage;
cnt=countw(var_value,'0A'x);
do i=1 to cnt;
txt=resolve(scan(var_value,i,'0A'x));
put txt /;
end;
%end;
run;
%end;
%else %if &alert_event=APPROVED %then %do;
/* there is no approval message */
data _null_;
File __out lrecl=32000;
length txt $2048;
%if %mf_getattrn(alertmessage,NLOBS)=0 %then %do;
/* fallback message */
put 'Dear user,';
put ' ';
put "Please be advised that a change to table &alert_lib..&alert_ds has "
"been approved by &from_user on the '&syshostname' SAS server.";
"been approved by &from_user on the &syshostname SAS server.";
put " ";
put "This is an automated email by Data Controller for SAS. For "
"documentation, please visit https://docs.datacontroller.io";
%end;
%else %do;
/* take template from config table */
set work.alertmessage;
cnt=countw(var_value,'0A'x);
do i=1 to cnt;
txt=resolve(scan(var_value,i,'0A'x));
put txt /;
end;
%end;
run;
%end;
%else %if &alert_event=REJECTED %then %do;
@@ -170,17 +200,29 @@ filename __out email (&emails)
run;
data _null_;
File __out lrecl=32000;
length txt $2048;
%if %mf_getattrn(alertmessage,NLOBS)=0 %then %do;
/* fallback message */
put 'Dear user,';
put ' ';
put "Please be advised that a change to table &alert_lib..&alert_ds has "
"been rejected by &from_user on the '&syshostname' SAS server.";
"been rejected by &from_user on the &syshostname SAS server.";
put " ";
length txt $2048;
txt=symget('REVIEW_REASON_TXT');
put "Reason provided: " txt;
put " ";
put "This is an automated email by Data Controller for SAS. For "
"documentation, please visit https://docs.datacontroller.io";
%end;
%else %do;
/* take template from config table */
set work.alertmessage;
cnt=countw(var_value,'0A'x);
do i=1 to cnt;
txt=resolve(scan(var_value,i,'0A'x));
put txt /;
end;
%end;
run;
%end;

View File

@@ -201,6 +201,44 @@ insert into &lib..mpe_config set
,var_value=' '
,var_active=1
,var_desc='Activation Key';
insert into &lib..mpe_config set
tx_from=0
,tx_to='31DEC9999:23:59:59'dt
,var_scope="DC_EMAIL"
,var_name="SUBMITTED_TEMPLATE"
,var_value='Dear user,'!!'0A'x!!'Please be advised that a change to table'
!!' &alert_lib..&alert_ds has been proposed by &from_user on the '
!!'&syshostname SAS server.'!!'0A'x!!'Reason provided: '
!!'%superq(SUBMITTED_TXT)'
!!'0A'x!!'This is an automated email by Data Controller for SAS. For '
!!'documentation, please visit https://docs.datacontroller.io'
,var_active=1
,var_desc='Template email, sent after submitting a change';
insert into &lib..mpe_config set
tx_from=0
,tx_to='31DEC9999:23:59:59'dt
,var_scope="DC_EMAIL"
,var_name="APPROVED_TEMPLATE"
,var_value='Dear user,'!!'0A'x!!'Please be advised that a change to table'
!!' &alert_lib..&alert_ds has been approved by &from_user on the '
!!'&syshostname SAS server.'!!'0A'x!!'This is an automated email by Data'
!!' Controller for SAS. For documentation, please visit '
!!'https://docs.datacontroller.io'
,var_active=1
,var_desc='Template email, sent after approving a change';
insert into &lib..mpe_config set
tx_from=0
,tx_to='31DEC9999:23:59:59'dt
,var_scope="DC_EMAIL"
,var_name="REJECTED_TEMPLATE"
,var_value='Dear user,'!!'0A'x!!'Please be advised that a change to table'
!!' &alert_lib..&alert_ds has been rejected by &from_user on the '
!!'&syshostname SAS server.'!!'0A'x!!'Reason provided: '
!!'%superq(REVIEW_REASON_TXT)'
!!'0A'x!!'This is an automated email by Data Controller for SAS. For '
!!'documentation, please visit https://docs.datacontroller.io'
,var_active=1
,var_desc='Template email, sent after rejecting a change';
insert into &lib..mpe_datadictionary set
@@ -213,7 +251,6 @@ insert into &lib..mpe_datadictionary set
,DD_RESPONSIBLE="&sysuserid"
,DD_SENSITIVITY="Low"
,tx_to='31DEC5999:23:59:59'dt;
insert into &lib..mpe_datadictionary set
tx_from=0
,DD_TYPE='TABLE'
@@ -224,7 +261,6 @@ insert into &lib..mpe_datadictionary set
,DD_RESPONSIBLE="&sysuserid"
,DD_SENSITIVITY="Low"
,tx_to='31DEC5999:23:59:59'dt;
insert into &lib..mpe_datadictionary set
tx_from=0
,DD_TYPE='COLUMN'
@@ -235,7 +271,6 @@ insert into &lib..mpe_datadictionary set
,DD_RESPONSIBLE="&sysuserid"
,DD_SENSITIVITY="Low"
,tx_to='31DEC5999:23:59:59'dt;
insert into &lib..mpe_datadictionary set
tx_from=0
,DD_TYPE='DIRECTORY'

View File

@@ -84,7 +84,8 @@ data work.reject;
REVIEW_STATUS_ID="REJECTED";
REVIEWED_BY_NM="&user";
REVIEWED_ON_DTTM=&now;
REVIEW_REASON_TXT=symget('STP_REASON');
/* sanitise message to prevent code injection */
REVIEW_REASON_TXT=compress(symget('STP_REASON'), '&%;');
run;
%mp_lockanytable(LOCK,

View File

@@ -51,6 +51,8 @@
data _null_;
set work.sascontroltable;
call symputx('action',action);
/* sanitise message to prevent code injection */
message=compress(message, '&%;');
call symputx('message',message);
libds=upcase(libds);
call symputx('orig_libds',libds);