/** 
 * <feature scope="SanteDB.Persistence.Data.ADO" id="0-001" name="Core Schema" invariantName="FirebirdSQL">
 *	<summary>Install Schema</summary>
 *	<remarks>Installs the core SanteDB schema including tables, views, and sequences needed for execution</remarks>
 *	<isInstalled mustSucceed="true">select true from rdb$database where exists (select 1 from rdb$relations where rdb$relation_name = 'SEC_USR_TBL');</isInstalled>
 *	<url>https://help.santesuite.org/ops/santedb/rim</url>
 * </feature>
 */

-- CREATE DOMAIN FOR BOOLEAN
-- MIGRATE:OPTIONAL
CREATE DOMAIN UUID AS CHAR(16);
--#!
ALTER CHARACTER SET NONE SET DEFAULT COLLATION NONE;
--#!

-- SECURITY USER CLASS CODES. THESE ARE USED TO IDENTIFY THE USER CLASSES AND ARE USED
-- TO DIFFERENTIATE THE CLASSES OF USERS
CREATE TABLE SEC_USR_CLS_CDTBL (
    CLS_ID UUID NOT NULL ,
    MNEMONIC VARCHAR(32) NOT NULL,
    CONSTRAINT PK_SEC_USR_CLS_CDTBL PRIMARY KEY (CLS_ID)
);
--#!


-- SECURITY PROVENANCE TABLE
-- THIS TABLE IS USED TO RECORD THE PROVENANCE OF AN OBJECT AT THE TIME OF CREATION / UPDATION / ETC.as
CREATE TABLE SEC_PROV_TBL (
	PROV_ID UUID NOT NULL, -- THE ID OF THE PROVENANCE EVENT
	USR_ID UUID, -- THE USER IDENTITY OF THE EVENT
	DEV_ID UUID, -- THE DEVICE ID OF THE EVENT
	APP_ID UUID NOT NULL, -- THE APPLICATION THE USER OR DEVICE WAS USING
	SES_ID UUID, -- THE SESSION OF THE EVENT IF APPLICABLE - NB THE SESSION MECHANISM MAY NOT BE IN THIS DATABASE SO THERE IS NO FK TO THE SESSION IDENTIFIER
	EST_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL , -- THE TIMESTAMP WHEN THE TRANSACTION BEGAN ON THE SERVER (REGARDLESS OF WHEN THE DEVICE SAID THE CREATION TIME WAS)
	EXT_ID UUID,
	EXT_TYP CHAR(1),
	CONSTRAINT PK_SEC_PROV_TBL PRIMARY KEY (PROV_ID),
	CONSTRAINT CK_SEC_PROV_ORGN CHECK (USR_ID IS NOT NULL OR DEV_ID IS NOT NULL OR SES_ID IS NOT NULL)
);
--#!

-- SECURITY USER TABLE IS USED BY THE SECURITY SUBSYSTEM AND IS OFTEN
-- LINKED TO A USER ENTITY, DEVICE, OR OTHER ENTITY IN THE CLINICAL 
-- DATA MODEL
CREATE TABLE SEC_USR_TBL (
    USR_ID UUID NOT NULL, -- THE UNIQUE IDENTIFIER FOR THE USER
    CLS_ID UUID DEFAULT x'33932B426F4B465988496ACA54139D8E' NOT NULL, -- THE USER CLASSIFICATION
    USR_NAME VARCHAR(64) NOT NULL, -- THE USERNAME OF THE USER
    EMAIL VARCHAR(196), -- THE EMAIL ADDRESS OF THE USER
    EMAIL_CNF BOOLEAN DEFAULT FALSE NOT NULL, -- WHETHER THE USERS EMAIL ADDRESS HAS BEEN CONFIRMED
    PHN_NUM VARCHAR(128), -- THE PRIMARY CONTACT NUMBER FOR SECURITY PURPOSES
    PHN_CNF BOOLEAN DEFAULT FALSE NOT NULL, -- INDICATES WHETHER THE SECURITY PHONE NUMBER HAS BEEN CONFIRMED
    TFA_ENABLED BOOLEAN DEFAULT FALSE NOT NULL, -- INDICATES WHETHER TWO FACTOR AUTHENTICATION IS REQUIRED FOR THIS ACCOUNT
    LOCKED TIMESTAMP, -- TRUE IF THE ACCOUNT HAS BEEN LOCKED
    PASSWD VARCHAR(128) NOT NULL, -- THE PASSWORD OF THE USER
    SEC_STMP VARCHAR(128) NOT NULL, -- THE SECURITY STAMP WHICH IS USED AS A VERIFICATION THAT THE USER INFORMATION HAS CHANGED
    FAIL_LOGIN INT DEFAULT 0 NOT NULL, -- THE NUMBER OF TIMES THAT THE USER HAS FAILED TO LOGIN
    LAST_LOGIN_UTC TIMESTAMP, -- THE LAST TIME THAT THE USER SUCCESSFULLY LOGGED IN
    CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT THE USER ACCOUNT WAS CREATED
    CRT_PROV_ID UUID, -- THE USER WHICH CREATED THIS USER ACCOUNT
    OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE USER RECORD WAS OBSOLETED
    OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THIS USER ACCOUNT
    UPD_UTC TIMESTAMP, -- THE TIME WHEN THIS USER RECORD WAS LAST UPDATED
    UPD_PROV_ID UUID, -- THE USER ID WHICH WAS RESPONSIBLE FOR THE UPDATE
    CONSTRAINT PK_SEC_USR PRIMARY KEY (USR_ID),
    CONSTRAINT FK_SEC_USR_OBSLT_PROV_ID FOREIGN KEY(OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT FK_SEC_USR_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT FK_SEC_USR_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT CK_SEC_USR_OBSLT_USR CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
    CONSTRAINT CK_SEC_USR_UPD_USR CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL),
    CONSTRAINT FK_SEC_USR_USR_CLS_ID FOREIGN KEY (CLS_ID) REFERENCES SEC_USR_CLS_CDTBL(CLS_ID)
);
--#!

-- CREATE UNIQUE INDEX ON THE LOWER USER NAME
CREATE UNIQUE INDEX SEC_USR_NAME_IDX ON SEC_USR_TBL COMPUTED BY (LOWER(USR_NAME));
--#!
CREATE INDEX SEC_USR_NAME_PWD_IDX ON SEC_USR_TBL(USR_NAME, PASSWD);
--#!

-- SECURITY USER CLAIMS
CREATE TABLE SEC_USR_CLM_TBL (
    CLM_ID UUID NOT NULL, -- UNIQUE ID FOR THE CLAIM
    USR_ID UUID NOT NULL, -- THE USER TO WHICH THE CLAIM BELONGS
    CLM_TYP VARCHAR(128) NOT NULL, -- THE TYPE OF CLAIM
    CLM_VAL VARCHAR(128) NOT NULL, -- THE VALUE OF THE CLAIM
    CONSTRAINT PK_SEC_USR_CLM_TBL PRIMARY KEY (CLM_ID),
    CONSTRAINT FK_SEC_USR_CLM_SEC_USR_TBL FOREIGN KEY (USR_ID) REFERENCES SEC_USR_TBL(USR_ID)
);
--#!

CREATE INDEX SEC_USR_CLM_USR_ID_IDX ON SEC_USR_CLM_TBL(USR_ID);
--#!

-- LINK TO EXTERNAL IDENTIFIER TOKENS
CREATE TABLE SEC_USR_EXTRN_LGN_TBL (
    LGN_PVDR VARCHAR(128) NOT NULL, -- THE PROVIDER (GMAIL, LIVE, ETC.)
    PVD_KEY VARCHAR(128) NOT NULL, -- THE PROVIDER KEY
    USR_ID UUID NOT NULL, -- THE USER TO WHICH THE LOGIN PROVIDES
    CONSTRAINT PK_SEC_USR_EXTRN_LGN PRIMARY KEY (LGN_PVDR, USR_ID),
    CONSTRAINT FK_SEC_USR_EXTRN_LGN_USR_ID FOREIGN KEY (USR_ID) REFERENCES SEC_USR_TBL(USR_ID)
);
--#!

-- SECURITY ROLES ARE USED TO GROU POLICIES AND ACTIONS AS WELL AS ACCESS TO 
-- PARTICULAR POS APPLICATIONS BASED ON POLICY
CREATE TABLE SEC_ROL_TBL (
    ROL_ID UUID NOT NULL, -- UNIQUE ID OF THE ROLE
    ROL_NAME VARCHAR(196) NOT NULL, -- THE NAME OF THE ROLE
    DESCR VARCHAR(196), -- THE DESCRIPTION OF THE ROLE
    CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE CREATION TIME OF THE ROLE
    CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATE THE ROLE
    OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE ROLE WAS OBSOLETED
    OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE ROLE
    UPD_UTC TIMESTAMP, -- THE TIME WHEN THE ROLE WAS UPDATED
    UPD_PROV_ID UUID, -- THE USER WHICH UPDATED THE ROLE
    CONSTRAINT PK_SEC_ROL_TBL PRIMARY KEY (ROL_ID),
    CONSTRAINT FK_SEC_ROL_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT FK_SEC_ROL_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT FK_SEC_ROL_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT CK_SEC_ROL_OBSLT_USR CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
    CONSTRAINT CK_SEC_ROL_UPD_USR CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!

-- UNIQUE INDEX ON NAME
CREATE UNIQUE INDEX SEC_ROL_ROL_NAME_IDX ON SEC_ROL_TBL COMPUTED BY (LOWER(ROL_NAME));
--#!

-- SECURITY USER TO ROLE ASSOCIATION
CREATE TABLE SEC_USR_ROL_ASSOC_TBL (
    USR_ID UUID NOT NULL, -- THE IDENTIFIER OF THE USER
    ROL_ID UUID NOT NULL, -- THE IDENTIFIER OF THE ROLE
    CONSTRAINT PK_SEC_ROL_ASSOC_TBL PRIMARY KEY (USR_ID, ROL_ID),
    CONSTRAINT FK_SEC_ROL_ASSOC_USR_ID FOREIGN KEY (USR_ID) REFERENCES SEC_USR_TBL(USR_ID),
    CONSTRAINT FK_SEC_ROL_ASSOC_ROL_ID FOREIGN KEY (ROL_ID) REFERENCES SEC_ROL_TBL(ROL_ID)
);
--#!

CREATE INDEX SEC_USR_ROL_ASSOC_USR_ID_IDX ON SEC_USR_ROL_ASSOC_TBL(USR_ID);
--#!
CREATE INDEX SEC_USR_ROL_ASSOC_ROL_ID_IDX ON SEC_USR_ROL_ASSOC_TBL(ROL_ID);
--#!

-- POLICY TABLE (SEE OIZ DESIGN DOCUMENTATION)
CREATE TABLE SEC_POL_TBL (
    POL_ID UUID NOT NULL, -- THE UNIQUE IDENTIFIER OF THE POLICY
    OID VARCHAR(128) NOT NULL, -- THE OID FOR THE POLICY
    POL_NAME VARCHAR(64) NOT NULL, -- THE NAME OF THE POLICY
    HDLR_CLS VARCHAR(196), -- THE HANDLER CLASS
    IS_PUB BOOLEAN DEFAULT FALSE NOT NULL, -- WHETHER THE POLICY IS INTERNAL OR SHOULD BE DISCLOSED
    IS_ELEV BOOLEAN DEFAULT FALSE NOT NULL, -- WHETHER THE POLICY CAN BE ELEVATED OVER
    CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE DATE THE POLICY WAS CREATED
    CRT_PROV_ID UUID NOT NULL, -- THE USER THAT CREATED THE ROLE
    OBSLT_UTC TIMESTAMP, -- THE DATE THE POLICY WAS OBSOLETED
    OBSLT_PROV_ID UUID, -- THE OBSOLTION USER
    CONSTRAINT PK_SEC_POL_TBL PRIMARY KEY (POL_ID),
    CONSTRAINT FK_SEC_POL_CRT_UTC FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
    CONSTRAINT FK_SEC_POL_OBSLT_UTC FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID)
);
--#!

CREATE UNIQUE INDEX SEC_OID_IDX ON SEC_POL_TBL(OID);
--#!

-- SECURITY ROLE TO POLICY ASSOCIATIVE ENTITY
CREATE TABLE SEC_ROL_POL_ASSOC_TBL (
	SEC_POL_INST_ID UUID NOT NULL, -- UNIQUE IDENTIFIER
	ROL_ID UUID NOT NULL, -- THE ROLE TO WHICH THE POLICY APPLIES
	POL_ID UUID NOT NULL, -- POLICY IDENTIFIER
	POL_ACT INT DEFAULT 0 NOT NULL CHECK (POL_ACT < 3), -- POLICY ACTIONS
	CONSTRAINT PK_SEC_POL_ROL_ASSOC PRIMARY KEY (SEC_POL_INST_ID),
	CONSTRAINT FK_SEC_POL_ROL_ASSOC_ROL_ID FOREIGN KEY (ROL_ID) REFERENCES SEC_ROL_TBL(ROL_ID),
	CONSTRAINT FK_SEC_POL_ROL_ASSOC_POL_ID FOREIGN KEY (POL_ID) REFERENCES SEC_POL_TBL(POL_ID)
);
--#!

CREATE INDEX SEC_POL_ROL_ASSOC_ROL_ID_IDX ON SEC_ROL_POL_ASSOC_TBL(ROL_ID);
--#!
CREATE UNIQUE INDEX SEC_POL_ROL_ASSOC_POL_ROL_IDX ON SEC_ROL_POL_ASSOC_TBL(ROL_ID, POL_ID);
--#!
CREATE INDEX SEC_ROL_POL_ASSOC_POL_IDX ON SEC_ROL_POL_ASSOC_TBL(POL_ID);
--#!

-- SECURITY DEVICE WHICH IS HOW DEVICES AUTHENTICATE THEMSELVES
CREATE TABLE SEC_DEV_TBL (
	DEV_ID UUID NOT NULL, -- UNIQUE IDENTIFIER FOR THE DEVICE
	DEV_SCRT VARCHAR(64) NOT NULL, -- THE SECRET OF THE DEVICE (EX: X509 THUMB)
	DEV_PUB_ID VARCHAR(64) NOT NULL, -- THE PUBLIC IDENTIIFER
	LOCKED TIMESTAMP, -- LOCKOUT PERIOD
	FAIL_AUTH INTEGER, -- FAILED AUTHENTICATION ATTEMPTS
	LAST_AUTH_UTC TIMESTAMP, -- THE LAST AUTHETNICATION TIME
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE DATE THE DEVICE WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED
	UPD_UTC TIMESTAMP, -- THE DATE THE DEVICE WAS CREATED
	UPD_PROV_ID UUID, -- THE USER WHICH UPDATED THE DEVICE
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE DEVICE WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETD THE DEVICE
	RPLC_DEV_ID UUID, -- THE DEVICE THAT THIS DEVICE REPLACES.
	CONSTRAINT PK_SEC_DEV_TBL PRIMARY KEY (DEV_ID),
	CONSTRAINT FK_SEC_DEV_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_SEC_DEV_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_SEC_DEV_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_SEC_DEV_RPLC_DEV_ID FOREIGN KEY (RPLC_DEV_ID) REFERENCES SEC_DEV_TBL(DEV_ID),
	CONSTRAINT CK_SEC_DEV_UPD_USR CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL),
	CONSTRAINT CK_SEC_DEV_OBSLT_USR CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL)
);
--#!

CREATE UNIQUE INDEX SEC_DEV_PUB_ID_IDX ON SEC_DEV_TBL(DEV_PUB_ID);
--#!
CREATE UNIQUE INDEX SEC_DEV_SCRT_IDX ON SEC_DEV_TBL(DEV_SCRT);
--#!

-- SECURITY APPLICATION WHICH IS HOW APPLICATIONS AUTHENTICATE THEMSELVES
CREATE TABLE SEC_APP_TBL (
	APP_ID UUID NOT NULL, -- UNIQUE IDENTIIFER FOR THE DEV
	APP_PUB_ID VARCHAR(64) NOT NULL, -- THE PUBLIC IDENTIFIER FOR THE APP
	APP_SCRT VARCHAR(64) NOT NULL, -- THE APPLICATION SECRET
	LOCKED TIMESTAMP, -- LOCKOUT PERIOD
	FAIL_AUTH INTEGER, -- FAILED AUTHENTICATION ATTEMPTS
	LAST_AUTH_UTC TIMESTAMP, -- THE LAST AUTHETNICATION TIME
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE CREATION TIME OF THE APP
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH IS RESPONSIBLE FOR THE CREATION
	UPD_UTC TIMESTAMP, -- THE CREATION TIME OF THE APP
	UPD_PROV_ID UUID, -- THE USER WHICH IS RESPONSIBLE FOR THE CREATION OF THE APP
	OBSLT_UTC TIMESTAMP, -- OBSOLETION TIME
	OBSLT_PROV_ID UUID, -- THE OBSOLETION USER
	RPLC_APP_ID UUID, -- THE APPLICATION WICH THIS APPLICATION REPLACES
	CONSTRAINT PK_SEC_APP_TBL PRIMARY KEY (APP_ID),
	CONSTRAINT FK_SEC_APP_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_SEC_APP_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_SEC_APP_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_SEC_APP_RPLC_APP_ID FOREIGN KEY (RPLC_APP_ID) REFERENCES SEC_APP_TBL(APP_ID),
	CONSTRAINT CK_SEC_APP_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL),
	CONSTRAINT CK_SEC_APP_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL)
);
--#!

CREATE UNIQUE INDEX SEC_APP_APP_PUB_ID_IDX ON SEC_APP_TBL(APP_PUB_ID);
--#!
CREATE INDEX SEC_APP_APP_SCRT_IDX ON SEC_APP_TBL(APP_SCRT);
--#!

-- SECURITY DEVICE TO POLICY ASSOC
CREATE TABLE SEC_DEV_POL_ASSOC_TBL (
	SEC_POL_INST_ID UUID NOT NULL, -- CHAR(16) FOR THE INSTANCES
	DEV_ID UUID NOT NULL, -- DEVICE IDENTIFIER TO WHICH THE POLICY APPLIES
	POL_ID UUID NOT NULL, -- POLICY IDENTIIFER TO WHICH THE POLICY APPLIES
	POL_ACT INT NOT NULL CHECK (POL_ACT < 3), -- POLICY ACTION EITHER GRANT, DENY OR ELEVATE
	CONSTRAINT PK_SEC_DEV_POL_ASSOC_TBL PRIMARY KEY (SEC_POL_INST_ID), 
	CONSTRAINT FK_SEC_DEV_POL_ASSOC_DEV_ID FOREIGN KEY (DEV_ID) REFERENCES SEC_DEV_TBL(DEV_ID),
	CONSTRAINT FK_SEC_DEV_POL_ASSOC_POL_ID FOREIGN KEY (POL_ID) REFERENCES SEC_POL_TBL(POL_ID)
);
--#!

CREATE INDEX SEC_DEV_POL_ASSOC_DEV_ID_IDX ON SEC_DEV_POL_ASSOC_TBL(DEV_ID);
--#!

-- SECURITY APPLICATION TO POLICY INSTANCE ASSOCIATION
CREATE TABLE SEC_APP_POL_ASSOC_TBL (
	SEC_POL_INST_ID UUID NOT NULL, -- CHAR(16) FOR THE INSTANCE
	APP_ID UUID NOT NULL, -- APPLICATION IDENTIFIER TO WHICH THE POLICY APPLIES
	POL_ID UUID NOT NULL, -- THE POLICY TO WHICH THE POLICY INSTANCE APPLIES
	POL_ACT INT CHECK (POL_ACT < 3) NOT NULL, -- POLICY ACTION
	CONSTRAINT PK_SEC_APP_POL_ASSOC_TBL PRIMARY KEY (SEC_POL_INST_ID),
	CONSTRAINT FK_SEC_APP_POL_ASSOC_APP_ID FOREIGN KEY (APP_ID) REFERENCES SEC_APP_TBL(APP_ID),
	CONSTRAINT FK_SEC_APP_POL_ASSOC_POL_ID FOREIGN KEY (POL_ID) REFERENCES SEC_POL_TBL(POL_ID)
);
--#!

CREATE INDEX SEC_APP_POL_ASSOC_APP_ID_IDX ON SEC_APP_POL_ASSOC_TBL(APP_ID);
--#!

-- PHONETIC ALGORITHMS TABLE
CREATE TABLE PHON_ALG_TBL (
	ALG_ID UUID NOT NULL, -- UNIQUE IDENTIFIER FOR THE ALGORITHM
	ALG_NAME VARCHAR(32) NOT NULL, -- NAME OF THE ALGORITHM
	HDLR_CLS VARCHAR(196), -- THE HANDLER CLASS WHICH CAN GENERATE THE ALGORITHM CODES
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE CREATION TIME
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED THE ALGORITHM
	UPD_UTC TIMESTAMP, -- THE UPDATED TIME FOR THE ALGORITHM
	UPD_PROV_ID UUID, -- THE USER WHICH UPDATED THE ALGORITHM
	OBSLT_UTC TIMESTAMP, -- THE TIMESTAMP OF THE OBSOLETION
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE ALGORITHM
	CONSTRAINT PK_PHON_ALG_TBL PRIMARY KEY (ALG_ID),
	CONSTRAINT FK_PHON_ALG_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_PHON_ALG_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_PHON_ALG_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_PHON_ALG_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_PHON_ALG_UPD_USR CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!

CREATE INDEX PHON_ALG_NAME_IDX ON PHON_ALG_TBL(ALG_NAME);
--#!

CREATE SEQUENCE PHON_VAL_SEQ;
--#!

-- PHONETIC VALUES TABLE ASSOCIATES STRINGS WITH VALUES
CREATE TABLE PHON_VAL_TBL (
	VAL_SEQ_ID INTEGER NOT NULL, -- UNIQUE IDENTIFIER FORHTE VALUE
	VAL VARCHAR(64) NOT NULL, -- THE VALUE OF THE CODE IN HUMAN READABLE FORM
	PHON_CS VARCHAR(32), -- THE PHONETIC CODE OF THE VALUE
	ALG_ID UUID NOT NULL, -- THE PHONETIC ALGORITHM USED TO GENERATE THE CODE
	CONSTRAINT PK_PHON_VAL_TBL PRIMARY KEY (VAL_SEQ_ID),
	CONSTRAINT FK_PHON_VAL_ALG_ID FOREIGN KEY (ALG_ID) REFERENCES PHON_ALG_TBL(ALG_ID)
);
--#!

CREATE TRIGGER TG_PHON_VAL_TBL_SEQ FOR PHON_VAL_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.VAL_SEQ_ID = NEXT VALUE FOR PHON_VAL_SEQ;
END;
--#!

CREATE INDEX PHON_VAL_PHON_CS_IDX ON PHON_VAL_TBL(PHON_CS);
--#!
CREATE INDEX PHON_VAL_PHON_VAL_IDX ON PHON_VAL_TBL(VAL);
--#!

-- GENERIC CONCEPTS TABLE
CREATE TABLE CD_TBL (
	CD_ID UUID NOT NULL,
	IS_SYS BOOLEAN DEFAULT FALSE NOT NULL, -- WHETHER THE CONCEPT IS A SYSTEM CONCEPT
	CONSTRAINT PK_CD_TBL PRIMARY KEY (CD_ID)
);
--#!

-- CONCEPT CLASSIFICATIONS TABLE
CREATE TABLE CD_CLS_TBL (
	CLS_ID UUID NOT NULL,
	CLS_NAME VARCHAR(50) NOT NULL, -- THE NAME OF THE CLASS
	MNEMONIC VARCHAR(16) NOT NULL, -- THE MNEMONIC USED BY THE SYSTEM TO LOCATE CONCEPTS
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT HTE CONCEPT CLASS WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED THE CONCEPT CLASS
	UPD_UTC TIMESTAMP, -- THE TIME WHEN THE CONCEPT CLASS WAS CREATE
	UPD_PROV_ID UUID, -- THE USER ID THAT UPDATED THE CONCEPT CLASS
	OBSLT_UTC TIMESTAMP, -- THE OBSOLETION TIME OF THE CONCEPT
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE CONCEPT
	CONSTRAINT PK_CD_CLS_TBL PRIMARY KEY (CLS_ID),
	CONSTRAINT FK_CD_CLS_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_CLS_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_CLS_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_CD_CLS_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_CD_CLS_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!

CREATE UNIQUE INDEX CD_CLS_MNEMONIC_IDX ON CD_CLS_TBL(MNEMONIC);
--#!

-- CONCEPT SETS REPRESENT A SET OF CONCEPTS LOGICALLY GROUPED TOGEHTHER
CREATE TABLE CD_SET_TBL (
	SET_ID UUID NOT NULL, 
	SET_NAME VARCHAR(50) NOT NULL, -- THE NAME OF THE SET
	MNEMONIC VARCHAR(64) NOT NULL, -- THE MNEMONIC (SYSTEM NAME) OF THE SET
	OID VARCHAR(64) NOT NULL, -- THE OID (EXTERNAL ID) OF THE CONCEPT SET
	URL VARCHAR(196) NOT NULL, -- THE DEFINITION URL OF THE CONCEPT SET
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE CREATION TIME OF THE CONCEPT SET
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED THE CONCEPT SET
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE SET WAS OBSOLETED
	OBSLT_RSN BLOB SUB_TYPE TEXT, -- THE REASON THE SET WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE OBSOLETION USER IDENTIFIER
	UPD_UTC TIMESTAMP, -- THE UPDATED TIME OF THE CONCEPT SET
	UPD_PROV_ID UUID, -- THE CHAR(16) OF THE USER WHICH UPDATED THE CONCEPT SET
	CONSTRAINT PK_CD_SET_TBL PRIMARY KEY (SET_ID), 
	CONSTRAINT FK_CD_SET_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_SET_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_SET_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_CD_SET_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_CD_SET_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!

CREATE UNIQUE INDEX CD_SET_OID_IDX ON CD_SET_TBL(OID);
--#!
CREATE UNIQUE INDEX CD_SET_URL_IDX ON CD_SET_TBL(URL);
--#!
CREATE UNIQUE INDEX CD_SET_MNEMONIC_IDX ON CD_SET_TBL(MNEMONIC);
--#!

-- CONCEPT SET MEMBERS ASSOCIATION
CREATE TABLE CD_SET_MEM_ASSOC_TBL (
	SET_ID UUID NOT NULL, -- THE CONCEPT SET TO WHICH THE CONCEPT BELONGS
	CD_ID UUID NOT NULL, -- THE CONCEPT WHICH BELONGS TO THE SET.,
	CONSTRAINT PK_CD_SET_MEM_ASSOC_TBL PRIMARY KEY (SET_ID, CD_ID),
	CONSTRAINT FK_CD_SET_MEM_ASSOC_CD_SET FOREIGN KEY (SET_ID) REFERENCES CD_SET_TBL(SET_ID),
	CONSTRAINT FK_CD_SET_MEM_ASSOC_CD_ID FOREIGN KEY (CD_ID) REFERENCES CD_TBL(CD_ID)
);
--#!

CREATE INDEX CD_SET_MEM_ASSOC_CD_SET_ID_IDX ON CD_SET_MEM_ASSOC_TBL(SET_ID);
--#!
CREATE INDEX CD_SET_MEM_ASSOC_CD_ID_IDX ON CD_SET_MEM_ASSOC_TBL(CD_ID);
--#!

-- VERSION SEQUENCING
CREATE SEQUENCE CD_VRSN_SEQ;
--#!

-- CONCEPT VERSIONS
CREATE TABLE CD_VRSN_TBL (
	CD_VRSN_ID UUID NOT NULL, 
	VRSN_SEQ_ID INTEGER UNIQUE NOT NULL,-- VERSION SEQUENCE
	CD_ID UUID NOT NULL, -- THE CONCEPT TO WHICH THE VERSION APPLIES
	STS_CD_ID UUID NOT NULL, -- THE STATUS OF THE CONCEPT AT THE CURRENT STATE
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THE VERSION WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH WAS RESPONSIBLE FOR THE CREATION OF THE CONCEPT VERSION
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT OBSOLETED THIS VERSION
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THIS VERSION
	RPLC_VRSN_ID UUID, -- THE VERSION THAT THIS VERSION REPLACES
	CLS_ID UUID NOT NULL, -- THE CONCEPT CLASSIFICATION OF THE CONCEPT AT THE CURRENT VERSION
	MNEMONIC VARCHAR(64) NOT NULL, -- THE MNEMONIC OF THE CONCEPT AT THE CURRENT VERSION
	CONSTRAINT PK_CD_VRSN_TBL PRIMARY KEY (CD_VRSN_ID),
	CONSTRAINT FK_CD_VRSN_STAT_CD_ID FOREIGN KEY (STS_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_CD_VRSN_CD_ID FOREIGN KEY (CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_CD_VRSN_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_VRSN_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_VRSN_CLS_ID FOREIGN KEY (CLS_ID) REFERENCES CD_CLS_TBL(CLS_ID),
	CONSTRAINT FK_CD_VRSN_RPLC_VRSN_ID FOREIGN KEY (RPLC_VRSN_ID) REFERENCES CD_VRSN_TBL(CD_VRSN_ID),
	CONSTRAINT CK_CD_VRSN_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL)
);
--#!

CREATE TRIGGER TG_CD_VRSN_TBL_SEQ FOR CD_VRSN_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.VRSN_SEQ_ID = NEXT VALUE FOR CD_VRSN_SEQ;
END;
--#!

CREATE INDEX CD_VRSN_CD_ID_IDX ON CD_VRSN_TBL(CD_ID);
--#!
CREATE INDEX CD_VRSN_MNEMONIC_IDX ON CD_VRSN_TBL(MNEMONIC);
--#!
--DROP INDEX CD_VRSN_MNEMONIC_UQ_IDX ON CD_VRSN_TBL(MNEMONIC) WHERE OBSLT_UTC IS NULL;

-- CONCEPT NAME LOCALIZATION TABLE
CREATE TABLE CD_NAME_TBL (
	NAME_ID UUID NOT NULL,
	CD_ID UUID NOT NULL, -- THE CONCEPT THAT THE NAME APPLIES TO
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION SEQUENCE WHERE THIS BECOMES EFFECTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION SEQUENCE WHERE THIS IS NO LONGER EFFECTIVE
	LANG_CS CHAR(2) NOT NULL, -- THE LANGUAGE CODE
	VAL VARCHAR(196) NOT NULL, -- NAME OF THE CODE
	PHON_CS VARCHAR(32), -- THE PHONETIC CODE
	PHON_ALG_ID UUID NOT NULL, -- THE PHONETIC ALGORITHM USED TO GENERATE THE CODE
	CONSTRAINT PK_CD_NAME_TBL PRIMARY KEY (NAME_ID),
	CONSTRAINT FK_CD_NAME_CD_ID FOREIGN KEY (CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_CD_NAME_EFFT_VRSN_SEQ FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES CD_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_CD_NAME_OBSLT_VRSN_SEQ FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES CD_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_CD_NAME_PHON_ALG_ID FOREIGN KEY (PHON_ALG_ID) REFERENCES PHON_ALG_TBL(ALG_ID)
);
--#!

CREATE INDEX CD_NAME_VRSN_IDX ON CD_NAME_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX CD_NAME_VAL_IDX ON CD_NAME_TBL(VAL);
--#!
CREATE INDEX CD_NAME_PHON_CS_IDX ON CD_NAME_TBL(PHON_CS);
--#!
CREATE INDEX CD_NAME_CD_ID_IDX ON CD_NAME_TBL(CD_ID);
--#!

-- CODE SYSTEMS TABLE
CREATE TABLE CD_SYS_TBL (
	CS_ID UUID NOT NULL, 
	CS_NAME VARCHAR(196), -- HUMAN READABLE NAME FOR THE CODESYSTEM
	OID VARCHAR(64) NOT NULL, -- THE OID OF THE CODE SYSTEM
	DOMAIN VARCHAR(50), -- THE ASSIGNING AUTHORITY OF THE COE SYSTEM
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT THE CODE SYSTEM WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER IDENTIFIER THAT CREATED THE CODE SYSTEM
	OBSLT_UTC TIMESTAMP, -- THE TIMESTAMP OF OBSOLETION
	OBSLT_PROV_ID UUID, -- THE USER WHO OBSOLETED
	UPD_UTC TIMESTAMP, -- THE TIMESTAMP OFUPDATING
	UPD_PROV_ID UUID, -- THE USER IDENTIIFER WHO UPDATED
	URL VARCHAR(196) NOT NULL, -- THE DEFINITION URL FOR THE CODE SYSTEM
	VRSN_TXT VARCHAR(10), -- THE VERSION OF THE CODE SYSTEM AS DEFINED BY THE AUTHORITY
	DESCR BLOB SUB_TYPE TEXT, -- THE HUMAN DESCRIPTION OF THE CODE SYSTEM
	CONSTRAINT PK_CD_SYS_TBL PRIMARY KEY (CS_ID),
	CONSTRAINT FK_CD_SYS_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_SYS_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_SYS_OBSLT_PROV_ID FOREIGN KEy (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_CD_SYS_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_CD_SYS_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)

);
--#!


-- INDEX ON CODE SYSTEM
CREATE UNIQUE INDEX CD_SYS_OID_IDX ON CD_SYS_TBL(OID);
--#!
CREATE UNIQUE INDEX CD_SYS_URL_IDX ON CD_SYS_TBL(URL);
--#!

-- CONCEPT RELATIONSHIP TYPES
CREATE TABLE CD_REL_TYP_CDTBL (
	REL_TYP_ID UUID NOT NULL, 
	REL_NAME VARCHAR(50) NOT NULL, -- NAME OF THE RELATIONSHIP TYPE
	MNEMONIC VARCHAR(20) NOT NULL, -- THE UNCHANGING MNEMONIC OF THE RELATIONSHIP
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT THE RELATION WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER IDENTIFIER THAT CREATED THE RELATION
	OBSLT_UTC TIMESTAMP, -- THE TIMESTAMP OF OBSOLETION
	OBSLT_PROV_ID UUID, -- THE USER WHO OBSOLETED
	UPD_UTC TIMESTAMP, -- THE TIMESTAMP OFUPDATING
	UPD_PROV_ID UUID, -- THE USER IDENTIIFER WHO UPDATED
	CONSTRAINT PK_CD_REL_TYP_CDTBL PRIMARY KEY (REL_TYP_ID),
	CONSTRAINT FK_CD_REL_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_REL_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_CD_REL_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_CD_REL_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_CD_REL_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
	
);
--#!

CREATE INDEX CD_REL_TYP_MNEMONIC_IDX ON CD_REL_TYP_CDTBL(MNEMONIC);
--#!

-- REFERENCE TERMS
CREATE TABLE REF_TERM_TBL (
	REF_TERM_ID UUID NOT NULL, 
	CS_ID UUID NOT NULL, -- CODE SYSTEM UUID
	MNEMONIC VARCHAR(50) NOT NULL, -- MNEMONIC OF THE REF TERM
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT THE REF WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER IDENTIFIER THAT CREATED THE REF
	OBSLT_UTC TIMESTAMP, -- THE TIMESTAMP OF OBSOLETION
	OBSLT_PROV_ID UUID, -- THE USER WHO OBSOLETED
	UPD_UTC TIMESTAMP, -- THE TIMESTAMP OFUPDATING
	UPD_PROV_ID UUID, -- THE USER IDENTIIFER WHO UPDATED
	CONSTRAINT PK_REF_TERM_TBL PRIMARY KEY (REF_TERM_ID),
	CONSTRAINT FK_REF_TERM_CS_ID FOREIGN KEY (CS_ID) REFERENCES CD_SYS_TBL(CS_ID),
	CONSTRAINT FK_REF_TERM_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_REF_TERM_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_REF_TERM_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_REF_TERM_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_REF_TERM_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!
CREATE INDEX CD_REF_TERM_MNEMONIC_IDX ON REF_TERM_TBL(MNEMONIC);
--#!
CREATE UNIQUE INDEX CD_REF_TERM_CS_MNEMONIC_UQ_IDX ON REF_TERM_TBL(CS_ID, MNEMONIC);
--#!

-- CONCEPT REFERENCE TERM ASSOCIATION
CREATE TABLE CD_REF_TERM_ASSOC_TBL (
	CD_REF_TERM_ID UUID NOT NULL,
	REF_TERM_ID UUID NOT NULL, -- THE REFERENCE TERM PART OF THIS RELATIONSHIP
	CD_ID UUID NOT NULL, -- THE CONCEPT DEFINITION IDENTIFIER
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION AT WHICH THE REFERENCE TERM RELATIONSHIP BECAME ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION AT WHICH THE REFERENCE TERM IS NO LONGER ACTIVE
	REL_TYP_ID UUID NOT NULL, -- THE RELATIONSHIP TYPE IDENTIFIER
	CONSTRAINT PK_CD_REF_TERM_ASC_TBL PRIMARY KEY (CD_REF_TERM_ID),
	CONSTRAINT FK_CD_REF_TERM_ASC_REF_TERM_ID FOREIGN KEY (REF_TERM_ID) REFERENCES REF_TERM_TBL(REF_TERM_ID),
	CONSTRAINT FK_CD_REF_TERM_ASC_CD_ID FOREIGN KEY (CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_CD_REF_TERM_ASC_EFT_VER_SEQ FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES CD_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_CD_REF_TERM_ASC_OBS_VER_SEQ FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES CD_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_CD_REF_TERM_ASC_REL_TYP_ID FOREIGN KEY (REL_TYP_ID) REFERENCES CD_REL_TYP_CDTBL(REL_TYP_ID)
);
--#!

CREATE INDEX CD_REF_TERM_ASSOC_CD_ID_IDX ON CD_REF_TERM_ASSOC_TBL(CD_ID);
--#!
CREATE INDEX CD_REF_TERM_ASSOC_VRSN_IDX ON CD_REF_TERM_ASSOC_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- REFERENCE TERM DISPLAY NAMES 
CREATE TABLE REF_TERM_NAME_TBL (
	REF_TERM_NAME_ID UUID NOT NULL,
	REF_TERM_ID UUID NOT NULL, -- THE REFERENCE TERM ID TO WHICH THE NAME APPLIES
	LANG_CS CHAR(2) NOT NULL, -- THE ISO LANGUAGE CODE FOR WHICH THE NAME APPLIES
	TERM_NAME VARCHAR(196) NOT NULL, -- THE NAME TO BE USED
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THE NAME WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH WAS RESPONSIBLE FOR THE CREATION OF THE NAME
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT OBSOLETED THIS NAME
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THIS NAME
	OBSLT_RSN BLOB SUB_TYPE TEXT, -- THE REASON THAT THE TERM NAME WAS OBSOLETED
	PHON_CS VARCHAR(20), -- THE PHONETIC CODE FOR THE NAME
	PHON_ALG_ID UUID NOT NULL, -- THE PHONETIC ALGORITHM FOR THE NAME
	CONSTRAINT PK_REF_TERM_NAME_TBL PRIMARY KEY (REF_TERM_NAME_ID),
	CONSTRAINT FK_REF_TERM_NAME_REF_TERM_ID FOREIGN KEY (REF_TERM_ID) REFERENCES REF_TERM_TBL(REF_TERM_ID),
	CONSTRAINT FK_REF_TERM_NAME_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_REF_TERM_NAME_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_REF_TERM_NAME_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL)
);
--#!

-- INDEX OF REF TERM NAMES
CREATE INDEX REF_TERM_NAME_PHON_CS_IDX ON REF_TERM_NAME_TBL(PHON_CS);
--#!
CREATE INDEX REF_TERM_NAME_TERM_NAME_IDX ON REF_TERM_NAME_TBL(TERM_NAME);
--#!

-- REFERENCE TERM RELATIONSHIP TABLE
CREATE TABLE CD_REL_ASSOC_TBL (
	CD_REL_ID UUID NOT NULL,
	SRC_CD_ID UUID NOT NULL, -- THE SOURCE OF THE RELATIONSHIP
	TRG_CD_ID UUID NOT NULL, -- THE TARGET OF THE RELATIONSHIP
	REL_TYP_ID UUID NOT NULL, -- THE TYPE OF RELATIONSHIP
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION AT WHICH THE RELATIONSHIP BECOMES ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION AT WHICH THE RELATIONSHIP IS NO LONGER ACTIVE
	CONSTRAINT PK_CD_REL_ASSOC_TBL PRIMARY KEY (CD_REL_ID),
	CONSTRAINT FK_CD_REL_ASSOC_SRC_CD_ID FOREIGN KEY (SRC_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_CD_REL_ASSOC_TRG_CD_ID FOREIGN KEY (TRG_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_CD_REL_ASSOC_REL_TYP_ID FOREIGN KEY (REL_TYP_ID) REFERENCES CD_REL_TYP_CDTBL(REL_TYP_ID),
	CONSTRAINT FK_CD_REL_ASC_EFT_VER_SEQ FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES CD_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_CD_REL_ASC_OBS_VER_SEQ FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES CD_VRSN_TBL(VRSN_SEQ_ID)
);
--#!

-- INDEX FOR RELATIONSHIP
CREATE INDEX CD_REL_ASSOC_VRSN_IDX ON CD_REL_ASSOC_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX CD_REL_ASSOC_SRC_ID_IDX ON CD_REL_ASSOC_TBL(SRC_CD_ID);
--#!
CREATE INDEX CD_REL_ASSOC_TRG_ID_IDX ON CD_REL_ASSOC_TBL(TRG_CD_ID);
--#!

-- CURRENT CONCEPT VERSION VIEW
CREATE VIEW CD_CUR_VRSN_VW AS
	SELECT CD_VRSN_TBL.*, CD_TBL.IS_SYS, CD_CLS_TBL.MNEMONIC AS CLS_MNEMONIC 
	FROM CD_VRSN_TBL INNER JOIN CD_TBL USING (CD_ID)
		INNER JOIN CD_CLS_TBL USING (CLS_ID)
		WHERE CD_VRSN_TBL.OBSLT_UTC IS NULL;
--#!

-- CONCEPT SET MEMBERS VIEW
CREATE VIEW CD_SET_MEM_VW AS
	SELECT CD_SET_TBL.SET_ID, CD_SET_TBL.MNEMONIC AS SET_MNEMONIC, CD_CUR_VRSN_VW.CD_ID, CD_CUR_VRSN_VW.CD_VRSN_ID, CD_CUR_VRSN_VW.MNEMONIC AS CD_MNEMONIC, CD_CUR_VRSN_VW.CLS_MNEMONIC
	FROM CD_SET_MEM_ASSOC_TBL INNER JOIN CD_SET_TBL USING (SET_ID) 
	INNER JOIN CD_CUR_VRSN_VW USING(CD_ID);
--#!

CREATE EXCEPTION codification_error 'O9002';
--#!

-- ASSERT A CONCEPT HAS A PARTICULAR CLASSIFIER
-- RETURN : TRUE IF THE CLASS CARRIES THE SPECIIFED CLASSIFICATION
-- PARAM CD_ID_IN : THE CHAR(16) OF THE CONCEPT 
-- PARAM CLS_MNEMONIC_IN : THE CLASS TO ASSERT
CREATE FUNCTION ASSRT_CD_CLS(
	CD_ID_IN UUID,
	CLS_MNEMONIC_IN VARCHAR(32)
) RETURNS BOOLEAN AS
BEGIN
	RETURN (
		SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END AS r
		FROM CD_VRSN_TBL INNER JOIN CD_CLS_TBL USING (CLS_ID) WHERE CD_ID = :CD_ID_IN AND (CD_CLS_TBL.MNEMONIC = :CLS_MNEMONIC_IN OR
	-- CAN ALSO BE A NuLL REASON
	 CD_CLS_TBL.CLS_ID = char_to_uuid('05ac7b93-1b1e-47dd-87dd-e56e353ecb94')));
END;
--#!

-- ASSERT THAT A CONCEPT HAS A SET MEMBER
-- RETURN : TRUE IF THE CONCEPT SET CONTAINS THE CONCEPT
-- PARAM CD_ID_IN : THE CHAR(16) FO THE CONCEPT
-- PARAM SET_MNEMONIC_IN : THE NAME OF THE CONCEPT SET TO TEST
CREATE FUNCTION IS_CD_SET_MEM(
	CD_ID_IN  UUID,
	SET_MNEMONIC_IN VARCHAR(32)
) RETURNS BOOLEAN AS 
BEGIN
	RETURN (SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END AS r FROM CD_SET_MEM_ASSOC_TBL INNER JOIN CD_SET_TBL USING(SET_ID) WHERE CD_ID = :CD_ID_IN AND (MNEMONIC = :SET_MNEMONIC_IN OR SET_ID = char_to_uuid('51925f69-14a3-4516-bb2c-e2280a4f3065')));
END;
--#!

CREATE OR ALTER FUNCTION CK_IS_CD_SET_MEM ( CD_ID_IN UUID, SET_MNEMONIC_IN VARCHAR(32), ALLOW_NULL_IN BOOLEAN) RETURNS BOOLEAN AS
 BEGIN 
	IF (IS_CD_SET_MEM(:cd_id_in, :set_mnemonic_in) OR :allow_null_in AND IS_CD_SET_MEM(:cd_id_in, 'NullReason')) THEN
		RETURN TRUE;
	ELSE 
		EXCEPTION codification_error
			 'Codification Error: Concept ' || uuid_to_char(:cd_id_in) || ' is not in set ' || :set_mnemonic_in;
 END;
--#!

-- CONSTRAINT CHECK FOR CONCEPT SETS
ALTER TABLE CD_VRSN_TBL ADD CONSTRAINT CK_CD_VRSN_STS_CD_ID CHECK (IS_CD_SET_MEM(STS_CD_ID, 'ConceptStatus'));
--#!

-- EXTENSION TYPE REGISTRY
CREATE TABLE EXT_TYP_TBL (
	EXT_TYP_ID UUID NOT NULL,
	HDLR_CLS VARCHAR(196) NOT NULL, -- THE EXTENSION HANDLER WHICH HANDLES (SERIALIZES) THIS TYPE OF EXTENSION
	EXT_NAME VARCHAR(128) NOT NULL, -- THE HUMAN NAME OF THE EXTENSION
	IS_ACTIVE BOOLEAN DEFAULT TRUE NOT NULL, -- TRUE IF THE EXTENSION REGISTRATION IS ACTIVE
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE CREATION TIME OF THE EXTENSION TYPE
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHO CREATED THE EXTENSION REGISTRATION
	UPD_UTC TIMESTAMP, -- THE TIME THAT THE EXTENSION TYPE WAS UPDATED
	UPD_PROV_ID UUID, -- THE USER WHICH UPDATED THE EXTENSION TYPE
	OBSLT_UTC TIMESTAMP, -- THE TIME WHEN THE EXTENSION WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE EXTENSION TYPE
	CONSTRAINT PK_EXT_TYP_TBL PRIMARY KEY (EXT_TYP_ID),
	CONSTRAINT FK_EXT_TYP_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_EXT_TYP_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_EXT_TYP_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_EXT_TYP_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_EXT_TYP_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!

-- INDEX ON EXTENSION TYPE
CREATE UNIQUE INDEX EXT_TYP_NAME_IDX ON EXT_TYP_TBL(EXT_NAME);
--#!

-- ASSIGNING AUTHORITY
CREATE TABLE ASGN_AUT_TBL (
	AUT_ID UUID NOT NULL,
	AUT_NAME VARCHAR(50) NOT NULL, -- THE NAME OF THE ASSIGNING AUTHORITY
	OID VARCHAR(196) NOT NULL, -- THE OID OF THE ASSIGNING AUTHORTIY
	NSID VARCHAR(32) NOT NULL, -- THE HL7 V2 CX.4 ASSIGNING AUTHORITY DOMAIN
	URL VARCHAR(250), -- THE URL OF THE ASSINGING AUTHORITY DEFINITION
	APP_ID UUID, -- APPLICATION IDENTIFIER OF A DEVICE THAT IS PERMITTED TO ASSIGN IDS
	DESCR BLOB SUB_TYPE TEXT, -- THE DESCRIPTION OF THE AUTHORITY
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT THE AA WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED THE AA
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE AA WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE AA
	VAL_RGX VARCHAR(64), -- REGULAR EXPRESSION FOR VALIDATION
	IS_UNQ BOOLEAN DEFAULT FALSE NOT NULL, -- TRUE IF THE ASSIGNING AUTHORITY IS UNIQUE
	CONSTRAINT PK_ASGN_AUT_TBL PRIMARY KEY (AUT_ID),
	CONSTRAINT FK_ASGN_AUT_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ASGN_AUT_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_ASGN_AUT_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT FK_ASGN_AUT_APP_ID FOREIGN KEY (APP_ID) REFERENCES SEC_APP_TBL(APP_ID)
);
--#!

CREATE UNIQUE INDEX ASGN_AUT_NAME_IDX ON ASGN_AUT_TBL(NSID);
--#!
CREATE UNIQUE INDEX ASGN_AUT_OID_IDX ON ASGN_AUT_TBL(OID);
--#!

-- IDENTIFIES SCOPES TO WHICH AN AA APPLIES
CREATE TABLE ASGN_AUT_SCP_TBL (
	AUT_ID UUID NOT NULL, -- THE AA TO WHICH THE SCOPE APPLIES
	CD_ID UUID NOT NULL, -- THE CHAR(16) FOR THE CLASS WHICH DESCRIBES THE SCOPE
	CONSTRAINT PK_ASGN_AUT_SCP_TBL PRIMARY KEY (AUT_ID, CD_ID),
	CONSTRAINT FK_ASGN_AUT_SCP_AUT_ID FOREIGN KEY (AUT_ID) REFERENCES ASGN_AUT_TBL(AUT_ID),
	CONSTRAINT FK_ASGN_AUT_SCP_CD_ID FOREIGN KEY (CD_ID) REFERENCES CD_TBL(CD_ID)
);
--#!

-- IDENTIFIER TYPES
CREATE TABLE ID_TYP_TBL (
	ID_TYP_ID UUID NOT NULL,
	TYP_CD_ID UUID NOT NULL, -- THE TYPE OF IDENTIFIER
	ENT_SCP_CD_ID UUID NOT NULL, -- THE SCOPE IN WHICH THE IDENTIFIER TYPE CAN BE USED
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT THE AA WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED THE AA
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE AA WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE AA
	CONSTRAINT PK_ID_TYP_TBL PRIMARY KEY (ID_TYP_ID),
	CONSTRAINT FK_ID_TYP_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ID_TYP_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_ID_TYP_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT FK_ID_TYP_TYP_CD_ID FOREIGN KEY (TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ID_TYP_ENT_SCP_CD_ID FOREIGN KEY (ENT_SCP_CD_ID) REFERENCES CD_TBL(CD_ID)
);
--#!

-- TEMPLATE DEFINITION TABLE
CREATE TABLE TPL_DEF_TBL (
	TPL_ID UUID NOT NULL,
	OID VARCHAR(64), -- THE OID OF THE TEMPLATE DEFINITION
	MNEMONIC VARCHAR(64) NOT NULL, -- THE MNEMONIC FOR THE TEMPLATE DEFINITION
	TPL_NAME VARCHAR(128), -- THE HUMAN READABLE NAME FOR THE TEMPLATE DEFINITION
	DESCR BLOB SUB_TYPE TEXT, -- A DESCRIPTION OF THE TEMPLATE
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE CREATION TIME OF THE EXTENSION TYPE
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHO CREATED THE EXTENSION REGISTRATION
	UPD_UTC TIMESTAMP, -- THE TIME THAT THE EXTENSION TYPE WAS UPDATED
	UPD_PROV_ID UUID, -- THE USER WHICH UPDATED THE EXTENSION TYPE
	OBSLT_UTC TIMESTAMP, -- THE TIME WHEN THE EXTENSION WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE EXTENSION TYPE
	CONSTRAINT PK_TPL_DEF_TBL PRIMARY KEY (TPL_ID),
	CONSTRAINT FK_TPL_DEF_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_TPL_DEF_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_TPL_DEF_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_TPL_DEF_OBSLT_PROV_ID CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_TPL_DEF_UPD_PROV_ID CHECK (UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL OR UPD_PROV_ID IS NULL AND UPD_UTC IS NULL)
);
--#!

CREATE UNIQUE INDEX TPL_DEF_OID_IDX ON TPL_DEF_TBL(OID);
--#!
CREATE UNIQUE INDEX TPL_DEF_MNEMONIC_IDX ON TPL_DEF_TBL(MNEMONIC);
--#!

-- CREATE ACT TABLE
CREATE TABLE ACT_TBL (
	ACT_ID UUID NOT NULL,
	TPL_ID UUID, -- IDENTIFIES THE TEMPLATE WHICH THIS ACT FOLLOWS
	CLS_CD_ID UUID NOT NULL, -- CLASSIFIES THE TYPE OF ACT
	MOD_CD_ID UUID NOT NULL, -- IDENTIIFES THE MOOD OF THE ACT
	CONSTRAINT PK_ACT PRIMARY KEY (ACT_ID),
	CONSTRAINT FK_ACT_CLS_CD_ID FOREIGN KEY (CLS_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ACT_MOD_CD_ID FOREIGN KEY (MOD_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ACT_CLS_CD CHECK (IS_CD_SET_MEM(CLS_CD_ID, 'ActClass')),
	CONSTRAINT CK_ACT_MOD_CD CHECK (IS_CD_SET_MEM(MOD_CD_ID, 'ActMood')),
	CONSTRAINT FK_ACT_TPL_ID FOREIGN KEY (TPL_ID) REFERENCES TPL_DEF_TBL(TPL_ID)
);
--#!

-- INDEXING
CREATE INDEX ACT_CLS_CD_IDX ON ACT_TBL(CLS_CD_ID);
--#!

-- ACT VERSION SEQUENCE
CREATE SEQUENCE ACT_VRSN_SEQ;
--#!

-- ACT VERSION TABLE
CREATE TABLE ACT_VRSN_TBL (
	ACT_VRSN_ID UUID NOT NULL,
	VRSN_SEQ_ID INTEGER UNIQUE NOT NULL, -- THE VERSION SEQUENCE
	ACT_ID UUID NOT NULL, -- THE ACT IDENTIFIER TO WHICH THIS VERSION APPLIES
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THAT HTE VERSION WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH WAS RESPONSIBLE FOR THE CREATION OF THE VERSION
	OBSLT_UTC TIMESTAMP, -- THE TIME WHEN THE ACT VERSION BECOMES OBSOLETE
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE ACT VERSION
	OBSLT_RSN BLOB SUB_TYPE TEXT, -- THE REASON WHY THE VERSION WSA OBSOLETED
	RPLC_VRSN_ID UUID, -- THE CHAR(16) OF THE VERSION THAT THIS VERISON REPLACE
	NEG_IND BOOLEAN DEFAULT FALSE NOT NULL, -- TRUE IF THE ACT NEVER OCCURRED
	TYP_CD_ID UUID, -- THE TYPE CONCEPT OF THE ACT AT THIS VERSION
	STS_CD_ID UUID NOT NULL, -- THE STATUS OF THE ACT AS OF THIS VERSION
	RSN_CD_ID UUID, -- THE REASON OF THE ACT TO OCCUR
	ACT_UTC TIMESTAMP, -- THE TIME THE ACT OCCURRED
	ACT_START_UTC TIMESTAMP, -- THE TIME THE ACT STARTED OR WAS TO START
	ACT_STOP_UTC TIMESTAMP, -- THE TIME THAT THE ACT STOPPED TO WAS TO STOP
	CONSTRAINT PK_ACT_VRSN_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_ACT_VRSN_ACT FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_VRSN_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ACT_VRSN_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ACT_VRSN_RPLC_VRSN_ID FOREIGN KEY (RPLC_VRSN_ID) REFERENCES ACT_VRSN_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_ACT_VRSN_TYP_CD_ID FOREIGN KEY (TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ACT_VRSN_RSN_CD_ID FOREIGN KEY (RSN_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ACT_VRSN_STS_CD_ID FOREIGN KEY (STS_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ACT_VRSN_STS_CD CHECK (IS_CD_SET_MEM(STS_CD_ID, 'ActStatus')),
	CONSTRAINT CK_ACT_VRSN_RSN_CD CHECK (RSN_CD_ID IS NULL OR IS_CD_SET_MEM(RSN_CD_ID, 'ActReason') OR IS_CD_SET_MEM(RSN_CD_ID, 'NullReason')),
	CONSTRAINT CK_ACT_VRSN_OBSLT_PROV_ID CHECK(OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL),
	CONSTRAINT CK_ACT_VRSN_ACT_UTC CHECK(ACT_UTC IS NOT NULL OR ACT_START_UTC IS NOT NULL OR ACT_STOP_UTC IS NOT NULL) -- CHECK: ONE OF ACT TIME, START, OR END MUST BE PROVIDED
);
--#!

CREATE TRIGGER TG_ACT_VRSN_TBL_SEQ FOR ACT_VRSN_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.VRSN_SEQ_ID = NEXT VALUE FOR ACT_VRSN_SEQ;
END;
--#!

-- INDEXING FOR ACTS
CREATE INDEX ACT_VRSN_ACT_ID_IDX ON ACT_VRSN_TBL(ACT_ID);
--#!
CREATE INDEX ACT_VRSN_TYP_CD_ID_IDX ON ACT_VRSN_TBL(TYP_CD_ID);
--#!

-- IDENTIFIERS FOR ACTS
CREATE TABLE ACT_ID_TBL (
	ACT_ID_ID UUID NOT NULL,
	ID_TYP_ID UUID, -- THE TYPE OF IDENTIFIER 
	ACT_ID UUID NOT NULL, -- THE IDENTIFIER OF THE ACT
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION AT WHICH TIME THIS IDENTIIFER BECAME ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION SEQUENCE AT WHICH THE IDENTIFIER WAS NO LONGER ACTIVE
	AUT_ID UUID NOT NULL, -- THE ASSIGNING AUTHORITY OF THE IDENTIFIER
	ID_VAL VARCHAR(64) NOT NULL, -- THE VALUE OF THE IDENTIFIER
	CONSTRAINT PK_ACT_ID_TBL PRIMARY KEY(ACT_ID_ID),
	CONSTRAINT FK_ACT_ID_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_ID_ID_TYP_ID FOREIGN KEY (ID_TYP_ID) REFERENCES ID_TYP_TBL(ID_TYP_ID),
	CONSTRAINT FK_ACT_ID_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_ID_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_ID_AUT_ID FOREIGN KEY (AUT_ID) REFERENCES ASGN_AUT_TBL(AUT_ID)
);
--#!

-- INDEXING FO RTHE ID TABLE
CREATE INDEX ACT_ID_ACT_ID_IDX ON ACT_ID_TBL(ACT_ID);
--#!
CREATE INDEX ACT_ID_VRSN_IDX ON ACT_ID_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- ACT RELATIONSHIPS
CREATE TABLE ACT_REL_TBL (
	REL_ID UUID NOT NULL,
	SRC_ACT_ID UUID NOT NULL, -- THE SOURCE ACT
	TRG_ACT_ID UUID NOT NULL, -- THE TARGET ACT
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- EFFECTIVE VERSION OF THE RELATIONSHIP
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE OBSOLETION VERSION OF THE RELATIONSHIP
	REL_TYP_CD_ID UUID NOT NULL, -- THE RELATIONSHIP TYPE CONCEPT
	CONSTRAINT PK_ACT_REL_TBL PRIMARY KEY (REL_ID),
	CONSTRAINT FK_ACT_REL_SRC_ACT_ID FOREIGN KEY (SRC_ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_REL_TRG_ACT_ID FOREIGN KEY (TRG_ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_REL_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_REL_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_REL_REL_TYP_CD_ID FOREIGN KEY (REL_TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ACT_REL_REL_TYP_CD CHECK (IS_CD_SET_MEM(REL_TYP_CD_ID, 'ActRelationshipType'))
);
--#!

CREATE INDEX ACT_REL_SRC_ACT_ID_IDX ON ACT_REL_TBL(SRC_ACT_ID);
--#!
CREATE INDEX ACT_REL_TRG_ACT_ID_IDX ON ACT_REL_TBL(TRG_ACT_ID);
--#!
CREATE INDEX ACT_REL_VRSN_IDX ON ACT_REL_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- ACT EXTENSIONS TABLE
CREATE TABLE ACT_EXT_TBL (
	ACT_EXT_ID UUID NOT NULL,
	ACT_ID UUID NOT NULL, -- THE ACT TO WHICH THE EXTENSION APPLIES
	EXT_TYP_ID UUID NOT NULL, -- THE TYPE OF EXTENSION
	EXT_VAL BLOB, -- THE SERIALIZED EXTENSION VALUE
	EXT_DISP VARCHAR(64), -- THE DISPLAY (HUMAN) VERSION OF THE EXTENSION
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION AT WHICH THE EXTENSION IS ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION AT WHICH THE EXTENSION IS NOT ACTIVE
	CONSTRAINT PK_ACT_EXT_TBL PRIMARY KEY (ACT_EXT_ID), 
	CONSTRAINT FK_ACT_EXT_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_EXT_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_EXT_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_EXT_EXT_TYP_ID FOREIGN KEY (EXT_TYP_ID) REFERENCES EXT_TYP_TBL(EXT_TYP_ID)
);
--#!

CREATE INDEX ACT_EXT_VRSN_IDX ON ACT_EXT_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ACT_EXT_ACT_ID ON ACT_EXT_TBL(ACT_ID);
--#!

-- CONTROL ACT TABLE
CREATE TABLE CNTRL_ACT_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE LINK TO THE ACT WHICH IS A CONTROL ACT
	CONSTRAINT PK_CNTRL_ACT_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_CNTRL_ACT_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES ACT_VRSN_TBL(ACT_VRSN_ID)
);
--#!

-- PROCEDURES TABLE
CREATE TABLE PROC_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE UUID FOR THE ACT VERSION INFORMATION
	MTH_CD_ID UUID, -- THE UUID FOR THE METHOD / TECHNIQUE CODE
	APR_STE_CD_ID UUID, -- THE UUID FOR THE APPOACH SITE CODE
	TRG_STE_CD_ID UUID, -- THE UUID FOR THE TARGET SITE CODE
	CONSTRAINT PK_PROC_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_PROC_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES ACT_VRSN_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_PROC_MTH_CD_ID FOREIGN KEY (MTH_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_PROC_APR_STE_CD_ID FOREIGN KEY (APR_STE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_PROC_TRG_STE_CD_ID FOREIGN KEY (TRG_STE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_PROC_MTH_CD_ID CHECK (MTH_CD_ID IS NULL OR CK_IS_CD_SET_MEM(MTH_CD_ID, 'ProcedureTechniqueCode', TRUE)),
	CONSTRAINT CK_PROC_APR_STE_CD_ID CHECK(APR_STE_CD_ID IS NULL OR CK_IS_CD_SET_MEM(APR_STE_CD_ID, 'BodySiteOrSystemCode', TRUE)),
	CONSTRAINT CK_PROC_TRG_STE_CD_ID CHECK (TRG_STE_CD_ID IS NULL OR CK_IS_CD_SET_MEM(TRG_STE_CD_ID, 'BodySiteOrSystemCode', TRUE))
);
--#!

-- OBSERVATION TABLE
CREATE TABLE OBS_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE VERSION TO WHICH THIS OBSERVATION DATA APPLIES
	INT_CD_ID UUID, -- THE INTERPRETATION CODE OF THE OBSERVATION
	VAL_TYP VARCHAR(2) CHECK (VAL_TYP IN ('PQ','ST','CD')) NOT NULL, -- THE TYPE OF VALUE
	CONSTRAINT PK_OBS_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_OBS_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES ACT_VRSN_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_OBS_INT_CD_ID FOREIGN KEY (INT_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_OBS_INT_CD CHECK (INT_CD_ID IS NULL OR IS_CD_SET_MEM(INT_CD_ID, 'ActInterpretation'))
);
--#!

-- OBSERVATION VALUE TYPE INDEx
CREATE INDEX OBS_VAL_TYP_IDX ON OBS_TBL(VAL_TYP);
--#!

-- QUANTITY OBSERVATION TABLE
CREATE TABLE QTY_OBS_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE VERSION TO WHICH THE OBSERVATION DATA APLIES
	QTY DECIMAL NOT NULL, -- THE QUANTITY ITSELF
	QTY_PRC NUMERIC(2), -- THE PRECISION OF THE OBSERVED VALUES
	UOM_CD_ID UUID NOT NULL, -- THE UNIT OF MEASURE OF THE QUANTITY
	CONSTRAINT PK_QTY_OBS_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_QTY_OBS_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES OBS_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_QTY_OBS_UOM_CD_ID FOREIGN KEY (UOM_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_QTY_OBS_UOM_CD CHECK (ASSRT_CD_CLS(UOM_CD_ID, 'UnitOfMeasure'))
);
--#!

-- CODIFIED OBSERVATION TABLE
CREATE TABLE CD_OBS_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE VERSION TO WHICH THE OBSERVATION DTA APPLIES
	VAL_CD_ID UUID NOT NULL, -- THE CONCEPT WHICH REPRESENTS THE VALUE
	CONSTRAINT PK_CD_OBS_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_CD_OBS_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES OBS_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_CD_OBS_VAL_CD_ID FOREIGN KEY (VAL_CD_ID) REFERENCES CD_TBL(CD_ID)
);
--#!

-- BLOB SUB_TYPE TEXT OBSERVATION
CREATE TABLE TXT_OBS_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE VERSION TO WHICH THE BLOB SUB_TYPE TEXT DATA APPLIES
	OBS_VAL BLOB SUB_TYPE TEXT NOT NULL, -- THE OBSERVATION VALUE 
	CONSTRAINT PK_TXT_OBS_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_TXT_OBS_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES OBS_TBL(ACT_VRSN_ID)
);
--#!

-- PATIENT ENCOUNTER
CREATE TABLE PAT_ENC_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE VERSION TO WHICH THE ENCOUNTER DATA APPLIES
	DSCH_DSP_CD_ID UUID, -- THE DISCHARGE DISPOSITION IF KNOWN
	CONSTRAINT PK_PAT_ENC_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_PAT_ENC_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES ACT_VRSN_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_PAT_ENC_DSCH_DSP_CD_ID FOREIGN KEY (DSCH_DSP_CD_ID) REFERENCES CD_TBL(CD_ID)
);
--#!

-- SUBBSTANCE ADMINISTRATION
CREATE TABLE SUB_ADM_TBL (
	ACT_VRSN_ID UUID NOT NULL, -- THE VERSION TO WHICH THE SUBSTANCE ADMINISTRATION DATA APPLIES
	STE_CD_ID UUID, -- THE SITE OF ADMINISTRATION
	RTE_CD_ID UUID DEFAULT x'8BA48D376C864A549A2FE3A1DAD2E6A2'  NOT NULL, -- THE ROUTE OF ADMINISTRATION
	DOS_QTY DECIMAL NOT NULL, -- THE AMOUNT ADMINISTERED
	DOS_UNT_CD_ID UUID NOT NULL, -- THE DOSE UOM CODE
	SEQ_ID INT, -- THE SEQUENCE CODE OF THE DOSE IF GIVEN AS PART OF A DOSE
	CONSTRAINT PK_SUB_ADM_TBL PRIMARY KEY (ACT_VRSN_ID),
	CONSTRAINT FK_SUB_ADM_ACT_VRSN_ID FOREIGN KEY (ACT_VRSN_ID) REFERENCES ACT_VRSN_TBL(ACT_VRSN_ID),
	CONSTRAINT FK_SUB_ADM_STE_CD_ID FOREIGN KEY (STE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_SUB_ADM_RTE_CD_ID FOREIGN KEY (RTE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_SUB_ADM_RTE_CD CHECK (ASSRT_CD_CLS(RTE_CD_ID, 'Route')),
	CONSTRAINT FK_SUB_ADM_DOS_UNT_CD_ID FOREIGN KEY (DOS_UNT_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_SUB_ADM_DOS_UNT_CD CHECK (ASSRT_CD_CLS(DOS_UNT_CD_ID, 'UnitOfMeasure'))
);
--#!

-- ACT TAG
CREATE TABLE ACT_TAG_TBL (
	TAG_ID UUID NOT NULL, 
	ACT_ID UUID NOT NULL, -- THE ACT TO WHICH THE TAG APPLIES
	TAG_NAME VARCHAR(64) NOT NULL, -- THE NAME OF THE TAG
	TAG_VALUE BLOB SUB_TYPE TEXT, -- THE VALUE OF THE TAG
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THE TAG WAS ATTACHED TO THE ACT
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH IS RESPONSIBLE FOR THE CREATION OF THE ACT TAG
	OBSLT_UTC TIMESTAMP, -- THE TIME THAT THE TAG NO LONGER APPLIES TO THE OBJECT
	OBSLT_PROV_ID UUID, -- THE USER THAT OBSOLETED THE TAG
	CONSTRAINT PK_ACT_TAG_TBL PRIMARY KEY (TAG_ID),
	CONSTRAINT FK_ACT_TAG_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_TAG_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ACT_TAG_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_ACT_TAG_OBSLT_USR CHECK (OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL OR OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL)
);
--#!

CREATE INDEX ACT_TAG_TAG_NAME_IDX ON ACT_TAG_TBL(TAG_NAME);
--#!
CREATE INDEX ACT_TAG_ACT_ID_IDX ON ACT_TAG_TBL(ACT_ID);
--#!

-- ACT POLICY ASSOCIATION
CREATE TABLE ACT_POL_ASSOC_TBL (
	SEC_POL_INST_ID UUID NOT NULL,
	ACT_ID UUID NOT NULL, -- THE ACT TO WHICH THE POLICY APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION OF THE ACT WHERE THE POLICY ASSOCIATION DID BECOME ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION OF THE ACT WHERE THE POLICY ASSOCIATION IS OBSOLETE,
	POL_ID UUID NOT NULL, -- THE IDENTIFIER OF THE POLICY WHICH IS ATTACHED TO THE ACT
	CONSTRAINT PK_ACT_POL_ASSOC_TBL PRIMARY KEY(SEC_POL_INST_ID),
	CONSTRAINT FK_ACT_POL_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_POL_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_POL_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_POL_POL_ID FOREIGN KEY (POL_ID) REFERENCES SEC_POL_TBL(POL_ID)
);
--#!

CREATE INDEX ACT_POL_ASSOC_POL_ID_IDX ON ACT_POL_ASSOC_TBL(POL_ID);
--#!
CREATE INDEX ACT_POL_ASSOC_VRSN_IDX ON ACT_POL_ASSOC_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- ENTITY TABLE
CREATE TABLE ENT_TBL (
	ENT_ID UUID NOT NULL,
	TPL_ID UUID, -- THE TEMPLATE WHICH THIS ENTITY FOLLOWS
	CLS_CD_ID UUID NOT NULL, -- IDENTIIFES THE CLASS CONCEPT
	DTR_CD_ID UUID NOT NULL, -- IDENTIFIES THE ENTITY DETERMINER
	CONSTRAINT PK_ENT_TBL PRIMARY KEY (ENT_ID),
	CONSTRAINT FK_ENT_TPL_ID FOREIGN KEY (TPL_ID) REFERENCES TPL_DEF_TBL(TPL_ID),
	CONSTRAINT FK_ENT_CLS_CD_ID FOREIGN KEY (CLS_CD_ID) REFERENCES CD_TBL (CD_ID),
	CONSTRAINT FK_ENT_DTR_CD_ID FOREIGN KEY (DTR_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ENT_CLS_CD CHECK (IS_CD_SET_MEM(CLS_CD_ID, 'EntityClass')),
	CONSTRAINT FK_ENT_DTR_CD CHECK (IS_CD_SET_MEM(DTR_CD_ID, 'EntityDeterminer'))
);
--#!

CREATE INDEX ENT_TBL_CLS_CD_ID_IDX ON ENT_TBL(CLS_CD_ID);
--#!

-- ASSRERT ENTITY IS A PARTICULAR CLASS
CREATE FUNCTION IS_ENT_CLS(
	ENT_ID_IN UUID,
	CLS_MNEMONIC_IN VARCHAR(32)
) RETURNS BOOLEAN AS 
BEGIN
	RETURN (SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END AS r FROM ENT_TBL INNER JOIN CD_CUR_VRSN_VW ON (ENT_TBL.CLS_CD_ID = CD_CUR_VRSN_VW.CD_ID) WHERE ENT_ID = :ENT_ID_IN AND CD_CUR_VRSN_VW.MNEMONIC = :CLS_MNEMONIC_IN);
END;
--#!

-- ENTITY TAGS
CREATE TABLE ENT_TAG_TBL (
	TAG_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE TAG APPLIES
	TAG_NAME VARCHAR(64) NOT NULL, -- THE NAME OF THE TAG
	TAG_VALUE BLOB SUB_TYPE TEXT, -- THE VALUE OF THE TAG
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME WHEN THE TAG WAS ADDED TO THE ENTITY
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED OR ATTACHED THE TAG TO THE ENTITY
	OBSLT_UTC TIMESTAMP, -- THE TIME WHEN THE TAG WAS OBSOLETED,
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE TAG
	CONSTRAINT PK_ENT_TAG_TBL PRIMARY KEY (TAG_ID),
	CONSTRAINT FK_ENT_TAG_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_TAG_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ENT_TAG_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_ENT_TAG_OBSLT_USR CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL)
);
--#!

-- INDEX ON ENTITY TAG
CREATE INDEX ENT_TAG_ENT_ID_IDX ON ENT_TAG_TBL(ENT_ID);
--#!

-- ENTITY VERSION
CREATE SEQUENCE ENT_VRSN_SEQ;
--#!

-- ENTITY VERSION TABLE
CREATE TABLE ENT_VRSN_TBL (
	ENT_VRSN_ID UUID NOT NULL,
	VRSN_SEQ_ID INTEGER UNIQUE NOT NULL, -- UNIQUE VERSION SEQUENCE FOR THE ENTITY VERSION
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE VERSION APPLIES
	RPLC_VRSN_ID UUID, -- THE VERSION THAT THIS ENTITY VERSION REPLACES
	STS_CD_ID UUID NOT NULL, -- THE STATUS OF THE ENTITY AT THIS VERSION
	TYP_CD_ID UUID, -- THE SUBCLASS OR TYPE WITHIN THE CLASS OF THE ENTITY
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME WHEN THE VERSION WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATED THIS VERSION OF THE ENTITY
	OBSLT_UTC TIMESTAMP, -- THE TIME WHEN THE VERSION WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THEUSER WHICH OBSOLETED THE VERSION
	CONSTRAINT PK_ENT_VRSN_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_ENT_VRSN_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_VRSN_RPLC_VRSN_SEQ_ID FOREIGN KEY (RPLC_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_ENT_VRSN_STS_CD_ID FOREIGN KEY (STS_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ENT_VRSN_TYP_CD_ID FOREIGN KEY (TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ENT_VRSN_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_ENT_VRSN_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_ENT_VRSN_STS_CD CHECK (IS_CD_SET_MEM(STS_CD_ID, 'EntityStatus')),
	CONSTRAINT CK_ENT_VRSN_OBSLT_USR CHECK (OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL OR OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL)
);
--#!

CREATE TRIGGER TG_ENT_VRSN_TBL_SEQ FOR ENT_VRSN_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.VRSN_SEQ_ID = NEXT VALUE FOR ENT_VRSN_SEQ;
END;
--#!

CREATE INDEX ENT_VRSN_STS_CD_ID_IDX ON ENT_VRSN_TBL(STS_CD_ID);
--#!
CREATE INDEX ENT_VRSN_ENT_ID_IDX ON ENT_VRSN_TBL(ENT_ID);
--#!


-- ENT POLICY ASSOCIATION
CREATE TABLE ENT_POL_ASSOC_TBL (
	SEC_POL_INST_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENT TO WHICH THE POLICY APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION OF THE ENT WHERE THE POLICY ASSOCIATION DID BECOME ENTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION OF THE ENT WHERE THE POLICY ASSOCIATION IS OBSOLETE,
	POL_ID UUID NOT NULL, -- THE IDENTIFIER OF THE POLICY WHICH IS ATTACHED TO THE ENT
	CONSTRAINT PK_ENT_POL_ASSOC_TBL PRIMARY KEY(SEC_POL_INST_ID),
	CONSTRAINT FK_ENT_POL_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_POL_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_POL_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_POL_POL_ID FOREIGN KEY (POL_ID) REFERENCES SEC_POL_TBL(POL_ID)
);
--#!

CREATE INDEX ENT_POL_ASSOC_POL_ID_IDX ON ENT_POL_ASSOC_TBL(POL_ID);
--#!
CREATE INDEX ENT_POL_ASSOC_VRSN_IDX ON ENT_POL_ASSOC_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- ENTITY RELATIONSHIP TABLE
CREATE TABLE ENT_REL_TBL (
	ENT_REL_ID UUID NOT NULL,
	SRC_ENT_ID UUID NOT NULL, -- THE SOURCE ENTITY OF THE RELATIONSHIP
	TRG_ENT_ID UUID NOT NULL, -- THE TARGET ENTITY OF THE RELATIONSHIP
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE SOURCE VERSION SEQUENCE WHERE THE RELATIONSHIP BECAME ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE SOURCE VERSION SEQUENCE WHERE THE RELATIONSHIP BECAME OBSOLETE
	REL_TYP_CD_ID UUID NOT NULL, -- THE TYPE OF RELATIONSHIP BETWEEN THE ENTITIES
	QTY BIGINT DEFAULT 1, -- THE NUMER OF THE TARGET ENTITY RELATED TO THE SOURCE ENTIYT
	CONSTRAINT PK_ENT_REL_TBL PRIMARY KEY (ENT_REL_ID),
	CONSTRAINT FK_ENT_REL_SRC_ENT_ID FOREIGN KEY (SRC_ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_REL_TRG_ENT_ID FOREIGN KEY (TRG_ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_REL_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_REL_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_REL_REL_TYP_CD_ID FOREIGN KEY (REL_TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ENT_REL_REL_TYPE_CD CHECK (IS_CD_SET_MEM(REL_TYP_CD_ID, 'EntityRelationshipType'))
);
--#!

CREATE INDEX ENT_REL_SRC_ENT_ID_IDX ON ENT_REL_TBL(SRC_ENT_ID);
--#!
CREATE INDEX ENT_REL_TRG_ENT_ID_IDX ON ENT_REL_TBL(TRG_ENT_ID);
--#!
CREATE INDEX ENT_REL_VRSN_IDX ON ENT_REL_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ent_rel_tbl_rel_typ_idx ON ent_rel_tbl (rel_typ_cd_id);
--#!
-- ENTITY ADDRESS TABLE
CREATE TABLE ENT_ADDR_TBL (
	ADDR_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE ADDRESS IS ATTACHED
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION WHEN THE ADDRESS RELATIONSHIP BECAME ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION WHEN THE ADDRESS RELATIOSHIP IS NOT ACTIVE
	USE_CD_ID UUID NOT NULL, -- INDICATES THE USE OF THE ADDRESS
	CONSTRAINT PK_ENT_ADDR_TBL PRIMARY KEY (ADDR_ID),
	CONSTRAINT FK_ENT_ADDR_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_ADDR_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_ADDR_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_ADDR_ADDR_USE_CD_ID FOREIGN KEY (USE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ENT_ADDR_USE_CD CHECK (IS_CD_SET_MEM(USE_CD_ID, 'AddressUse'))
);
--#!

-- INDEX FO ADDRESS
CREATE INDEX ENT_ADDR_ENT_ID_IDX ON ENT_ADDR_TBL(ENT_ID);
--#!
CREATE INDEX ENT_ADDR_VRSN_IDX ON ENT_ADDR_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- VALUE SEQUENCE
CREATE SEQUENCE ENT_ADDR_CMP_VAL_SEQ;
--#!

-- ENTITY ADDRESS VALUES TABLE
CREATE TABLE ENT_ADDR_CMP_VAL_TBL (
	VAL_SEQ_ID INTEGER NOT NULL,
	VAL VARCHAR(196) NOT NULL, -- THE VALUE OF THE COMPONENT
	CONSTRAINT PK_ENT_ADDR_CMP_VAL_TBL PRIMARY KEY (VAL_SEQ_ID)
);
--#!

CREATE TRIGGER TG_ENT_ADDR_CMP_VAL_TBL_SEQ FOR ENT_ADDR_CMP_VAL_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.VAL_SEQ_ID = NEXT VALUE FOR ENT_ADDR_CMP_VAL_SEQ;
END;
--#!

CREATE INDEX EN_ADDR_CMP_VAL_VAL_IDX ON ENT_ADDR_CMP_VAL_TBL(VAL);
--#!

-- ENTITY ADDRESS COMPONENT TABLE
CREATE TABLE ENT_ADDR_CMP_TBL (
	CMP_ID UUID NOT NULL,
	TYP_CD_ID UUID, -- THE TYPE OF THE COMPONENT (STREET, CITY, ETC.)
	VAL_SEQ_ID INTEGER NOT NULL, -- THE CHAR(16) FOR THE ADDRESS VALUE
	ADDR_ID UUID NOT NULL, -- THE CHAR(16) FOR THE ADDRESS TO WHICH THE COMPONENT APPLIES
	CONSTRAINT PK_ENT_ADDR_CMP_TBL PRIMARY KEY(CMP_ID),
	CONSTRAINT FK_ENT_ADDR_CMP_TYP_CD_ID FOREIGN KEY (TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ENT_ADDR_CMP_VAL_ID FOREIGN KEY (VAL_SEQ_ID) REFERENCES ENT_ADDR_CMP_VAL_TBL(VAL_SEQ_ID),
	CONSTRAINT FK_ENT_ADDR_CMP_ADDR_ID FOREIGN KEY (ADDR_ID) REFERENCES ENT_ADDR_TBL(ADDR_ID),
	CONSTRAINT CK_ENT_ADDR_CMP_TYP_CD CHECK (TYP_CD_ID IS NULL OR IS_CD_SET_MEM(TYP_CD_ID, 'AddressComponentType'))
);
--#!

CREATE INDEX ENT_ADDR_CMP_ADDR_ID_IDX ON ENT_ADDR_CMP_TBL(ADDR_ID);
--#!
CREATE INDEX ENT_ADDR_CMP_VAL_ID_IDX ON ENT_ADDR_CMP_TBL(VAL_SEQ_ID);
--#!

-- ENTITY NAME TABLE
CREATE TABLE ENT_NAME_TBL (
	NAME_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE NAME APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE ENTITY SEQUENCE AT WHICH THE NAME BECOMES ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE ENTITY SEQUENCE WHERE THE NAME IS NO LONGER ACTIVE
	USE_CD_ID UUID NOT NULL, -- THE USE OF THE NAME (LEGAL, ETC.)
	CONSTRAINT PK_ENT_NAME_TBL PRIMARY KEY (NAME_ID),
	CONSTRAINT FK_ENT_NAME_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_NAME_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_NAME_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_NAME_USE_CD_ID FOREIGN KEY (USE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ENT_NAME_USE_CD CHECK (IS_CD_SET_MEM(USE_CD_ID, 'NameUse'))
);
--#!

CREATE INDEX ENT_NAME_ENT_ID_IDX ON ENT_NAME_TBL(ENT_ID);
--#!
CREATE INDEX ENT_NAME_VRSN_IDX ON ENT_NAME_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

CREATE SEQUENCE NAME_VAL_SEQ;
--#!

-- ENTITY NAME COMPONENT
CREATE TABLE ENT_NAME_CMP_TBL (
	CMP_ID UUID NOT NULL,
	TYP_CD_ID UUID, -- THE TYPE OF COMPONENT (FAMILY, GIVEN, ETC);
	VAL_SEQ_ID INTEGER NOT NULL, -- THE PHONETIC CODE FOR THE NAME
	NAME_ID UUID NOT NULL, -- THE NAME TO WHICH THE COMPONENT APPLIES
	CMP_SEQ NUMERIC(18) NOT NULL,
	CONSTRAINT PK_ENT_NAME_CMP_TBL PRIMARY KEY (CMP_ID),
	CONSTRAINT FK_ENT_NAME_CMP_TYP_CD_ID FOREIGN KEY (TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ENT_NAME_CMP_PHON_VAL_ID FOREIGN KEY (VAL_SEQ_ID) REFERENCES PHON_VAL_TBL(VAL_SEQ_ID),
	CONSTRAINT FK_ENT_NAME_CMP_NAME_ID FOREIGN KEY (NAME_ID) REFERENCES ENT_NAME_TBL(NAME_ID),
	CONSTRAINT CK_ENT_NAME_CMP_TYP_CD CHECK (TYP_CD_ID IS NULL OR IS_CD_SET_MEM(TYP_CD_ID, 'NameComponentType'))
);
--#!

CREATE TRIGGER TG_ENT_NAME_CMP_VAL_SEQ FOR ENT_NAME_CMP_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.CMP_SEQ = NEXT VALUE FOR NAME_VAL_SEQ;
END;
--#!

CREATE INDEX ENT_NAME_CMP_NAME_ID_IDX ON ENT_NAME_CMP_TBL(NAME_ID);
--#!
CREATE INDEX ENT_NAME_CMP_PHON_VAL_ID_IDX ON ENT_NAME_CMP_TBL(VAL_SEQ_ID);
--#!

-- ENTITY EXTENSIONS TABLE
CREATE TABLE ENT_EXT_TBL (
	ENT_EXT_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE EXTENSION APPLIES
	EXT_TYP_ID UUID NOT NULL, -- THE TYPE OF ENTITY EXTENSION
	EXT_VAL BLOB, -- THE VALUE OF THE EXTENSION
	EXT_DISP VARCHAR(64), -- A DISPLAY OF THE ENTITY EXTENSION
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- EFFECTIVE VERSION IDENTIFIER
	OBSLT_VRSN_SEQ_ID INTEGER, -- OBSOLETIONS VERSION SEQ
	CONSTRAINT PK_ENT_EXT_TBL PRIMARY KEY (ENT_EXT_ID),
	CONSTRAINT FK_ENT_EXT_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_EXT_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_EXT_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_EXT_TYP_ID FOREIGN KEY (EXT_TYP_ID) REFERENCES EXT_TYP_TBL(EXT_TYP_ID)
);
--#!

CREATE INDEX ENT_EXT_ENT_ID_IDX ON ENT_EXT_TBL(ENT_ID);
--#!
CREATE INDEX ENT_EXT_VRSN_IDX ON ENT_EXT_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- ENTITY IDENTIFIER TABLE
CREATE TABLE ENT_ID_TBL (
	ENT_ID_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE IDENTIFIER IS ATTACHED
	ID_TYP_ID UUID, -- THE TYPE OF IDENTIIFER
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION WHEN THE IDENTIFIER WAS ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- OBSOLETE VERSION SEQUENCE ID
	AUT_ID UUID NOT NULL, -- THE ASSIGNING AUTHORITY OF THE IDENTIFIER
	ID_VAL VARCHAR(64) NOT NULL, -- THE VALUE OF THE IDENTIFIER
	CONSTRAINT PK_ENT_ID_TBL PRIMARY KEY (ENT_ID_ID),
	CONSTRAINT FK_ENT_ID_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_ID_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_ID_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_ID_AUT_ID FOREIGN KEY (AUT_ID) REFERENCES ASGN_AUT_TBL(AUT_ID)
);
--#!

-- TODO: MAYBE IS TO BE CHANGED 
CREATE FUNCTION IS_ENT_ID_UNQ (
	AUT_ID_IN UUID,
	ID_VAL_IN VARCHAR(64)
) RETURNS BOOLEAN AS
DECLARE VARIABLE VAR_EXISTING UUID;
BEGIN

	SELECT FIRST 1 ENT_ID_ID FROM ENT_ID_TBL NATURAL JOIN ASGN_AUT_TBL WHERE IS_UNQ = 1 AND AUT_ID = :AUT_ID_IN AND ID_VAL = :ID_VAL_IN AND OBSLT_VRSN_SEQ_ID IS NULL INTO VAR_EXISTING;

	IF (VAR_EXISTING IS NOT NULL) THEN
		RETURN TRUE;
	ELSE
		RETURN FALSE;
	
END;
--#!

CREATE INDEX ENT_ID_VRSN_IDX ON ENT_ID_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ENT_ID_ENT_ID_IDX ON ENT_ID_TBL(ENT_ID);
--#!
CREATE UNIQUE INDEX ENT_ID_ENT_VAL_UQ_IDX ON ENT_ID_TBL(EFFT_VRSN_SEQ_ID, AUT_ID, ID_VAL);
--#!

-- TELECOM ADDRESS
CREATE TABLE ENT_TEL_TBL (
	TEL_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE TELECOM ADDRESS APPLIES
	TYP_CD_ID UUID, -- THE TYPE OF ADDRESS (FAX, TEL, EMAIL, PAGER, ETC.)
	USE_CD_ID UUID NOT NULL, -- IDENTIIFES THE USE OF THE ADDRESS (HOME, WORK, ETC.)
	TEL_VAL VARCHAR(196) NOT NULL, -- THE VALUE OF THE ADDRESS
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION SEQUENCE WHEN THE ADDRESS IS ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION SEQUENCE WHEN TH ADDRESS IS OBSOLETE
	CONSTRAINT PK_ENT_TEL_TBL PRIMARY KEY (TEL_ID),
	CONSTRAINT FK_ENT_TEL_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_TEL_TYP_CD_ID FOREIGN KEY (TYP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ENT_TEL_USE_CD_ID FOREIGN KEY (USE_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_ENT_TEL_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_TEL_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT CK_ENT_TEL_TYP_CD CHECK (TYP_CD_ID IS NULL OR IS_CD_SET_MEM(TYP_CD_ID, 'TelecomAddressType')),
	CONSTRAINT CK_ENT_TEL_USE_CD CHECK (IS_CD_SET_MEM(USE_CD_ID, 'TelecomAddressUse'))
);
--#!

CREATE INDEX ENT_TEL_VRSN_IDX ON ENT_TEL_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ENT_TEL_ENT_ID_IDX ON ENT_TEL_TBL(ENT_ID);
--#!
CREATE INDEX ENT_TEL_VAL_IDX ON ENT_TEL_TBL(TEL_VAL);
--#!

-- PLACE TABLE
CREATE TABLE PLC_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY VERSION THIS PLACE REPRESENTS
	MOB_IND BOOLEAN DEFAULT FALSE NOT NULL, -- TRUE IF THE PLACE HAS NO FIXED ADDRESS
	LAT FLOAT, -- THE LATITUDE OF THE PLACE 
	LNG FLOAT, -- THE LONGITUDE OF THE PLACE
	CONSTRAINT PK_PLC_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_PLC_ENT_VRSN_TBL FOREIGN KEY (ENT_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID)
);
--#!

-- PLACE SERVICE TABLE
CREATE TABLE PLC_SVC_TBL (
	SVC_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE SERVICE APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- EFFECTIVE VERSION SEQUENCE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION WHEERE THE SERVICE WAS REMOVED
	SVC_CD_ID UUID NOT NULL, -- THE CONCEPT WHICH DEFINES THE SERVICE
	SCHDL BLOB SUB_TYPE TEXT NOT NULL, -- THE SERVICE SCHEDULE
	CONSTRAINT PK_PLC_SVC_TBL PRIMARY KEY (SVC_ID),
	CONSTRAINT FK_PLC_SVC_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT CK_PLC_SVC_ENT CHECK (IS_ENT_CLS(ENT_ID, 'ServiceDeliveryLocation')),
	CONSTRAINT FK_PLC_SVC_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_PLC_SVC_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_PLC_SVC_CD_ID FOREIGN KEY (SVC_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_PLC_SVC_CD CHECK (IS_CD_SET_MEM(SVC_CD_ID, 'ServiceCode'))
);
--#!

-- ORGANIZATION TABLE
CREATE TABLE ORG_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY VERSION TO WHICH THIS ORG APPLIES
	IND_CD_ID UUID, -- THE INDUSTRY CONCEPT OF THE ORGANIZATION
	CONSTRAINT PK_ORG_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_ORG_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID), 
	CONSTRAINT FK_ORG_IND_CD_ID FOREIGN KEY (IND_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ORG_IND_CD CHECK (IND_CD_ID IS NULL OR IS_CD_SET_MEM(IND_CD_ID, 'IndustryCode'))
);
--#!

-- APPLICATION ENTITY
CREATE TABLE APP_ENT_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE VERISON APPLIES
	SEC_APP_ID UUID, -- THE SECURITY APPLICATION ASSOCIATION EDITH THE ENTITY
	SOFT_NAME VARCHAR(64) NOT NULL, -- THE NAME OF THE SOFTWARE PRODUCT THIS APPLICATION ENTITY REPRESENTS
	VER_NAME VARCHAR(64), -- THE VERSION NAME OF THE ENTITY 
	VND_NAME VARCHAR(64), -- THE VENDOR NAME
	CONSTRAINT PK_APP_ENT_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_APP_ENT_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_APP_ENT_SEC_APP_ID FOREIGN KEY (SEC_APP_ID) REFERENCES SEC_APP_TBL(APP_ID)
);
--#!

CREATE INDEX APP_ENT_SEC_APP_ID_IDX ON APP_ENT_TBL(SEC_APP_ID);
--#!

-- DEVICE ENTITY 
CREATE TABLE DEV_ENT_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY VERSION TO WHICH THE DEVICE INFORMATION APPLIES
	SEC_DEV_ID UUID, -- THE SECURITY DEVICE TO WHICH THE DEVICE INFORMATION APPLIES
	MNF_NAME VARCHAR(64) NOT NULL, -- THE NAME THE MANUFACTURER GAVE TO THE DEVICE
	OS_NAME VARCHAR(64), -- THE NAME OF THE OPERATING SYSTEM ON THE DEVICE
	CONSTRAINT PK_DEV_ENT_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_DEV_ENT_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_DEV_SEC_DEV_ID FOREIGN KEY (SEC_DEV_ID) REFERENCES SEC_DEV_TBL(DEV_ID)
);
--#!

CREATE INDEX DEV_ENT_SEC_APP_ID_IDX ON DEV_ENT_TBL(SEC_DEV_ID);
--#!

-- MATERIALS TABLE
CREATE TABLE MAT_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY VERSION TO WHICH TH EMATERIAL DATA APPLIES
	EXP_UTC DATE, -- THE DATE WHEN THE MATERIAL EXPIRES
	FRM_CD_ID UUID, -- THE FORM OF THE MATERIAL (CAPSULES, INJECTION, ETC),
	QTY DECIMAL(18,4), -- THE QUANTITY OF THIS OBJECT IN THE PARENT OBJECT
	QTY_CD_ID UUID, -- IDENTIFIES THE QUANTITY UNITS OF MATERIAL 
	IS_ADM BOOLEAN DEFAULT FALSE NOT NULL, -- TRUE IF THE MATERIAL ISN'T A REAL MATERIAL, RATHER EXISTS FOR ADMINISTRATIVE TRACKING PURPOSES
	CONSTRAINT PK_MAT_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_MAT_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_MAT_FRM_CD_ID FOREIGN KEY (FRM_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_MAT_QTY_CD_ID FOREIGN KEY (QTY_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_MAT_FRM_CD CHECK (FRM_CD_ID IS NULL OR ASSRT_CD_CLS(FRM_CD_ID, 'Form')),
	CONSTRAINT CK_MAT_QTY_CD CHECK (QTY_CD_ID IS NULL OR ASSRT_CD_CLS(QTY_CD_ID, 'UnitOfMeasure'))
);
--#!

-- MANUFACTURED MATERIALS TABLE
CREATE TABLE MMAT_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE MATERIAL VERSION ID
	LOT_NO VARCHAR(32), -- THE LOT NUMBER OF THE MMAT
	CONSTRAINT PK_MMAT_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_MMAT_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES MAT_TBL(ENT_VRSN_ID)
);
--#!

CREATE INDEX MMAT_LOT_NO_IDX ON MMAT_TBL (LOT_NO);
--#!

-- PERSON TABLE
CREATE TABLE PSN_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY VERSION ID TO WHICH TH EPERSON INFO 
	DOB DATE, -- DATE OF BIRTH OF THE PERSON
	DOB_PREC CHAR(1) CHECK (DOB_PREC IN ('Y','M','D')), -- THE PRECISION OF TH EDATE
	CONSTRAINT PK_PSN_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_PSN_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES ENT_VRSN_TBL(ENT_VRSN_ID)
);
--#!

-- PERSON LANGUAGE COMMUNICATION TABLE
CREATE TABLE PSN_LNG_TBL (
	LNG_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE PERSON TO WHICH THE LANGUAGE APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION OF THE PERSON ENTITY WHERE THIS BECOMES ACTIVE
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE OBSOLETION VERISON OF THE PERSON LANGUAGE
	LNG_CS CHAR(5) NOT NULL, -- THE LANGUAGE CODE REPRESENTING THE COMMUNICATION
	PREF_IND BOOLEAN DEFAULT FALSE NOT NULL, -- PREFERENCE INDICATOR
	CONSTRAINT PK_PSN_LNG_TBL PRIMARY KEY (LNG_ID),
	CONSTRAINT FK_PSN_LNG_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_PSN_LNG_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_PSN_LNG_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID)
);
--#!

CREATE INDEX PSN_LNG_ENT_ID_IDX ON PSN_LNG_TBL(ENT_ID);
--#!
CREATE INDEX PSN_LNG_VRSN_IDX ON PSN_LNG_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!

-- PATIENT TABLE
CREATE TABLE PAT_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE VERSION ID OF THE ENTITY VERSION TO WHICH THE PATIENT INFO APPLIES
	GNDR_CD_ID UUID NOT NULL, -- THE GENDER OF THE PATIENT
	DCSD_UTC DATE, -- THE DATE THE PATIENT DIED
	DCSD_PREC CHAR(1) CHECK (DCSD_PREC IN ('Y','M','D')),
	MB_ORD NUMERIC(2), -- THE ORDER IN WHICH THE PATIENT WAS BORN
	MRTL_STS_CD_ID UUID, -- MARITAL STATUS KEY
	EDU_LVL_CD_ID UUID, -- EDUCATION LEVEL KEY
	LVN_ARG_CD_ID UUID, -- LIVING ARRANGEMENT
	RLGN_CD_ID UUID, -- RELIGION CODE
	ETH_GRP_CD_ID UUID, -- ETHNIC GROUP KEY
	CONSTRAINT PK_PAT_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_PAT_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES PSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_PAT_GNDR_CD_ID FOREIGN KEY (GNDR_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_PAT_GNDR_CD CHECK (IS_CD_SET_MEM(GNDR_CD_ID, 'AdministrativeGenderCode')),
	CONSTRAINT FK_PSN_MRTL_STS_CD_ID FOREIGN KEY (MRTL_STS_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_PAT_EDU_LVL_CD_ID FOREIGN KEY (EDU_LVL_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_PAT_LVN_ARG_CD_ID FOREIGN KEY (LVN_ARG_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_PAT_RLGN_CD_ID FOREIGN KEY (RLGN_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT FK_PAT_EHT_GRP_CD_ID FOREIGN KEY (ETH_GRP_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_PAT_MRTL_STS_CD CHECK (MRTL_STS_CD_ID IS NULL OR IS_CD_SET_MEM(MRTL_STS_CD_ID, 'MaritalStatus')),
	CONSTRAINT CK_PAT_EDU_LVL_CD CHECK (EDU_LVL_CD_ID IS NULL OR IS_CD_SET_MEM(EDU_LVL_CD_ID, 'EducationLevel')),
	CONSTRAINT CK_PAT_LVN_ARG_CD CHECK (LVN_ARG_CD_ID IS NULL OR IS_CD_SET_MEM(LVN_ARG_CD_ID, 'LivingArrangement')),
	CONSTRAINT CK_PAT_RLGN_CD CHECK (RLGN_CD_ID IS NULL OR IS_CD_SET_MEM(RLGN_CD_ID, 'Religion')),
	CONSTRAINT CK_PAT_ETH_GRP_CD CHECK (ETH_GRP_CD_ID IS NULL OR IS_CD_SET_MEM(ETH_GRP_CD_ID, 'Ethnicity'))
);
--#!

-- PROVIDER TABLE
CREATE TABLE PVDR_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE VERSION OF THE PERSON TO WHICH THE PROVIDER INFO APPLIES
	SPEC_CD_ID UUID, -- THE PROVIDER'S SPECIALTY
	CONSTRAINT PK_PVDR_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_PVDR_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES PSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_PVDR_SPEC_CD_ID FOREIGN KEY (SPEC_CD_ID) REFERENCES CD_TBL(CD_ID)
);
--#!

-- USER ENTITY TABLE
CREATE TABLE USR_ENT_TBL (
	ENT_VRSN_ID UUID NOT NULL, -- THE ENTITY VERSION OF THE PERSON THE ENTITY APPLIES TO
	SEC_USR_ID UUID NOT NULL, -- THE SECURITY USER IDENTIFIER OF THE USER ENTITY
	CONSTRAINT PK_USR_ENT_TBL PRIMARY KEY (ENT_VRSN_ID),
	CONSTRAINT FK_USR_ENT_VRSN_ID FOREIGN KEY (ENT_VRSN_ID) REFERENCES PSN_TBL(ENT_VRSN_ID),
	CONSTRAINT FK_USR_ENT_SEC_USR_ID FOREIGN KEY (SEC_USR_ID) REFERENCES SEC_USR_TBL(USR_ID)
);
--#!

CREATE INDEX USR_ENT_SEC_USR_ID_IDX ON USR_ENT_TBL(SEC_USR_ID);
--#!

-- CLINICAL PROTOCOL HANDLER
CREATE TABLE PROTO_HDLR_TBL (
	HDLR_ID UUID NOT NULL,
	HDLR_NAME VARCHAR(64) NOT NULL, -- THE NAME OF THE HANDLER (HUMAN READABLE)
	HDLR_CLS VARCHAR(196) NOT NULL, -- THE CLASS WHICH IS RESPONSIBLE FOR THE PROTOCOL EXECUTION
	IS_ACTIVE BOOLEAN DEFAULT TRUE NOT NULL, -- INDICATES WHETHER THE PROTOCOL IS ACTIVE
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME WHEN THE HANDLER WAS CREATED
	CRT_PROV_ID UUID NOT NULL , -- THE IDENTIFIER OF THE USER WHICH CREATED THE HANDLER
	OBSLT_UTC TIMESTAMP, -- THE TIME THE HANDLER WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE HANDLER
	CONSTRAINT PK_PROTO_HDLR_TBL PRIMARY KEY (HDLR_ID),
	CONSTRAINT FK_PROTO_HDLR_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_PROTO_HDLR_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_PROTO_HDLR_OBSLT_USR CHECK (OBSLT_UTC IS NULL AND OBSLT_PROV_ID IS NULL OR OBSLT_UTC IS NOT NULL AND OBSLT_PROV_ID IS NOT NULL)
);
--#!

-- CLINICAL PROTOCOL DEFINITION TABLE
CREATE TABLE PROTO_TBL (
	PROTO_ID UUID NOT NULL,
	PROTO_NAME VARCHAR(64) NOT NULL, -- NAME FO THE PROTOCOL (EX: CHILDHOOD VACCINATIONS)
	HDLR_ID UUID NOT NULL, -- THE HANDLER CLASS WHICH EXECUTES THE PROTOCOL
	OID VARCHAR(64), -- THE OID OF THE PROTOCOL
	DEFN BLOB, -- THE DEFINITION FILE WHICH DEFINES THE PROTOCOL IN A FORMAT THAT THE HANDLER CAN USE
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIME THE PROTOCOL DEFINITION WAS CREATE
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHICH CREATE THE PROTOCOL
	OBSLT_UTC TIMESTAMP, -- THE TIME WHEN THE PROTOCOL DEFINITION WAS OBSOLETED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE PROTOCL DEFINITION
	RPLC_PROTO_ID UUID, -- IF THE PROTOCOL REPLACES A PREVIOUS PROTOCOL
	CONSTRAINT PK_PROTO_TBL PRIMARY KEY (PROTO_ID),
	CONSTRAINT FK_PROTO_HDLR_ID FOREIGN KEY (HDLR_ID) REFERENCES PROTO_HDLR_TBL(HDLR_ID),
	CONSTRAINT FK_PROTO_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_PROTO_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_PROTO_RPLC_PROTO_ID FOREIGN KEY (RPLC_PROTO_ID) REFERENCES PROTO_TBL(PROTO_ID),
	CONSTRAINT CK_PROTO_OBSLT_USR CHECK (OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL OR OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL)
);
--#!

-- INDEX FOR PROTOCOL BY OID
CREATE UNIQUE INDEX PROTO_NAME_UQ_IDX ON PROTO_TBL(PROTO_NAME);
--#!

-- PROTOCOL TO ACT TABLE
CREATE TABLE ACT_PROTO_ASSOC_TBL (
	PROTO_ID UUID NOT NULL, 
	ACT_ID UUID NOT NULL, -- THE ACT TO WHICH THE PROTOCOL APPLIES
	SEQ INT NOT NULL, -- INDICATES THE SEQUENCE IN THE CARE PROTOCOL
	IS_COMPL BOOLEAN DEFAULT FALSE NOT NULL, -- INDICATES THAT THE ACT IS A TERMINAL STATE OF THE PROTOCOL
	STATE_DAT BLOB, -- ANY STATE DATA THE PROTOCOL HANDLER WISHES TO ATTACH
	CONSTRAINT PK_ACT_PROTO_ASSOC_TBL PRIMARY KEY (PROTO_ID, ACT_ID),
	CONSTRAINT FK_ACT_PROTO_ASSOC_PROTO_ID FOREIGN KEY (PROTO_ID) REFERENCES PROTO_TBL(PROTO_ID),
	CONSTRAINT FK_ACT_PROTO_ASSOC_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID)
);
--#!

CREATE INDEX ACT_PROTO_ASSOC_ACT_ID_IDX ON ACT_PROTO_ASSOC_TBL(ACT_ID);
--#!

-- ACT NOTES TABLE
CREATE TABLE ACT_NOTE_TBL (
	NOTE_ID UUID NOT NULL,
	ACT_ID UUID NOT NULL, -- THE ACT TO WHICH THE NOTE APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION OF HTE ACT WHERE THE NOTE WAS ADDED
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION OF THE ACT WHERE THE NOTE WAS REMOVED
	AUTH_ENT_ID UUID NOT NULL, -- THE UAHTOR WHO CREATED THE NOTE (SINCE A NOTE CAN BE ATTACHED WITHOUT CREATING A NEW VERSION)
	NOTE_TXT BLOB SUB_TYPE TEXT NOT NULL, -- THE NOTE BLOB SUB_TYPE TEXT
	CONSTRAINT PK_ACT_NOTE_TBL PRIMARY KEY (NOTE_ID),
	CONSTRAINT FK_ACT_NOTE_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_NOTE_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_NOTE_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_NOTE_AUTH_ENT_ID FOREIGN KEY (AUTH_ENT_ID) REFERENCES ENT_TBL(ENT_ID)
);
--#!

CREATE INDEX ACT_NOTE_VRSN_IDX ON ACT_NOTE_TBL (EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ACT_NOTE_ACT_ID_IDX ON ACT_NOTE_TBL(ACT_ID);
--#!

-- ENTITY NOTE TABLE
CREATE TABLE ENT_NOTE_TBL (
	NOTE_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE NOTE APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION OF HTE ENTITY WHERE THE NOTE WAS ADDED
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERSION OF THE ENTITY WHERE THE NOTE WAS REMOVED
	AUTH_ENT_ID UUID NOT NULL, -- THE UAHTOR WHO CREATED THE NOTE (SINCE A NOTE CAN BE ATTACHED WITHOUT CREATING A NEW VERSION)
	NOTE_TXT BLOB SUB_TYPE TEXT NOT NULL, -- THE NOTE BLOB SUB_TYPE TEXT
	CONSTRAINT PK_ENT_NOTE_TBL PRIMARY KEY (NOTE_ID),
	CONSTRAINT FK_ENT_NOTE_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ENT_NOTE_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_NOTE_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ENT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ENT_NOTE_AUTH_ENT_ID FOREIGN KEY (AUTH_ENT_ID) REFERENCES ENT_TBL(ENT_ID)
);
--#!

CREATE INDEX ENT_NOTE_VRSN_IDX ON ENT_NOTE_TBL (EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ENT_NOTE_ENT_ID_IDX ON ENT_NOTE_TBL(ENT_ID);
--#!

CREATE SEQUENCE ACT_PTCPT_SEQ;
--#!

-- ACT PARTICIPATION TABLE
CREATE TABLE ACT_PTCPT_TBL (
	ACT_PTCPT_ID UUID NOT NULL,
	ENT_ID UUID NOT NULL, -- THE ENTITY TO WHICH THE PARTICIPATION APPLIES
	ACT_ID UUID NOT NULL, -- THE ACT TO WHICH THE PARTICIPATION APPLIES
	EFFT_VRSN_SEQ_ID INTEGER NOT NULL, -- THE VERSION OF THE ACT WHERE THE PARTICIPATION IS ACTIVATED
	OBSLT_VRSN_SEQ_ID INTEGER, -- THE VERISON OF THE ACT WHERE THE PARTICIPATION IS NO LONGER ACTIVE
	QTY INT DEFAULT 1, -- THE QUANTITY OF ENTITY PARTICIPATING IN ACT
	ROL_CD_ID UUID NOT NULL, -- THE ROLE THAT THE ENTITY PLAYS IN ACT
	PTCPT_SEQ_ID INTEGER NOT NULL,
	CONSTRAINT PK_ACT_PTCPT_TBL PRIMARY KEY (ACT_PTCPT_ID),
	CONSTRAINT FK_ACT_PTCPT_ENT_ID FOREIGN KEY (ENT_ID) REFERENCES ENT_TBL(ENT_ID),
	CONSTRAINT FK_ACT_PTCPT_ACT_ID FOREIGN KEY (ACT_ID) REFERENCES ACT_TBL(ACT_ID),
	CONSTRAINT FK_ACT_PTCPT_EFFT_VRSN_SEQ_ID FOREIGN KEY (EFFT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_PTCPT_OBSLT_VRSN_SEQ_ID FOREIGN KEY (OBSLT_VRSN_SEQ_ID) REFERENCES ACT_VRSN_TBL(VRSN_SEQ_ID),
	CONSTRAINT FK_ACT_PTCPT_ROL_CD_ID FOREIGN KEY (ROL_CD_ID) REFERENCES CD_TBL(CD_ID),
	CONSTRAINT CK_ACT_PTCPT_ROL_CD CHECK (IS_CD_SET_MEM(ROL_CD_ID, 'ActParticipationType'))
);
--#!

CREATE TRIGGER TG_ACT_PTCPT_TBL_SEQ FOR ACT_PTCPT_TBL ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.PTCPT_SEQ_ID = NEXT VALUE FOR ACT_PTCPT_SEQ;
END;
--#!

CREATE INDEX ACT_PTCPT_ENT_ID_IDX ON ACT_PTCPT_TBL(ENT_ID);
--#!
CREATE INDEX ACT_PTCPT_ACT_ID_IDX ON ACT_PTCPT_TBL(ACT_ID);
--#!
CREATE INDEX ACT_PTCPT_VRSN_ID_IDX ON ACT_PTCPT_TBL(EFFT_VRSN_SEQ_ID, OBSLT_VRSN_SEQ_ID);
--#!
CREATE INDEX ACT_PTCPT_ACT_ROL_IDX ON ACT_PTCPT_TBL(ACT_ID, ROL_CD_ID);
--#!
CREATE INDEX ACT_PTCPT_ENT_ROL_IDX ON ACT_PTCPT_TBL(ENT_ID, ROL_CD_ID);
--#!

-- ALERT MESSAGES
CREATE TABLE MAIL_MSG_TBL (
	MAIL_MSG_ID UUID NOT NULL,
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- TIME THE ALERT WAS CREATED
	CRT_PROV_ID UUID NOT NULL, -- THE USER WHO CREATED THE ALERT
	OBSLT_UTC TIMESTAMP, -- THE TIME THE ALERT WAS REMOVED
	OBSLT_PROV_ID UUID, -- THE USER WHICH OBSOLETED THE ALERT
	UPD_UTC TIMESTAMP, -- THE TIME THE ALERT WAS UPDATED
	UPD_PROV_ID UUID, -- THE USER WHICH UPDATED THE ALERT
	FROM_INFO VARCHAR(128) NOT NULL, -- THE INFORMATION WHICH APPEARS IN THE FROM HEADER (EXAMPLE: THE FROM MIME HEADER)
	TO_INFO VARCHAR(128) NOT NULL, -- THE INFORMATION WHICH APPEARS IN THE TO HEADER (EXAMPLE: FROM MIME)
	MSG_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, -- THE TIMESTAMP OF THE MESSAGE
	SUBJ VARCHAR(196), -- THE SUBJECT OF THE MESSAGE
	BODY BLOB SUB_TYPE TEXT NOT NULL, -- THE BODY OF THE MESSAGE
	FLAGS INT DEFAULT 0 NOT NULL, -- FLAGS OF THE MESSAGE
	CONSTRAINT PK_MAIL_TBL PRIMARY KEY (MAIL_MSG_ID),
	CONSTRAINT FK_MAIL_CRT_PROV_ID FOREIGN KEY (CRT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_MAIL_UPD_PROV_ID FOREIGN KEY (UPD_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT FK_MAIL_OBSLT_PROV_ID FOREIGN KEY (OBSLT_PROV_ID) REFERENCES SEC_PROV_TBL(PROV_ID),
	CONSTRAINT CK_MAIL_UPD_USR CHECK (UPD_PROV_ID IS NULL AND UPD_UTC IS NULL OR UPD_PROV_ID IS NOT NULL AND UPD_UTC IS NOT NULL),
	CONSTRAINT CK_MAIL_OBSLT_USR CHECK (OBSLT_PROV_ID IS NULL AND OBSLT_UTC IS NULL OR OBSLT_PROV_ID IS NOT NULL AND OBSLT_UTC IS NOT NULL)
);
--#!

-- INDEX
CREATE INDEX MAIL_TO_INFO_IDX ON MAIL_MSG_TBL(TO_INFO);
--#!

-- ALERT RECIPIENT (RCPT TO) TABLE
CREATE TABLE MAIL_MSG_RCPT_TO_TBL (
	MAIL_MSG_ID UUID NOT NULL, -- THE ALERT TO WHICH THE RCPT TO APPLIES
	USR_ID UUID NOT NULL, -- THE RCPT TO USER 
	CONSTRAINT PK_MAIL_RCPT_TO_TBL PRIMARY KEY (MAIL_MSG_ID, USR_ID),
	CONSTRAINT FK_MAIL_RCPT_TO_MAIL_MSG_ID FOREIGN KEY (MAIL_MSG_ID) REFERENCES MAIL_MSG_TBL(MAIL_MSG_ID),
	CONSTRAINT FK_MAIL_RCPT_TO_USR_ID FOREIGN KEY (USR_ID) REFERENCES SEC_USR_TBL(USR_ID)
);
--#!

CREATE INDEX MAIL_RCPT_TO_USR_ID_IDX ON MAIL_MSG_RCPT_TO_TBL(USR_ID);
--#!
CREATE INDEX MAIL_RCPT_TO_MAIL_MSG_ID_IDX ON MAIL_MSG_RCPT_TO_TBL(MAIL_MSG_ID);
--#!


-- PATCHES TABLE
CREATE TABLE PATCH_DB_SYSTBL (
	PATCH_ID VARCHAR(24) NOT NULL, 
	APPLY_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
	CONSTRAINT PK_PTCH_DB_SYSTBL PRIMARY KEY (PATCH_ID)
);
--#!

-- VERSIONING AND PATCHING FUNCTIONS
CREATE FUNCTION REG_PATCH(PATCH_ID_IN VARCHAR(24)) RETURNS BOOLEAN AS 
BEGIN
	INSERT INTO PATCH_DB_SYSTBL (PATCH_ID) VALUES (:PATCH_ID_IN);
	RETURN TRUE;
END;
--#!

CREATE FUNCTION CK_PATCH(PATCH_ID_IN VARCHAR(24)) RETURNS BOOLEAN AS 
BEGIN
	RETURN (SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END AS r FROM PATCH_DB_SYSTBL WHERE PATCH_ID = :PATCH_ID_IN);
END;
--#!

-- GET THE SCHEMA VERSION
CREATE PROCEDURE GET_SCH_VRSN() RETURNS ( VER VARCHAR(10) ) AS
BEGIN
	FOR SELECT '1.1.0.0' FROM RDB$DATABASE
		INTO :VER
	DO BEGIN
		SUSPEND;
	END
END;
--#!

-- INDECIES FROM PATCHES
CREATE INDEX ent_addr_cmp_typ_cd_idx ON ent_addr_cmp_tbl(typ_cd_id);
--#!
CREATE INDEX act_ptcpt_rol_cd_idx ON act_ptcpt_tbl(rol_cd_id);
--#!

-- VALIDATION OF ENTITY RELATIONSHIPS
CREATE TABLE ent_rel_vrfy_cdtbl (
	ent_rel_vrfy_id UUID NOT NULL,
	rel_typ_cd_id UUID NOT NULL, -- THE TYPE OF RELATIONSHIP
	src_cls_cd_id UUID NOT NULL, -- THE CLASS CODE OF THE SOURCE ENTITY
	trg_cls_cd_id UUID NOT NULL, -- THE CLASS CODE OF THE TARGET ENTITY
	err_desc VARCHAR(128) NOT NULL, -- THE ERROR CONDITION
	CONSTRAINT pk_ent_rel_vrfy_cdtbl PRIMARY KEY (ent_rel_vrfy_id),
	CONSTRAINT fk_ent_rel_vrfy_rel_typ_cd FOREIGN KEY (rel_typ_cd_id) REFERENCES cd_tbl(cd_id),
	CONSTRAINT fk_ent_rel_vrfy_src_cls_cd FOREIGN KEY (src_cls_cd_id) REFERENCES cd_tbl(cd_id),
	CONSTRAINT fk_ent_rel_vrfy_trg_cls_cd FOREIGN KEY (trg_cls_cd_id) REFERENCES cd_tbl(cd_id)
);
--#!

CREATE TRIGGER TG_ENT_REL_VRFY_CDTBL_SEQ FOR ent_rel_vrfy_cdtbl ACTIVE BEFORE INSERT POSITION 0 AS BEGIN
	NEW.ent_rel_vrfy_id = gen_uuid();
END;
--#!

CREATE UNIQUE INDEX ent_rel_vrfy_src_trg_unq ON ent_rel_vrfy_cdtbl(rel_typ_cd_id, src_cls_cd_id, trg_cls_cd_id);
--#!

CREATE EXCEPTION invalid_relationships 'O9001';
--#!

-- TRIGGER FUNCTION WHICH VERIFIES ENTITY RELATIONSHIP
CREATE TRIGGER TG_VRFY_ENT_REL FOR ENT_REL_TBL BEFORE INSERT POSITION 0 AS 
DECLARE VARIABLE VAR_VALIDATION VARCHAR(128);
BEGIN
	SELECT  ent_rel_vrfy_cdtbl.err_desc
	FROM 
		ent_rel_vrfy_cdtbl 
		INNER JOIN ent_tbl src_ent ON (src_ent.ent_id = NEW.src_ent_id)
		INNER JOIN ent_tbl trg_ent ON (trg_ent.ent_id = NEW.trg_ent_id)
	WHERE 
		rel_typ_cd_id = NEW.rel_typ_cd_id 
		AND src_cls_cd_id = src_ent.cls_cd_id 
		AND trg_cls_cd_id = trg_ent.cls_cd_id
	INTO VAR_VALIDATION;
	
	IF (VAR_VALIDATION IS NULL AND NEW.obslt_vrsn_seq_id IS NULL) THEN
		EXCEPTION invalid_relationships 
			'Validation error: Relationship ' || uuid_to_char(NEW.rel_typ_cd_id) || ' between ' || uuid_to_char(NEW.src_ent_id) || ' > ' || uuid_to_char(NEW.trg_ent_id) || ' is invalid';
END;
--#!

 -- UPGRADE CONSTRAINTS - THIS MAY TAKE SOME TIME
 ALTER TABLE CD_VRSN_TBL DROP CONSTRAINT CK_CD_VRSN_STS_CD_ID;
--#!
 ALTER TABLE CD_VRSN_TBL ADD CONSTRAINT CK_CD_VRSN_STS_CD_ID CHECK (CK_IS_CD_SET_MEM(STS_CD_ID, 'ConceptStatus', FALSE));
--#!
	
 ALTER TABLE ACT_VRSN_TBL DROP CONSTRAINT CK_ACT_VRSN_STS_CD;
--#!
 ALTER TABLE ACT_VRSN_TBL ADD CONSTRAINT CK_ACT_VRSN_STS_CD CHECK (CK_IS_CD_SET_MEM(STS_CD_ID, 'ActStatus', FALSE));
--#!
	
 ALTER TABLE ENT_VRSN_TBL DROP CONSTRAINT CK_ENT_VRSN_STS_CD;
--#!
 ALTER TABLE ENT_VRSN_TBL ADD CONSTRAINT CK_ENT_VRSN_STS_CD CHECK (CK_IS_CD_SET_MEM(STS_CD_ID, 'EntityStatus', FALSE));
--#!

 ALTER TABLE ACT_TBL DROP CONSTRAINT CK_ACT_CLS_CD;
--#!
 ALTER TABLE ACT_TBL DROP CONSTRAINT CK_ACT_MOD_CD;
--#!
 ALTER TABLE ACT_TBL ADD CONSTRAINT CK_ACT_CLS_CD CHECK (CK_IS_CD_SET_MEM(CLS_CD_ID, 'ActClass', FALSE));
--#!
 ALTER TABLE ACT_TBL ADD CONSTRAINT CK_ACT_MOD_CD CHECK (CK_IS_CD_SET_MEM(MOD_CD_ID, 'ActMood', FALSE));
--#!
 
 ALTER TABLE ACT_VRSN_TBL DROP CONSTRAINT CK_ACT_VRSN_RSN_CD;
--#!
 ALTER TABLE ACT_VRSN_TBL ADD CONSTRAINT CK_ACT_VRSN_RSN_CD CHECK (RSN_CD_ID IS NULL OR CK_IS_CD_SET_MEM(RSN_CD_ID, 'ActReason', TRUE));
--#!

 ALTER TABLE ACT_REL_TBL DROP CONSTRAINT CK_ACT_REL_REL_TYP_CD;
--#!
 ALTER TABLE ACT_REL_TBL ADD CONSTRAINT CK_ACT_REL_REL_TYP_CD CHECK (CK_IS_CD_SET_MEM(REL_TYP_CD_ID, 'ActRelationshipType', TRUE));
--#!
 
 ALTER TABLE OBS_TBL DROP CONSTRAINT CK_OBS_INT_CD;
--#!
 ALTER TABLE OBS_TBL ADD CONSTRAINT CK_OBS_INT_CD CHECK (INT_CD_ID IS NULL OR CK_IS_CD_SET_MEM(INT_CD_ID, 'ActInterpretation', TRUE));
--#!

 ALTER TABLE ENT_TBL DROP CONSTRAINT CK_ENT_CLS_CD;
--#!
 ALTER TABLE ENT_TBL ADD CONSTRAINT CK_ENT_CLS_CD CHECK (CK_IS_CD_SET_MEM(CLS_CD_ID, 'EntityClass', FALSE));
--#!

 ALTER TABLE ENT_REL_TBL DROP CONSTRAINT CK_ENT_REL_REL_TYPE_CD;
--#!
 ALTER TABLE ENT_REL_TBL ADD CONSTRAINT CK_ENT_REL_REL_TYPE_CD CHECK (CK_IS_CD_SET_MEM(REL_TYP_CD_ID, 'EntityRelationshipType', FALSE));
--#!

 ALTER TABLE ENT_ADDR_TBL DROP CONSTRAINT CK_ENT_ADDR_USE_CD;
--#!
 ALTER TABLE ENT_ADDR_TBL ADD CONSTRAINT CK_ENT_ADDR_USE_CD CHECK (CK_IS_CD_SET_MEM(USE_CD_ID, 'AddressUse', FALSE));
--#!

 ALTER TABLE ENT_ADDR_CMP_TBL DROP CONSTRAINT CK_ENT_ADDR_CMP_TYP_CD;
--#!
 ALTER TABLE ENT_ADDR_CMP_TBL ADD CONSTRAINT CK_ENT_ADDR_CMP_TYP_CD CHECK (TYP_CD_ID IS NULL OR CK_IS_CD_SET_MEM(TYP_CD_ID, 'AddressComponentType', FALSE));
--#!

 ALTER TABLE ENT_NAME_TBL DROP CONSTRAINT CK_ENT_NAME_USE_CD;
--#!
 ALTER TABLE ENT_NAME_TBL ADD CONSTRAINT CK_ENT_NAME_USE_CD CHECK (CK_IS_CD_SET_MEM(USE_CD_ID, 'NameUse', FALSE));
--#!

 ALTER TABLE ENT_NAME_CMP_TBL DROP CONSTRAINT CK_ENT_NAME_CMP_TYP_CD;
--#!
 ALTER TABLE ENT_NAME_CMP_TBL ADD CONSTRAINT CK_ENT_NAME_CMP_TYP_CD CHECK (TYP_CD_ID IS NULL OR CK_IS_CD_SET_MEM(TYP_CD_ID, 'NameComponentType', FALSE));
--#!

 ALTER TABLE ENT_TEL_TBL DROP CONSTRAINT CK_ENT_TEL_TYP_CD;
--#!
 ALTER TABLE ENT_TEL_TBL ADD CONSTRAINT CK_ENT_TEL_TYP_CD CHECK (TYP_CD_ID IS NULL OR CK_IS_CD_SET_MEM(TYP_CD_ID, 'TelecomAddressType', TRUE));
--#!

 ALTER TABLE ENT_TEL_TBL DROP CONSTRAINT CK_ENT_TEL_USE_CD;
--#!
 ALTER TABLE ENT_TEL_TBL ADD CONSTRAINT CK_ENT_TEL_USE_CD CHECK (CK_IS_CD_SET_MEM(USE_CD_ID, 'TelecomAddressUse', FALSE));
--#!

 ALTER TABLE PLC_SVC_TBL DROP CONSTRAINT CK_PLC_SVC_CD;
--#!
 ALTER TABLE PLC_SVC_TBL ADD CONSTRAINT CK_PLC_SVC_CD CHECK (CK_IS_CD_SET_MEM(SVC_CD_ID, 'ServiceCode', FALSE));
--#!

 ALTER TABLE ORG_TBL DROP CONSTRAINT CK_ORG_IND_CD;
--#!
 ALTER TABLE ORG_TBL ADD CONSTRAINT CK_ORG_IND_CD CHECK (IND_CD_ID IS NULL OR CK_IS_CD_SET_MEM(IND_CD_ID, 'IndustryCode', TRUE)); 
--#!

 ALTER TABLE PAT_TBL DROP CONSTRAINT CK_PAT_GNDR_CD;
--#!
 ALTER TABLE PAT_TBL ADD CONSTRAINT CK_PAT_GNDR_CD CHECK (CK_IS_CD_SET_MEM(GNDR_CD_ID, 'AdministrativeGenderCode', TRUE));
--#!

 ALTER TABLE ACT_PTCPT_TBL DROP CONSTRAINT CK_ACT_PTCPT_ROL_CD;
--#!
 ALTER TABLE ACT_PTCPT_TBL ADD 	CONSTRAINT CK_ACT_PTCPT_ROL_CD CHECK (CK_IS_CD_SET_MEM(ROL_CD_ID, 'ActParticipationType', TRUE));
--#!
INSERT INTO SEC_PROV_TBL (PROV_ID, USR_ID, APP_ID) VALUES (char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'), char_to_uuid('FADCA076-3690-4A6E-AF9E-F1CD68E8C7E8'), char_to_uuid('4c5b9f8d-49f4-4101-9662-4270895224b2'));
--#!

-- CREATE USER CLASSES   
INSERT INTO SEC_USR_CLS_CDTBL (CLS_ID, MNEMONIC) VALUES (char_to_uuid('33932B42-6F4B-4659-8849-6ACA54139D8E'),'HumanUser');
--#!
INSERT INTO SEC_USR_CLS_CDTBL (CLS_ID, MNEMONIC) VALUES (char_to_uuid('E9CD4DAD-2759-4022-AB07-92FCFB236A98'),'ApplicationUser');
--#!
INSERT INTO SEC_USR_CLS_CDTBL (CLS_ID, MNEMONIC) VALUES (char_to_uuid('9F71BB34-9691-440F-8249-9C831EA16D58'),'SystemUser');
--#!

-- Create a system user
INSERT INTO SEC_USR_TBL (USR_ID, USR_NAME, PASSWD, SEC_STMP, CLS_ID, FAIL_LOGIN) VALUES (char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'), 'SYSTEM','XXXX','XXXX', char_to_uuid('9F71BB34-9691-440F-8249-9C831EA16D58'), 0);
--#!
-- Create the anonymous user
INSERT INTO SEC_USR_TBL (USR_ID, USR_NAME, PASSWD, SEC_STMP, CLS_ID) VALUES (char_to_uuid('C96859F0-043C-4480-8DAB-F69D6E86696C'), 'ANONYMOUS','XXXX','XXXX', char_to_uuid('9F71BB34-9691-440F-8249-9C831EA16D58'));    
--#!

-- SET users to created by anonymous
UPDATE SEC_USR_TBL SET CRT_PROV_ID = char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8');
--#!

-- BUILT IN OPENIZ POLICIES
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('da73c05a-3159-48c8-bbcb-741911d91cd2'), '1.3.6.1.4.1.33349.3.1.5.9.2', 'Unrestricted All', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('ea73c05a-3159-48c8-bbcb-741911d91cd2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0', 'Unrestricted Administrative Function', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('d80ac1cf-3d6e-429f-a4a0-88c0bbbc839d'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.1', 'Change Password', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('9c0d65ac-613e-4a67-8bc6-5ce2c0b42160'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.2', 'Create Role', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('79bcc227-0d13-4fbf-a83e-f2b9fce34151'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.3', 'Alter Role', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('ab8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.4', 'Create Identity', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('bb8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.5', 'Create Device', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('cb8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.6', 'Create Application', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('db8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.7', 'Administer Concept Dictionary', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('eb8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.8', 'Alter Identity', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('fb8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.9', 'Alter Policy', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('fa8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.0.10', 'Administer Data Warehouse', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));

--#!

INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), '1.3.6.1.4.1.33349.3.1.5.9.2.1', 'Login', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('e15b96ab-646c-4c00-9a58-ea09eee67d7c'), '1.3.6.1.4.1.33349.3.1.5.9.2.1.0', 'Login as a Service', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('f6840336-4e20-4bc0-b965-baa6d7c80be3'), '1.3.6.1.4.1.33349.3.1.5.9.2.2', 'Unrestricted Clinical Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('b81daf47-17a5-465e-a5fd-706b168b0265'), '1.3.6.1.4.1.33349.3.1.5.9.2.2.0', 'Query Clinical Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('d7276921-a078-4348-95f2-ed3cde83e607'), '1.3.6.1.4.1.33349.3.1.5.9.2.2.1', 'Write Clinical Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('2e027dee-ede4-4731-b7fa-cb67ae0586be'), '1.3.6.1.4.1.33349.3.1.5.9.2.2.2', 'Delete Clinical Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('5fb731bf-4e59-4863-80bd-51757d58ea3b'), '1.3.6.1.4.1.33349.3.1.5.9.2.2.3', 'Read Clinical Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('5fb731bf-4e59-4863-80bd-51757d58ea9a'), '1.3.6.1.4.1.33349.3.1.5.9.2.2.4', 'Export Clinical Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa124aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.1.0', 'Write Materials', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa125aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.1.1', 'Delete Materials', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa126aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.0.1.2', 'Read Materials', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa127aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.0.1.3', 'Query Materials', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa224aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.2.0', 'Write Places & Orgs', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa225aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.2.1', 'Delete Places & Orgs', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa226aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.0.2.2', 'Read Places & Orgs', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('baa227aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.0.2.3', 'Query Places & Orgs', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('dea891aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.999', 'Override Disclosure', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('eea891aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4', 'Unrestricted Metadata', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('fea891aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.4.0', 'Read Metadata', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('0ea891aa-224d-4859-81b3-c1eb2750067e'), '1.3.6.1.4.1.33349.3.1.5.9.2.10', 'Access Client Administrative Function', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('0a8642cb-28e4-4e9e-bd7b-d6df72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.5', 'Unrestricted Data Warehouse', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('1a8642cb-28e4-4e9e-bd7b-d6df72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.5.0', 'Write Warehouse Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('2a8642cb-28e4-4e9e-bd7b-d6df72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.5.1', 'Delete Warehouse Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('3a8642cb-28e4-4e9e-bd7b-d6df72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.5.2', 'Read Warehouse Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID) VALUES (char_to_uuid('4a8642cb-28e4-4e9e-bd7b-d6df72b729b2'), '1.3.6.1.4.1.33349.3.1.5.9.2.5.3', 'Query Warehouse Data', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO SEC_POL_TBL (POL_ID, OID, POL_NAME, CRT_PROV_ID, IS_ELEV) VALUES (char_to_uuid('36f1ed35-552e-421a-8f59-629561ab9eb6'), '1.3.6.1.4.1.33349.3.1.5.9.3', 'Restricted Information', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'), true);
--#!

-- INSERT THE DEFAULT ASSOCIATIONS
-- CREATE USERS ROLE
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('f4e58ae8-8bbd-4635-a6d4-8a195b143436'), 'USERS', 'Group for users who have login access', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('f4e58ae8-8bbd-4635-a6d4-8a195b143436'), 2); -- GRANT Login
--#!

-- CREATE ADMINISTRATORS ROLE
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 'ADMINISTRATORS', 'Group for users who have administrative access', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('ea73c05a-3159-48c8-bbcb-741911d91cd2'), char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 2); -- GRANT Access Administrative Function
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 2); -- GRANT Login
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('f6840336-4e20-4bc0-b965-baa6d7c80be3'), char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 0); -- DENY Unrestricted Clinical Data
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('dea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 0); -- DENY Override disclosure
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('0ea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 2); -- GRANT Local Administrator
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('eea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('f6d2ba1d-5bb5-41e3-b7fb-2ec32418b2e1'), 2); -- GRANT Unrestricted Metadata
--#!


-- CLINICAL STAFF
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('43167DCB-6F77-4F37-8222-133E675B4434'), 'CLINICAL_STAFF', 'Group for clinic staff', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('ea73c05a-3159-48c8-bbcb-741911d91cd2'), char_to_uuid('43167DCB-6F77-4F37-8222-133E675B4434'), 0); -- GRANT Access Administrative Function
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('43167DCB-6F77-4F37-8222-133E675B4434'), 2); -- GRANT Login
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('f6840336-4e20-4bc0-b965-baa6d7c80be3'), char_to_uuid('43167DCB-6F77-4F37-8222-133E675B4434'), 2); -- GRANT Unrestricted Clinical Data
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('dea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('43167DCB-6F77-4F37-8222-133E675B4434'), 0); -- DENY Override disclosure
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('fea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('43167DCB-6F77-4F37-8222-133E675B4434'), 2); -- GRANT Read Metadata Administrator
--#!

-- CREATE ROLE SYSTEM WHICH IS DENIED LOGIN
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('c3ae21d2-fc23-4133-ba42-b0e0a3b817d7'), 'SYSTEM', 'Group for user SYSTEM. Identifies the functions that internal system functions have access to. EDITING THIS ROLE MAY CAUSE SYSTEM FAILURE', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_USR_ROL_ASSOC_TBL (ROL_ID, USR_ID) VALUES (char_to_uuid('c3ae21d2-fc23-4133-ba42-b0e0a3b817d7'), char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('DA73C05A-3159-48C8-BBCB-741911D91CD2'), char_to_uuid('c3ae21d2-fc23-4133-ba42-b0e0a3b817d7'), 2); -- GRANT UNRESTRICTED ALL
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('c3ae21d2-fc23-4133-ba42-b0e0a3b817d7'), 0); -- DENY Login
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('dea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('c3ae21d2-fc23-4133-ba42-b0e0a3b817d7'), 0); -- DENY Override disclosure
--#!

-- CREATE ROLE ANONYMOUS WHICH IS DENIED ALL CLINICAL 
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), 'ANONYMOUS', 'Group for user ANONYMOUS. Identifies the functions that non-logged in users have access to. EDITING THIS ROLE MAY INTRODUCE SECURITY BREACHES', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_USR_ROL_ASSOC_TBL (ROL_ID, USR_ID) VALUES (char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), char_to_uuid('C96859F0-043C-4480-8DAB-F69D6E86696C'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('ea73c05a-3159-48c8-bbcb-741911d91cd2'), char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), 0); -- DENY Access Administrative Function
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), 0); -- DENY Login
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('f6840336-4e20-4bc0-b965-baa6d7c80be3'), char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), 0); -- DENY Unrestricted Clinical Data
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('dea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), 0); -- DENY Override disclosure
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('fea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('dadbd858-13c5-44a3-ad7d-1c44cecaa4b6'), 0); -- GRANT Read Metadata
--#!

-- CREATE SYNCHRONIZERS ROLE
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('54B7677C-682B-425F-A937-3AA03D5951F1'), 'SYNCHRONIZERS', 'Group for user SYNCHRONIZERS. Identifies the functions that are used for synchronization. EDITING THIS ROLE MAY INTRODUCE SECURITY BREACHES', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('e15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('54B7677C-682B-425F-A937-3AA03D5951F1'), 2); -- GRANT AS Service Login
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('f6840336-4e20-4bc0-b965-baa6d7c80be3'), char_to_uuid('54B7677C-682B-425F-A937-3AA03D5951F1'), 2); -- GRANT Unrestricted Clinical Data
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('fea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('54B7677C-682B-425F-A937-3AA03D5951F1'), 2); -- GRANT Read Metadata
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('eea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('54B7677C-682B-425F-A937-3AA03D5951F1'), 2); -- GRANT Unrestricted metadata
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('dea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('54B7677C-682B-425F-A937-3AA03D5951F1'), 0); -- DENY Override disclosure
--#!

-- CREATE DEVICE ROLE
INSERT INTO SEC_ROL_TBL (ROL_ID, ROL_NAME, DESCR, CRT_PROV_ID) VALUES (char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 'DEVICE', 'Represents a device in the system. Identifies the functions that are used for devices. EDITING THIS ROLE MAY INTRODUCE SECURITY BREACHES', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('0ea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 2); -- GRANT Access Client Administrative Function
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d80ac1cf-3d6e-429f-a4a0-88c0bbbc839d'), char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 0); -- DENY Change Any Password
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('eb8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 2); -- GRANT Alter Identity
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('ab8642cb-28e4-4e9e-bd7b-d6dc72b729b2'), char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 2); -- GRANT Create Identity
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('d15b96ab-646c-4c00-9a58-ea09eee67d7c'), char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 2); -- GRANT Login
--#!
INSERT INTO SEC_ROL_POL_ASSOC_TBL (SEC_POL_INST_ID, POL_ID, ROL_ID, POL_ACT)  VALUES (gen_uuid(), char_to_uuid('fea891aa-224d-4859-81b3-c1eb2750067e'), char_to_uuid('613d05a0-dd0d-4516-a30c-e733741885f0'), 2); -- GRANT Read Metadata
--#!

-- DEFAULT PHONETIC ALGORITHMS
INSERT INTO PHON_ALG_TBL (ALG_ID, ALG_NAME, HDLR_CLS, CRT_PROV_ID)  VALUES (char_to_uuid('402cd339-d0e4-46ce-8fc2-12a4b0e17226'), 'NONE', NULL, char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO PHON_ALG_TBL (ALG_ID, ALG_NAME, HDLR_CLS, CRT_PROV_ID)  VALUES (char_to_uuid('3352a79a-d2e0-4e0c-9b48-6fd2a202c681'), 'SOUNDEX', 'SanteDB.Core.Services.Impl.PhoneticAlgorithms.SoundexPhoneticAlgorithmHandler, SanteDB.Core, Version=0.6.0.0', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO PHON_ALG_TBL (ALG_ID, ALG_NAME, HDLR_CLS, CRT_PROV_ID)  VALUES (char_to_uuid('d79a4dc6-66a6-4602-8fcb-7dc09a895793'), 'METAPHONE', 'SanteDB.Core.Services.Impl.PhoneticAlgorithms.MetaphonePhoneticAlgorithmHandler, SanteDB.Core, Version=0.6.0.0', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO CD_REL_TYP_CDTBL (REL_TYP_ID, REL_NAME, MNEMONIC, CRT_PROV_ID) VALUES (char_to_uuid('2c4dafc2-566a-41ae-9ebc-3097d7d22f4a'), 'Same as', 'SameAs', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO CD_REL_TYP_CDTBL (REL_TYP_ID, REL_NAME, MNEMONIC, CRT_PROV_ID) VALUES (char_to_uuid('ad27293d-433c-4b75-88d2-b5360cd95450'), 'Inverse of', 'InverseOf', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO CD_REL_TYP_CDTBL (REL_TYP_ID, REL_NAME, MNEMONIC, CRT_PROV_ID) VALUES (char_to_uuid('a159d45b-3c34-4e1b-9b75-9193a7528ced'), 'Member of', 'MemberOf', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO CD_REL_TYP_CDTBL (REL_TYP_ID, REL_NAME, MNEMONIC, CRT_PROV_ID) VALUES (char_to_uuid('ae8b4f2f-009f-4e0d-b35e-5a89555c5947'), 'Negation of', 'NegationOf', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO CD_REL_TYP_CDTBL (REL_TYP_ID, REL_NAME, MNEMONIC, CRT_PROV_ID) VALUES (char_to_uuid('ae8b4f2f-009f-4e0d-b35e-5a89555c5980'), 'Wider-Than', 'WiderThan', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!
INSERT INTO CD_REL_TYP_CDTBL (REL_TYP_ID, REL_NAME, MNEMONIC, CRT_PROV_ID) VALUES (char_to_uuid('ae8b4f2f-009f-4e0d-b35e-5a89555c5990'), 'Narrower-Than', 'NarrowerThan', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!

INSERT INTO SEC_APP_TBL (APP_ID, APP_PUB_ID, APP_SCRT, CRT_PROV_ID) VALUES (char_to_uuid('4c5b9f8d-49f4-4101-9662-4270895224b2'), 'SYSTEM', 'XXXXXX', char_to_uuid('fadca076-3690-4a6e-af9e-f1cd68e8c7e8'));
--#!


ALTER TABLE SEC_PROV_TBL ADD CONSTRAINT FK_SEC_PROV_USR_TBL FOREIGN KEY (USR_ID) REFERENCES SEC_USR_TBL(USR_ID);
--#!
ALTER TABLE SEC_PROV_TBL ADD CONSTRAINT FK_SEC_PROV_DEV_TBL FOREIGN KEY (DEV_ID) REFERENCES SEC_DEV_TBL(DEV_ID);
--#!
ALTER TABLE SEC_PROV_TBL ADD CONSTRAINT FK_SEC_PROV_APP_TBL FOREIGN KEY (APP_ID) REFERENCES SEC_APP_TBL(APP_ID);
--#!

-- SECURITY SESSIONS TABLE
CREATE TABLE SEC_SES_TBL (
	SES_ID UUID NOT NULL,
	CRT_UTC TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL , -- THE TIME WHEN THE SESSION WAS ESTABLISHED
	EXP_UTC TIMESTAMP NOT NULL, -- THE TIME WHEN THE SESSION WILL EXPIRE
	APP_ID UUID NOT NULL, -- THE SECURITY APPLICATION WHICH THE SESSION IS ESTABLISHED FOR
	USR_ID UUID, -- THE USER IDENTIFIER (APPLICATION USER IF APPLICATION GRANT)
	DEV_ID UUID, -- THE DEVICE IDENTIFIER
	RFRSH_TKN VARCHAR(128) UNIQUE NOT NULL, -- THE REFRESH TOKEN FOR THE OBJECT 
	RFRSH_EXP_UTC TIMESTAMP NOT NULL, -- THE TIME THAT THE REFRESH TOKEN EXPIRES
	AUD VARCHAR(32) NOT NULL, -- THE REMOTE IP ADDRESS THAT ESTABLISHED THE SESSION
	CONSTRAINT PK_SEC_SES_TBL PRIMARY KEY (SES_ID),
	CONSTRAINT FK_SEC_SES_APP_ID FOREIGN KEY (APP_ID) REFERENCES SEC_APP_TBL(APP_ID),
	CONSTRAINT FK_SEC_SES_USR_ID FOREIGN KEY (USR_ID) REFERENCES SEC_USR_TBL(USR_ID),
	CONSTRAINT FK_SEC_SES_DEV_ID FOREIGN KEY (DEV_ID) REFERENCES SEC_DEV_TBL(DEV_ID),
	CONSTRAINT CK_SEC_SES_EXP CHECK (EXP_UTC > CRT_UTC),
	CONSTRAINT CK_SEC_SES_RFRSH_EXP CHECK (RFRSH_EXP_UTC > EXP_UTC)
);
--#!

-- SECURITY SESSION CLAIMS TABLE
CREATE TABLE SEC_SES_CLM_TBL ( 
	CLM_ID UUID NOT NULL,
	SES_ID UUID NOT NULL, -- THE SESSION TO WHICH THE CLAIM BELONGS
    CLM_TYP VARCHAR(128) NOT NULL, -- THE TYPE OF CLAIM
    CLM_VAL VARCHAR(128) NOT NULL, -- THE VALUE OF THE CLAIM
	CONSTRAINT PK_SEC_SES_CLM_TBL PRIMARY KEY (CLM_ID),
	CONSTRAINT FK_SEC_SES_CLM_SES_ID FOREIGN KEY (SES_ID) REFERENCES SEC_SES_TBL(SES_ID)
);
--#!

ALTER TABLE ENT_VRSN_TBL ADD CRT_ACT_ID UUID;
--#!
ALTER TABLE ENT_VRSN_TBL ADD CONSTRAINT FK_ENT_VRSN_CRT_ACT FOREIGN KEY (CRT_ACT_ID) REFERENCES ACT_TBL(ACT_ID);
--#!