
	clause
		model
		label
		question
		answer
		clause_text
		position_index // for rendering, no logical consequence

			EXAMPLE:

				MODEL | QUESTION / LABEL | ANSWER | CLAUSE_TEXT
[MODEL][TAB][QUESTION][TAB][ANSWER][TAB][QUERY]
Client	Active?	YES	(is_active IS TRUE)
Client	Active?	NO	(is_active IS FALSE)
Client	MCP assigned?	YES	(mcp_pro_id IS NOT NULL)
Client	MCP assigned?	NO	(mcp_pro_id IS NULL)
Client	Future MCP appointment?	YES	()
Client	Future MCP appointment?	NO	()
Client	MCB Primary?	YES	()
Client	MCB Primary?	NO	()
Client	Has active RM device?	YES	()
Client	Has active RM device?	NO	()
Client	Active device type?	Weight	()
Client	Active device type?	BP	()
Client	Active device type?	Weight ONLY	()
Client	Active device type?	BP ONLY	()
Client	Active device type?	Weight + BP	()
Client	Type 2 Diabetic	-	()
Pro	Active?	YES	(is_active IS TRUE)
Pro	Active?	NO	(is_active IS FALSE)
Pro	Is HCP?	YES	(is_hcp IS TRUE)
Pro	Is HCP?	NO	(is_hcp IS NOT TRUE)

			WORK:::::::::::::::

				- FRONTEND: paste a tsv into a textarea and see it as a table.
				- BACKEND PHP: take in a tsv, foreach over and spit it back as a JSON.

	stat_tree
		name
		model
		slug
		max_line_length
		last_refreshed_at
		tsv_text_for_lines

			EXAMPLE tsv_text_for_lines:
			


//Pros
Active? YES
	Is HCP? YES
	Is HCP? NO
Active? NO
	Is HCP? YES
	Is HCP? NO


	stat_tree_line
		stat_tree_id
		tree_order_position_index
		last_refresh_count
		tsv_text_for_report_columns

			EXAMPLE tsv_text_for_report_columns:

				LABEL | DISPLAY_KEY | DISPLAY_FUNCTION | RECORD_ROUTE_NAME

	stat_tree_line_clause
		stat_tree_line_id
		clause_id
		clause_label
		position_index

	stat_tree_line_report_column
		stat_tree_line_id
		label
		position_index
		display_key // if super simple
		display_function // if custom on model
		record_route_name

------------------------------------------------------------------------------------------------

	api/clause/replaceAll
		tsvText

			LOGIC:

				delete all lines
				foreach line, create record

	api/statTree/create
		name
		table
		slug

			LOGIC:

				confirm no duplicate
				create statTree

	api/statTree/delete
		uid

			LOGIC:

				delete it

	api/statTree/updateBasic // can't change table
		uid
		name
		slug

			LOGIC:

				confirm no duplicate
				update

	api/statTree/refreshCount
		uid

			LOGIC:

				public function refreshCount($statTreeID){
					$statTree = StatTree::get($statTreeID);
					foreach($statTree->lines as $line){
						this->updateStatTreeLineCount($line);
					}
					$statTree->last_refreshed_at = now();
				}

				private function refreshCount($line){
					$table = $line->statTree->table;
					$query = "SELECT COUNT(*) FROM $table WHERE ";
					$allClauses = $line->statTreeLineClauses;
					for($i = 0; $i < count($allClauses); $i++){
						$query .= $allClauses[$i] . ($i == count($allClauses) - 1 ? '' : ' AND ');
					}
					$count = runRawSqlSafelyForCount($query);
					$line->last_refresh_count = $count;
					return count;
				}

	api/statTree/replaceAllLines
		uid
		tsvText

			LOGIC:

				EXAMPLE tsv_text_for_lines:

					Active patient? YES
						MCP assigned? YES
							MCB Primary? NO
								Has active RM device? YES
						MCP assigned? NO
							MCB Primary? YES
					Active patient? NO
						MCB Primary? YES
							Has active RM device? YES	
							Has active RM device? NO	
						MCB Primary? NO
							Has active RM device? YES
							Has active RM device? NO
						Has active RM device? YES	
						Has active RM device? NO

				public function replaceAllLines($statTree, $tsvText){
					// fill in missing blanks down the rows
					// foreach fully filled row, create a stat_tree_line
				}


	api/statTreeLine/replaceAllReportColumns
		uid
		tsvText

			LOGIC:

				EXAMPLE tsv_text_for_report_columns:

					LABEL | DISPLAY_KEY | DISPLAY_FUNCTION | RECORD_ROUTE_NAME

					public function replaceAllReportColumns($statTreeLine, $tsvText){
						// fill in missing blanks down the rows
					}

------------------------------------------------------------------------------------------------

/stat-tree/{{$statTree->slug}}

	Stat Tree: {{ $statTree->name }} | Last refreshed: {{ $statTree->last_refreshed_at }}

	<table>
		<tr>
			@for($i = 0; $statTree->max_line_length - 2; $i++)
				<th></th>
			@endfor
			<th>Count</th>
		</tr>
		@foreach($statTree->lines as $line) // ->lines returns by tree_order_position_index
			@for($i = 0; $statTree->max_line_length - 2; $i++)
				<td>
					{{ $i == $line->all_clauses_length - 1 ? $line->clause->label : '-' }}
				</td>
			@endfor
			<td>{{ $line->last_refresh_count }}</td>
		@endforeach
	</table>

------------------------------------------------------------------------------------------------

/dynamic-stat-tree/{{statTree->slug}}?top-level-filters=(BASE64OFTHEM)

	Top level filters:
		-(WHERE mcp_pro_id=2)

	// render same thing as static stat-tree, but with this filter and dynamic count

------------------------------------------------------------------------------------------------

/stat-tree-line/{{uid}}

	Stat Tree: {{ $statTree->name }}
	Table: {{ $line-> }}
	Line: {{ $line->all_clauses_text }}

	@foreach($columns as $column)
		<th></th>

	@foreach($records as $record)
		@foreach($columns as $column)
		<td>{{ $record->{{$column->display_function ? $column->display_function : $column->display_key }} }}</td>

	(PAGINATE)

------------------------------------------------------------------------------------------------

/dynamic-stat-tree-line/{{uid}}?top-level-filters=(BASE64OFTHEM)

	Top level filters:
		-(WHERE mcp_pro_id=2)

	// render same thing as static stat-tree-line, but with this filter



client	Active?	YES	(is_active IS TRUE)
client	Active?	NO	(is_active IS FALSE)
client	MCP assigned?	YES	(mcp_pro_id IS NOT NULL)
client	MCP assigned?	NO	(mcp_pro_id IS NULL)
client	MCB Primary?	YES	(is_part_b_primary = 'YES')
client	MCB Primary?	NO	(is_part_b_primary = 'NO')


Active? YES
	MCP assigned? YES
		MCB Primary? YES
		MCB Primary? NO
	MCP assigned? NO
Active? NO
