diff --git a/RESTAPI/Functions/GENERATE_SWAGGER_FROM_DBML.sql b/RESTAPI/Functions/GENERATE_SWAGGER_FROM_DBML.sql
index a4aa364..5cb770c 100644
--- a/RESTAPI/Functions/GENERATE_SWAGGER_FROM_DBML.sql
+++ b/RESTAPI/Functions/GENERATE_SWAGGER_FROM_DBML.sql
@@ -1 +1,386 @@
-âÅã@×ÁãÈ@\ÓÉÂÓ@^@
%
%ÃÙÅÁãÅ@ÖÙ@ÙÅ×ÓÁÃÅ@ÆäÕÃãÉÖÕ@ÙÅâãÁ×ÉKÇÅÕÅÙÁãÅmâæÁÇÇÅÙmÆÙÖÔmÄÂÔÓ@M@
%ÉÕÁ××åÅÙ@åÁÙÃÈÁÙMñð]@k@
%ÉÕÁ××ÕÁÔÅ@åÁÙÃÈÁÙMñòø]@k@
%ÉÕÈÖâã@åÁÙÃÈÁÙMòõö]@k@
%ÉÕÂÁâÅ×ÁãÈ@åÁÙÃÈÁÙMòõö]@]@
%ÙÅãäÙÕâ@ÃÓÖÂMòñô÷ôøóöô÷]@@@
%ÓÁÕÇäÁÇÅ@âØÓ@
%â×ÅÃÉÆÉÃ@ÙÅâãÁ×ÉKÇÅÕÅÙÁãÅmâæÁÇÇÅÙmÆÙÖÔmÄÂÔÓ@
%ÕÖã@ÄÅãÅÙÔÉÕÉâãÉÃ@
%ÙÅÁÄâ@âØÓ@ÄÁãÁ@
%ÃÁÓÓÅÄ@ÖÕ@ÕäÓÓ@ÉÕ×äã@
%âÅã@Ö×ãÉÖÕ@@ÁÓæÂÓÒ@~@\ÁÓÓÙÅÁÄ@k@
%ÁÓæÃ×èÄãÁ@~@\Ö×ãÉÔÉéÅ@k@
%ÃÖÔÔÉã@~@\ÕÖÕÅ@k@
%ÄÅÃÙÅâäÓã@~@Móñk@óñk@ðð]@k@
%ÄèÕÄÆãÃÖÓ@~@\ÕÖ@k@
%ÄèÕäâÙ×ÙÆ@~@\äâÅÙ@k@
%âÙãâÅØ@~@\ÈÅç@@@
%ÂÅÇÉÕ@
%ÄÅÃÓÁÙÅ@åmÄÂÔÓ@ÃÓÖÂ@M@ò@Ç@]@^@
%ÄÅÃÓÁÙÅ@åmâæÁÇÇÅÙ@ÃÓÖÂ@M@ò@Ç@]@^@
%``@×¤““@£ˆ…@ÄÂÔÓ@
%âÅã@åmÄÂÔÓ@~@ÙÅâãÁ×É@K@ÇÅÕÅÙÁãÅmÄÂÔÓmåò@M@ÉÕÁ××åÅÙ@k@ÉÕÁ××ÕÁÔÅ@]@^@
%æÉãÈ@Ä@M@ÄÖÃ@]@Áâ@M@
%åÁÓäÅâ@çÔÓ×ÁÙâÅ@M@ÄÖÃäÔÅÕã@åmÄÂÔÓ@]@
%]@k@
%``@×™–‡™�”¢@M…•„—–‰•£¢]@
%×@Áâ@M@
%âÅÓÅÃã@ç@K@ÕÁÔÅ@Áâ@×ÇÔÕÁÔÅ@k@ç@K@×ÁãÈ@Áâ@ÙÅÓ×ÁãÈ@k@
%ä××ÅÙ@M@ç@K@ÔÅãÈÖÄ@]@Áâ@Èãã×ÔÅãÈÖÄ@k@ç@K@ÖÒ@Áâ@Èãã×âäÃÃÅââ@k@
%ç@K@ÆÁÉÓ@Áâ@Èãã×ÆÁÉÓ@k@ç@K@ÖäãæÙÁ×@Áâ@ÖäãæÙÁ×@
%ÆÙÖÔ@Ä@k@
%çÔÓãÁÂÓÅ@M@}[„a„‚”“a—™–‡™�”}@×ÁââÉÕÇ@Ä@K@ÄÖÃ@Áâ@„@
%ÃÖÓäÔÕâ@ÕÁÔÅ@åÁÙÃÈÁÙ@M@ñòø@]@×ÁãÈ@}|•�”…}@k@×ÁãÈ@åÁÙÃÈÁÙ@M@
%õñò@]@×ÁãÈ@}|™…¢£ä™‰×�£ˆã…”—“�£…}@k@
%ÔÅãÈÖÄ@åÁÙÃÈÁÙ@M@ñð@]@×ÁãÈ@}|™…¢£È££—Ù…˜¤…¢£Ô…£ˆ–„}@k@
%ÖÒ@åÁÙÃÈÁÙ@M@ó@]@×ÁãÈ@}|ˆ££—¢£�£¤¢–•¢¤ƒƒ…¢¢}@k@
%ÆÁÉÓ@åÁÙÃÈÁÙ@M@ó@]@×ÁãÈ@}|ˆ££—¢£�£¤¢–•†�‰“¤™…}@k@
%ÖäãæÙÁ×@åÁÙÃÈÁÙ@M@ñòø@]@×ÁãÈ@}|–¤£—¤£æ™�——…™É„…•£‰†‰…™}@]@
%Áâ@ç@
%]@k@
%``@×�™�”¢@M†™–”@L„�£�@KKK@™…¢£É•ç§§×�™�”~KKKn]@
%×ÙÔ@Áâ@M@
%âÅÓÅÃã@×ç@K@×ÇÔÕÁÔÅ@k@
%ÃÖÁÓÅâÃÅ@M@Äã@K@×ÁãÈÉÄ@k@Äã@K@ÆÖÙÔÉÄ@k@Äã@K@ØäÅÙèÉÄ@]@
%Áâ@×ÁÙÁÔmÕÁÔÅ@k@
%ÃÁâÅ@
%æÈÅÕ@Äã@K@×ÁãÈÉÄ@Éâ@ÕÖã@ÕäÓÓ@ãÈÅÕ@}—�£ˆ}@
%æÈÅÕ@Äã@K@ÆÖÙÔÉÄ@Éâ@ÕÖã@ÕäÓÓ@ãÈÅÕ@}†–™”Ä�£�}@
%æÈÅÕ@Äã@K@ØäÅÙèÉÄ@Éâ@ÕÖã@ÕäÓÓ@ãÈÅÕ@}˜¤…™¨}@
%ÅÕÄ@Áâ@×ÁÙÁÔmÉÕ@
%ÆÙÖÔ@Ä@k@
%çÔÓãÁÂÓÅ@M@}[„a„‚”“a—™–‡™�”}@×ÁââÉÕÇ@Ä@K@ÄÖÃ@Áâ@„@
%ÃÖÓäÔÕâ@×ÇÔÕÁÔÅ@åÁÙÃÈÁÙ@M@ñòø@]@×ÁãÈ@}|•�”…}@k@
%×ÇÔÕÖÄÅ@çÔÓ@×ÁãÈ@}K}@]@Áâ@×ç@
%ÓÅÆã@ÑÖÉÕ@çÔÓãÁÂÓÅ@M@}¢˜“a„�£�}@×ÁââÉÕÇ@×ç@K@×ÇÔÕÖÄÅ@
%ÃÖÓäÔÕâ@×ÁãÈÉÄ@åÁÙÃÈÁÙ@M@ñòø@]@×ÁãÈ@
%}|™…¢£É•×�£ˆ×�™�”}@k@
%ÆÖÙÔÉÄ@åÁÙÃÈÁÙ@M@ñòø@]@×ÁãÈ@}|™…¢£É•Æ–™”×�™�”}@k@
%ØäÅÙèÉÄ@åÁÙÃÈÁÙ@M@ñòø@]@×ÁãÈ@}|™…¢£É•Ø¤…™¨×�™�”}@]@Áâ@
%Äã@
%ÖÕ@ñ@~@ñ@
%æÈÅÙÅ@ÃÖÁÓÅâÃÅ@M@Äã@K@×ÁãÈÉÄ@k@Äã@K@ÆÖÙÔÉÄ@k@Äã@K@ØäÅÙèÉÄ@]@
%Éâ@ÕÖã@ÕäÓÓ@
%]@k@
%``@×�£ˆ@£–’…•¢@M•–•`¥�™‰�‚“…@¢…‡”…•£¢]k@�¤£–`‰‡•–™‰•‡@£ˆ…@�——@•�”…@
%ãÖÒ@Áâ@M@
%âÅÓÅÃã@×@K@×ÇÔÕÁÔÅ@k@â@K@ÖÙÄÉÕÁÓm×ÖâÉãÉÖÕ@Áâ@×Öâ@k@
%ÓÖæÅÙ@M@â@K@ÅÓÅÔÅÕã@]@Áâ@ÙÁæmãÖÒÅÕ@
%ÆÙÖÔ@×@k@ãÁÂÓÅ@M@
%âèâãÖÖÓâ@K@â×ÓÉã@M@×@K@ÙÅÓ×ÁãÈ@k@}a}@]@
%]@Áâ@â@
%æÈÅÙÅ@â@K@ÅÓÅÔÅÕã@Ln@}}@
%ÁÕÄ@â@K@ÅÓÅÔÅÕã@ÕÖã@ÓÉÒÅ@}ÀlÐ}@
%ÁÕÄ@ÓÖæÅÙ@M@â@K@ÅÓÅÔÅÕã@]@Ln@ÓÖæÅÙ@M@ÉÕÁ××ÕÁÔÅ@]@@``@„–•}£@ˆ�™„ƒ–„…@�•¨@�——^@¤¢…``@£ˆ…@—�™�”@
%]@k@
%``@Æ‰™¢£@£¦–@£–’…•¢@~@„…†�¤“£@£�‡@M…K‡Kk@ä¢…™¢@`@ÔÁ×ÉÃâ]@
%ãÖ×ò@Áâ@M@
%âÅÓÅÃã@×ÇÔÕÁÔÅ@k@ÙÁæmãÖÒÅÕ@k@ÙÖæmÕäÔÂÅÙ@M@]@ÖåÅÙ@M@
%×ÁÙãÉãÉÖÕ@Âè@×ÇÔÕÁÔÅ@
%ÖÙÄÅÙ@Âè@×Öâ@
%]@Áâ@ÙÕ@
%ÆÙÖÔ@ãÖÒ@
%]@k@
%ãÁÇÙÁæ@Á
\ No newline at end of file
+SET PATH *LIBL ; 
+
+CREATE OR REPLACE FUNCTION RESTAPI.GENERATE_SWAGGER_FROM_DBML ( 
+	INAPPVER VARCHAR(10) , 
+	INAPPNAME VARCHAR(128) , 
+	INHOST VARCHAR(256) , 
+	INBASEPATH VARCHAR(256) ) 
+	RETURNS CLOB(2147483647)   
+	LANGUAGE SQL 
+	SPECIFIC RESTAPI.GENERATE_SWAGGER_FROM_DBML 
+	NOT DETERMINISTIC 
+	READS SQL DATA 
+	CALLED ON NULL INPUT 
+	SET OPTION  ALWBLK = *ALLREAD , 
+	ALWCPYDTA = *OPTIMIZE , 
+	COMMIT = *NONE , 
+	DECRESULT = (31, 31, 00) , 
+	DYNDFTCOL = *NO , 
+	DYNUSRPRF = *USER , 
+	SRTSEQ = *HEX   
+	BEGIN 
+DECLARE V_DBML CLOB ( 2 G ) ; 
+DECLARE V_SWAGGER CLOB ( 2 G ) ; 
+-- Pull the DBML 
+SET V_DBML = RESTAPI . GENERATE_DBML_V2 ( INAPPVER , INAPPNAME ) ; 
+WITH D ( DOC ) AS ( 
+VALUES XMLPARSE ( DOCUMENT V_DBML ) 
+) , 
+-- Programs (endpoints) 
+P AS ( 
+SELECT X . NAME AS PGMNAME , X . PATH AS RELPATH , 
+UPPER ( X . METHOD ) AS HTTPMETHOD , X . OK AS HTTPSUCCESS , 
+X . FAIL AS HTTPFAIL , X . OUTWRAP AS OUTWRAP 
+FROM D , 
+XMLTABLE ( '$d/dbml/program' PASSING D . DOC AS "d" 
+COLUMNS NAME VARCHAR ( 128 ) PATH '@name' , PATH VARCHAR ( 
+512 ) PATH '@restUriPathTemplate' , 
+METHOD VARCHAR ( 10 ) PATH '@restHttpRequestMethod' , 
+OK VARCHAR ( 3 ) PATH '@httpstatusonsuccess' , 
+FAIL VARCHAR ( 3 ) PATH '@httpstatusonfailure' , 
+OUTWRAP VARCHAR ( 128 ) PATH '@outputWrapperIdentifier' ) 
+AS X 
+) , 
+-- Params (from <data ... restInXxxParam="...">) 
+PRM AS ( 
+SELECT PX . PGMNAME , 
+COALESCE ( DT . PATHID , DT . FORMID , DT . QUERYID ) 
+AS PARAM_NAME , 
+CASE 
+WHEN DT . PATHID IS NOT NULL THEN 'path' 
+WHEN DT . FORMID IS NOT NULL THEN 'formData' 
+WHEN DT . QUERYID IS NOT NULL THEN 'query' 
+END AS PARAM_IN 
+FROM D , 
+XMLTABLE ( '$d/dbml/program' PASSING D . DOC AS "d" 
+COLUMNS PGMNAME VARCHAR ( 128 ) PATH '@name' , 
+PGMNODE XML PATH '.' ) AS PX 
+LEFT JOIN XMLTABLE ( 'sql/data' PASSING PX . PGMNODE 
+COLUMNS PATHID VARCHAR ( 128 ) PATH 
+'@restInPathParam' , 
+FORMID VARCHAR ( 128 ) PATH '@restInFormParam' , 
+QUERYID VARCHAR ( 128 ) PATH '@restInQueryParam' ) AS 
+DT 
+ON 1 = 1 
+WHERE COALESCE ( DT . PATHID , DT . FORMID , DT . QUERYID ) 
+IS NOT NULL 
+) , 
+-- Path tokens (non-variable segments), auto-ignoring the app name 
+TOK AS ( 
+SELECT P . PGMNAME , S . ORDINAL_POSITION AS POS , 
+LOWER ( S . ELEMENT ) AS RAW_TOKEN 
+FROM P , TABLE ( 
+SYSTOOLS . SPLIT ( P . RELPATH , '/' ) 
+) AS S 
+WHERE S . ELEMENT <> '' 
+AND S . ELEMENT NOT LIKE '{%}' 
+AND LOWER ( S . ELEMENT ) <> LOWER ( INAPPNAME )  -- don't hardcode any app; use-- the param 
+) , 
+-- First two tokens = default tag (e.g., "Users - MAPICS") 
+TOP2 AS ( 
+SELECT PGMNAME , RAW_TOKEN , ROW_NUMBER ( ) OVER ( 
+PARTITION BY PGMNAME 
+ORDER BY POS 
+) AS RN 
+FROM TOK 
+) , 
+TAGRAW AS ( 
+SELECT T1 . PGMNAME , T1 . RAW_TOKEN AS RAW1 , T2 . RAW_TOKEN AS RAW2 
+FROM TOP2 T1 
+LEFT JOIN TOP2 T2 
+ON T2 . PGMNAME = T1 . PGMNAME 
+AND T2 . RN = 2 
+WHERE T1 . RN = 1 
+) , 
+-- Pretty display for any raw token using NAME_MAP, else TitleCase 
+NAME_FMT AS ( 
+SELECT X . RAW_TOKEN , 
+COALESCE ( 
+NM . DISPLAY , UPPER ( SUBSTR ( X . RAW_TOKEN , 1 , 1 ) ) CONCAT 
+CASE 
+WHEN 
+LENGTH ( X . RAW_TOKEN ) > 1 
+THEN 
+LOWER ( 
+REPLACE ( 
+REPLACE ( 
+SUBSTR ( X . RAW_TOKEN , 2 ) , '-' , ' ' 
+) , '_' , ' ' ) ) 
+ELSE '' 
+END ) AS DISPLAY 
+FROM ( 
+SELECT DISTINCT RAW_TOKEN 
+FROM TOK 
+) X 
+LEFT JOIN RESTAPI . NAME_MAP NM 
+ON NM . RAW_TOKEN = X . RAW_TOKEN 
+) , 
+-- Verb = last token if it's in VERB_MAP 
+LASTTOK AS ( 
+SELECT PGMNAME , MAX ( POS ) AS MAXPOS 
+FROM TOK 
+GROUP BY PGMNAME 
+) , 
+VERB AS ( 
+SELECT L . PGMNAME , T . RAW_TOKEN AS RAW_VERB , 
+VM . DISPLAY AS VERB_DISPLAY , 
+CASE 
+WHEN VM . RAW_VERB IS NULL THEN 0 
+ELSE 1 
+END AS IS_VERB , L . MAXPOS 
+FROM LASTTOK L 
+JOIN TOK T 
+ON T . PGMNAME = L . PGMNAME 
+AND T . POS = L . MAXPOS 
+LEFT JOIN RESTAPI . VERB_MAP VM 
+ON VM . RAW_VERB = T . RAW_TOKEN 
+) , 
+-- Object phrase = last one or two nouns *before* the verb (if verb recognized),-- 
+-- else last one or two overall 
+OBJ_SRC AS ( 
+SELECT T . PGMNAME , T . POS , T . RAW_TOKEN , V . IS_VERB , V . MAXPOS 
+FROM TOK T 
+LEFT JOIN VERB V 
+ON V . PGMNAME = T . PGMNAME 
+) , 
+OBJ_NOUNS AS ( 
+SELECT PGMNAME , RAW_TOKEN , ROW_NUMBER ( ) OVER ( 
+PARTITION BY PGMNAME 
+ORDER BY POS DESC 
+) AS RN_ALLDESC , ROW_NUMBER ( ) OVER ( 
+PARTITION BY PGMNAME 
+ORDER BY 
+CASE 
+WHEN IS_VERB = 1 THEN 
+CASE 
+WHEN POS < MAXPOS THEN POS 
+ELSE - 999999 
+END 
+ELSE POS 
+END DESC 
+) AS RN_BEFORE_VERB_DESC 
+FROM OBJ_SRC 
+) , 
+OBJ_PICK AS ( 
+-- Prefer nouns before verb (RN_BEFORE_VERB_DESC), fallback to overall (RN_ALLDE--SC) 
+SELECT O1 . PGMNAME , 
+COALESCE ( 
+NF1 . DISPLAY , 
+UPPER ( SUBSTR ( O1 . RAW_TOKEN , 1 , 1 ) ) CONCAT 
+LOWER ( SUBSTR ( O1 . RAW_TOKEN , 2 ) ) ) AS OBJ1 , 
+COALESCE ( 
+NF2 . DISPLAY , 
+UPPER ( SUBSTR ( O2 . RAW_TOKEN , 1 , 1 ) ) CONCAT 
+LOWER ( SUBSTR ( O2 . RAW_TOKEN , 2 ) ) ) AS OBJ2 
+FROM ( 
+SELECT * 
+FROM OBJ_NOUNS 
+WHERE RN_BEFORE_VERB_DESC = 1 
+) O1 
+LEFT JOIN ( 
+SELECT * 
+FROM OBJ_NOUNS 
+WHERE RN_BEFORE_VERB_DESC = 2 
+) O2 
+ON O2 . PGMNAME = O1 . PGMNAME 
+LEFT JOIN NAME_FMT NF1 
+ON NF1 . RAW_TOKEN = O1 . RAW_TOKEN 
+LEFT JOIN NAME_FMT NF2 
+ON NF2 . RAW_TOKEN = COALESCE ( O2 . RAW_TOKEN , '' ) 
+UNION ALL 
+SELECT O1 . PGMNAME , 
+COALESCE ( 
+NF1 . DISPLAY , 
+UPPER ( SUBSTR ( O1 . RAW_TOKEN , 1 , 1 ) ) CONCAT 
+LOWER ( SUBSTR ( O1 . RAW_TOKEN , 2 ) ) ) AS OBJ1 , 
+COALESCE ( 
+NF2 . DISPLAY , 
+UPPER ( SUBSTR ( O2 . RAW_TOKEN , 1 , 1 ) ) CONCAT 
+LOWER ( SUBSTR ( O2 . RAW_TOKEN , 2 ) ) ) AS OBJ2 
+FROM ( 
+SELECT * 
+FROM OBJ_NOUNS 
+WHERE RN_ALLDESC = 1 
+) O1 
+LEFT JOIN ( 
+SELECT * 
+FROM OBJ_NOUNS 
+WHERE RN_ALLDESC = 2 
+) O2 
+ON O2 . PGMNAME = O1 . PGMNAME 
+LEFT JOIN NAME_FMT NF1 
+ON NF1 . RAW_TOKEN = O1 . RAW_TOKEN 
+LEFT JOIN NAME_FMT NF2 
+ON NF2 . RAW_TOKEN = COALESCE ( O2 . RAW_TOKEN , '' ) 
+WHERE NOT EXISTS ( 
+SELECT 1 
+FROM OBJ_NOUNS Z 
+WHERE Z . PGMNAME = O1 . PGMNAME 
+AND Z . RN_BEFORE_VERB_DESC = 1 ) 
+) , 
+-- Derived tag ("Seg1 - Seg2") using display names 
+TAG_DERIVED AS ( 
+SELECT TR . PGMNAME , 
+CASE 
+WHEN 
+NF2 . DISPLAY IS NOT NULL 
+THEN NF1 . DISPLAY CONCAT ' - ' CONCAT NF2 . DISPLAY 
+ELSE NF1 . DISPLAY 
+END AS TAG_NAME 
+FROM TAGRAW TR 
+LEFT JOIN NAME_FMT NF1 
+ON NF1 . RAW_TOKEN = TR . RAW1 
+LEFT JOIN NAME_FMT NF2 
+ON NF2 . RAW_TOKEN = TR . RAW2 
+) , 
+-- Summaries: "{VerbDisplay or 'Execute'} {OBJ1 [OBJ2]} [for param1, param2 ...]--" 
+PATH_PARAMS AS ( 
+SELECT PGMNAME , 
+LISTAGG ( 
+PARAM_NAME , ', ' ) WITHIN GROUP ( ORDER BY PARAM_NAME ) 
+AS PATH_PARAM_LIST 
+FROM PRM 
+WHERE PARAM_IN = 'path' 
+GROUP BY PGMNAME 
+) , 
+SUMMARY_DERIVED AS ( 
+SELECT P . PGMNAME , 
+RTRIM ( 
+COALESCE ( V . VERB_DISPLAY , 'Execute' ) CONCAT ' ' 
+CONCAT 
+CASE 
+WHEN 
+OP . OBJ2 IS NOT NULL 
+THEN OP . OBJ2 CONCAT ' ' CONCAT OP . OBJ1 
+ELSE OP . OBJ1 
+END CONCAT 
+COALESCE ( ' for ' CONCAT PP . PATH_PARAM_LIST , '' ) ) 
+AS SUMMARY 
+FROM P 
+LEFT JOIN VERB V 
+ON V . PGMNAME = P . PGMNAME 
+LEFT JOIN OBJ_PICK OP 
+ON OP . PGMNAME = P . PGMNAME 
+LEFT JOIN PATH_PARAMS PP 
+ON PP . PGMNAME = P . PGMNAME 
+) , 
+-- Apply optional per-program overrides 
+META AS ( 
+SELECT P . PGMNAME , 
+COALESCE ( O . TAG_NAME , TD . TAG_NAME ) AS TAG_NAME , 
+COALESCE ( O . SUMMARY , SD . SUMMARY ) AS SUMMARY 
+FROM P 
+LEFT JOIN TAG_DERIVED TD 
+ON TD . PGMNAME = P . PGMNAME 
+LEFT JOIN SUMMARY_DERIVED SD 
+ON SD . PGMNAME = P . PGMNAME 
+LEFT JOIN RESTAPI . SWAGGER_OVERRIDES O 
+ON O . APPVER = INAPPVER 
+AND O . APPNAME = INAPPNAME 
+AND O . PGMNAME = P . PGMNAME 
+) , 
+-- Parameters JSON per program 
+PARMS AS ( 
+SELECT PGMNAME , 
+'[' CONCAT 
+COALESCE ( 
+LISTAGG ( 
+'{"name":"' CONCAT PARAM_NAME CONCAT 
+'","in":"' CONCAT PARAM_IN CONCAT 
+'","required":true,"type":"string"}' , ',' ) , 
+'' ) CONCAT ']' AS PARAMS_JSON 
+FROM PRM 
+GROUP BY PGMNAME 
+) , 
+-- Path method JSON per program 
+PATHS AS ( 
+SELECT '/v1' CONCAT RELPATH AS FULLPATH , 
+JSON_OBJECT ( 
+LOWER ( HTTPMETHOD ) VALUE JSON_OBJECT ( 
+'tags' VALUE JSON_ARRAY ( M . TAG_NAME ) , 
+'summary' VALUE M . SUMMARY , 
+'operationId' VALUE M . PGMNAME , 
+'consumes' VALUE JSON_ARRAY ( '*/*' ) , 
+'produces' VALUE JSON_ARRAY ( 'application/json' ) , 
+'parameters' VALUE JSON_ARRAY ( PR . PARAMS_JSON ) , 
+'responses' VALUE JSON_OBJECT ( 
+HTTPSUCCESS VALUE JSON_OBJECT ( 
+'description' VALUE 'Successful operation' 
+) , HTTPFAIL VALUE JSON_OBJECT ( 
+'description' VALUE 'Operation failure' , 
+'schema' VALUE JSON_OBJECT ( 
+'$ref' VALUE '#/definitions/' || 
+OUTWRAP 
+) 
+) 
+) 
+) 
+) AS METHOD_JSON 
+FROM P 
+LEFT JOIN META M 
+ON M . PGMNAME = P . PGMNAME 
+LEFT JOIN PARMS PR 
+ON PR . PGMNAME = P . PGMNAME 
+) , 
+PATHS_JSON AS ( 
+SELECT 
+'{' CONCAT 
+LISTAGG ( 
+'"' CONCAT FULLPATH CONCAT '": ' CONCAT METHOD_JSON , 
+',' ) CONCAT '}' AS J 
+FROM PATHS 
+) , 
+TAGS_JSON AS ( 
+SELECT 
+'[' CONCAT 
+LISTAGG ( 
+'{"name":"' CONCAT TAG_NAME CONCAT 
+'","description":"Operations for ' CONCAT TAG_NAME 
+CONCAT '"}' , ',' ) CONCAT ']' AS J 
+FROM ( 
+SELECT DISTINCT TAG_NAME 
+FROM META 
+) 
+) , 
+DEFS_JSON AS ( 
+SELECT 
+'{' CONCAT 
+'"SQLException":{"type":"object","properties":{"SQLState":{"type":"string","maxLength":5},"errorCode":{"type":"integer"},"message":{"type":"string"}}},' 
+CONCAT 
+'"SQLStateInfo":{"type":"object","properties":{"rowsAffectedCounts":{"type":"string"},"SQLError":{"$ref":"#/definitions/SQLException"},"SQLWarnings":{"type":"array","items":{"$ref":"#/definitions/SQLException"}}}},' 
+CONCAT 
+LISTAGG ( 
+'"' CONCAT OUTWRAP CONCAT 
+'":{"type":"object","properties":{"SQLStateInfo":{"$ref":"#/definitions/SQLStateInfo"}}}' 
+, ',' ) CONCAT '}' AS J 
+FROM ( 
+SELECT DISTINCT OUTWRAP 
+FROM P 
+) 
+) 
+SELECT '{' CONCAT '"swagger":"2.0",' CONCAT '"info":{"title":"' 
+CONCAT UPPER ( SUBSTR ( INAPPNAME , 1 , 1 ) ) CONCAT 
+LOWER ( SUBSTR ( INAPPNAME , 2 ) ) CONCAT ' APIs",' CONCAT 
+'"description":"APIs available for ' CONCAT INAPPNAME CONCAT 
+'",' CONCAT '"version":"1.0.0"},' CONCAT '"host":"' CONCAT 
+INHOST CONCAT '",' CONCAT '"schemes":["http"],' CONCAT 
+'"basePath":"' CONCAT INBASEPATH CONCAT '",' CONCAT '"tags":' 
+CONCAT COALESCE ( ( SELECT J 
+FROM TAGS_JSON ) , '[]' ) CONCAT ',' CONCAT 
+'"definitions":' CONCAT ( SELECT J 
+FROM DEFS_JSON ) CONCAT ',' CONCAT '"paths":' CONCAT 
+( SELECT J 
+FROM PATHS_JSON ) CONCAT '}' 
+INTO V_SWAGGER 
+FROM SYSIBM . SYSDUMMY1 ; 
+RETURN V_SWAGGER ; 
+END  ; 
+
+GRANT ALTER , EXECUTE   
+ON SPECIFIC FUNCTION RESTAPI.GENERATE_SWAGGER_FROM_DBML 
+TO AMAPICS WITH GRANT OPTION ; 
+
+GRANT EXECUTE   
+ON SPECIFIC FUNCTION RESTAPI.GENERATE_SWAGGER_FROM_DBML 
+TO PUBLIC ; 
+
