diff --git a/src/components/MapView.vue b/src/components/MapView.vue
index 9cbf88d88c469d86e68808e55164ac1b95bf654a..604d2506f93804fe3d83a6596f11994b9c12a0e9 100644
--- a/src/components/MapView.vue
+++ b/src/components/MapView.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 
-import {ConceptMapping, Mappings, MitMDataType} from "@/services/api"
+import {ConceptMapping, Mappings} from "@/services/api"
 import {useSelectionStore} from "@/services/selectionStore";
 import {computed, reactive, ref, watch} from "vue";
 import TableSelector from "@/components/helpers/TableSelector.vue";
@@ -13,7 +13,13 @@ import {ConceptMappingEntry, useMappingStore} from "@/services/mappingStore";
 import InfoDialog from "@/components/helpers/InfoDialog.vue";
 import {anyTIDtoTID, harmonizeToObj, rules} from "@/services/utils";
 import RelationsColumnMapper from "@/components/subcomponents/map/RelationsColumnMapper.vue";
-import {ForeignRelationMappings, WithinTableMappings} from "@/services/mappingUtils"
+import {
+  colMapFromNames,
+  ForeignRelationMappings,
+  suggestCol,
+  TypedColumnSelection,
+  WithinTableMappings
+} from "@/services/mappingUtils"
 
 const selection = useSelectionStore()
 const mappings = useMappingStore()
@@ -31,7 +37,7 @@ const kindCol = ref<string>()
 const idCols = ref({} as WithinTableMappings)
 const inlineCols = ref({} as WithinTableMappings)
 const foreignRelationMappings = ref({} as ForeignRelationMappings)
-const attributeCols = ref({} as { [key: string]: { selected: boolean, declaredType: MitMDataType } })
+const attributeCols = ref({} as TypedColumnSelection)
 
 const {columnList} = useColumnsOfTableWithProbe(selectedTable)
 
@@ -72,18 +78,7 @@ const isValid = computed(() => {
     && (Object.keys(cr.to_one).length == 0 || formvalidity.fkRelationCols)
 })
 
-function colMapFromNames(columns?: ExtendedColumnListItem[], nameColumnMapping?: { [key: string]: string }): {
-  [key: string]: ExtendedColumnListItem
-} {
-  if (!nameColumnMapping) return {}
-  else return Object.fromEntries(Object.entries(nameColumnMapping).map(([k, v]) => [k, columns?.find(item => item.name.toLowerCase() === v.toLowerCase())]).filter(([k, v]) => !!v))
-}
-
-function suggestCol(columns?: ExtendedColumnListItem[], name?: string, mitmType?: MitMDataType) {
-  return columns?.find(item => item.name.toLowerCase() === name?.toLowerCase() && item.inferredType === mitmType) ?? null
-}
-
-function suggestTypeCol(columns?: ExtendedColumnListItem[]) {
+function suggestTypeCol(columns?: ExtendedColumnListItem[]): ExtendedColumnListItem | null {
   const tc = !!recreatedMapping.value ? recreatedMapping.value.type_col : currentConceptProperties.value?.typing_concept
   return suggestCol(columns, tc, "text")
 }
@@ -115,7 +110,7 @@ function suggestInlineColMap(columns?: ExtendedColumnListItem[]) {
 }
 
 function suggestFKColMaps(columns?: ExtendedColumnListItem[]): {
-  [fkRelName: string]: { [nameToMap: string]: ExtendedColumnListItem }
+  [fkRelName: string]: { [nameToMap: string]: ExtendedColumnListItem | null }
 } {
   if (!!recreatedMapping.value?.foreign_relations) return Object.fromEntries(Object.entries(recreatedMapping.value.foreign_relations).map(([fkRelName, fkRel]) => [fkRelName, colMapFromNames(columns, harmonizeToObj(fkRel.fk_columns))]))
   const mitmDef = selectedMitMDef.value
@@ -144,7 +139,7 @@ function suggestForeignRelationsMappings(columns?: ExtendedColumnListItem[]): Fo
   }]))
 }
 
-function suggestAttributeColMap(columns?: ExtendedColumnListItem[], preselect?) {
+function suggestAttributeColMap(columns?: ExtendedColumnListItem[], preselect?): TypedColumnSelection {
   if (!!recreatedMapping.value?.attributes) {
     const attributes = recreatedMapping.value.attributes
     const attributeDTypes = recreatedMapping.value.attribute_dtypes
@@ -164,17 +159,18 @@ watch([columnList, currentConceptRelations], () => {
   console.log('Updating concept mapping suggestions.' + (recreatedMapping.value ? ' (recreating existing mapping)' : ''))
 
   const columns = columnList.value
-  typeCol.value = suggestTypeCol(columns)?.name
-  kindCol.value = suggestKindCol(columns)?.name
+  typeCol.value = suggestTypeCol(columns)?.name ?? null
+  kindCol.value = suggestKindCol(columns)?.name ?? null
   idCols.value = suggestIdColMap(columns)
   inlineCols.value = suggestInlineColMap(columns)
   foreignRelationMappings.value = suggestForeignRelationsMappings(columns)
-  const wasPreviouslySuggested = c => (c === typeCol.value || c === kindCol.value || Object.values(idCols.value).some(item => c === item.name) || Object.values(inlineCols.value).some(item => c === item.name) || Object.values(foreignRelationMappings.value).some(fkMapping => Object.values(fkMapping.fk_columns).some(item => c === item.name)))
+  const wasPreviouslySuggested = c => (c === typeCol.value || c === kindCol.value || Object.values(idCols.value).some(item => !!item && c === item.name) || Object.values(inlineCols.value).some(item => !!item && c === item.name) || Object.values(foreignRelationMappings.value).some(fkMapping => Object.values(fkMapping.fk_columns).some(item => !!item && c === item.name)))
   attributeCols.value = suggestAttributeColMap(columns, colItem => !wasPreviouslySuggested(colItem.name))
 }, {flush: "post"})
 
 
 async function onSubmit() {
+  if(!isValid.value) return
   loading.value = true
 
   const identity_columns = {}
@@ -219,7 +215,7 @@ async function onSubmit() {
   if (!!kindCol.value) {
     mapping["kind_col"] = kindCol.value
   }
-  console.log("Current MitM Def:\n", selectedMitM.value)
+  console.log("Current MitM Def:\n", selectedMitMDef.value)
   const res = await mappings.saveMapping(mapping)
   loading.value = false
 
@@ -297,7 +293,7 @@ const expanded = ref([0])
                                   :readonly="!!recreatedMapping"></InlineColumnMapper>
             </template>
 
-            <template v-if="!!currentConceptRelations && Object.keys(currentConceptRelations.to_one).length > 0">
+            <template v-if="!!currentConceptRelations && Object.keys(foreignRelationMappings).length > 0">
               <RelationsColumnMapper class="ma-2 pa-2" title="Foreign Relations"
                                      :mitm-def="selectedMitMDef"
                                      :base-table="selectedTable"
diff --git a/src/components/helpers/TimeRangeInput.vue b/src/components/helpers/TimeRangeInput.vue
index 72717846a428f5d3794c6ba4321dcc25f623e3e4..412807538b618dce0a2447a0eb27a8a8957a1a30 100644
--- a/src/components/helpers/TimeRangeInput.vue
+++ b/src/components/helpers/TimeRangeInput.vue
@@ -11,22 +11,28 @@ const dateRange = ref()
 const startTime = ref("00:00:00")
 const endTime = ref("00:00:00")
 
-watch([dateRange, startTime, endTime], ([dr, st, et]) => {
-  if (!!dr && dr.length >= 1) {
-    const ds = DateTime.fromJSDate(dr[0].getDate(), {zone: props.timezone})
-    const de = DateTime.fromJSDate(dr.slice(-1)[0].getDate(), {zone: props.timezone})
-    if (!!st) {
-      const ts = DateTime.fromISO(st)
-      startDateTime.value = ds.set({hour: ts.hour, minute: ts.minute, second: ts.second})
-    }
-    if (!!et) {
-      const te = DateTime.fromISO(et)
-      endDateTime.value = de.set({hour: te.hour, minute: te.minute, second: te.second})
+function time(s: string): { hour: number, minute: number, second: number } {
+  const [hour, minute, second] = s.split(":").map(v => Number(v))
+  return {hour, minute, second}
+}
+
+function pain(d: Date, t: string, tz: Zone): DateTime | null {
+  if (!!d && !!t)
+    return DateTime.fromObject({
+      year: d.getFullYear(),
+      month: 1 + d.getMonth(), // lol
+      day: d.getDate(),
+    }, {zone: tz}).set(time(t))
+  else return null
+}
 
-    } else {
-      startDateTime.value = null
-      endDateTime.value = null
-    }
+watch([dateRange, startTime, endTime, props.timezone], () => {
+  const dr = dateRange.value
+  const st = startTime.value
+  const et = endTime.value
+  if (!!dr && dr.length >= 1) {
+    startDateTime.value = pain(dr[0], st, props.timezone)
+    endDateTime.value = pain(dr.slice(-1)[0], et, props.timezone)
   }
 })
 
diff --git a/src/components/subcomponents/map/AttributeSelector.vue b/src/components/subcomponents/map/AttributeSelector.vue
index 94fa5eded597d3db8c45af521f52b1d81540e4ca..4d10e5519aae41f3df2fb23a02e0d77e25fad752 100644
--- a/src/components/subcomponents/map/AttributeSelector.vue
+++ b/src/components/subcomponents/map/AttributeSelector.vue
@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import {ExtendedColumnListItem, useMitMTypes} from "@/services/convenienceStore";
 import {MitMDataType} from "@/services/api";
+import {TypedColumnSelection} from "@/services/mappingUtils";
 
 const props = withDefaults(defineProps<{
   columnList: ExtendedColumnListItem[],
@@ -10,9 +11,7 @@ const props = withDefaults(defineProps<{
   readonly: false
 })
 
-const attributeDeclarations = defineModel<{
-  [key: string]: { selected: boolean, declaredType: MitMDataType }
-}>({required: true})
+const attributeDeclarations = defineModel<TypedColumnSelection>({required: true})
 
 const {mitmTypes} = useMitMTypes()
 
@@ -20,7 +19,7 @@ const {mitmTypes} = useMitMTypes()
 
 <template>
   <v-card variant="flat" title="Attributes">
-    <v-table density="compact">
+    <v-table density="compact" max-height="400">
       <thead>
       <tr>
         <th></th>
@@ -35,7 +34,7 @@ const {mitmTypes} = useMitMTypes()
         <template v-if="item.name in attributeDeclarations">
           <tr>
             <td>
-              <v-checkbox class="align-self-center" v-model="attributeDeclarations[item.name].selected"
+              <v-checkbox v-model="attributeDeclarations[item.name].selected"
                           :disabled="props.readonly"></v-checkbox>
             </td>
             <td>{{ item.name }}</td>
diff --git a/src/components/subcomponents/map/InlineColumnMapper.vue b/src/components/subcomponents/map/InlineColumnMapper.vue
index 9edd37a334b3cdc83ea8e0ce18e9eb743b759016..785c4839cb68afd2f4f63c19f9b7faeea6ef429a 100644
--- a/src/components/subcomponents/map/InlineColumnMapper.vue
+++ b/src/components/subcomponents/map/InlineColumnMapper.vue
@@ -1,20 +1,21 @@
 <script setup lang="ts">
 
 import {ExtendedColumnListItem} from "@/services/convenienceStore";
-import {MitMDataType, MitMDefinition} from "@/services/api";
-import {reactive, ref, shallowReactive, watch, watchEffect} from "vue";
+import {MitMDefinition} from "@/services/api";
+import {getRequiredType, WithinTableMappings} from "@/services/mappingUtils";
+import {ref, watch, watchEffect} from "vue";
 
 const props = defineProps<{
   mitmDef: MitMDefinition
   toMap: {
-    [name: string]: string;
+    [name: string]: string
   },
   columnList: ExtendedColumnListItem[],
   title: string,
   readonly?: boolean
 }>()
 
-const mappedColumns = defineModel<{ [key: string]: ExtendedColumnListItem }>('mappedColumns', {required: true})
+const mappedColumns = defineModel<WithinTableMappings>('mappedColumns', {required: true})
 const isValid = defineModel('isValid', {type: Boolean, default: false, required: false})
 const overrides = ref([])
 
@@ -25,13 +26,9 @@ watch(props.columnList, () => {
 watchEffect(() => {
   const toSkip = overrides.value
   const filtered = Object.entries(mappedColumns.value).filter(([name, mc]) => !toSkip.some(n => n === name))
-  isValid.value = filtered.every(([name, mc]) => getRequiredType(props.toMap[name]) === mc.inferredType)
+  isValid.value = !!props.mitmDef && filtered.every(([name, mc]) => !!mc && getRequiredType(props.mitmDef, props.toMap[name]) === mc.inferredType)
 })
 
-function getRequiredType(concept: string): MitMDataType {
-  return props.mitmDef.weak_concepts[concept]
-}
-
 </script>
 
 <template>
@@ -54,18 +51,21 @@ function getRequiredType(concept: string): MitMDataType {
           <td>{{ name }}</td>
           <td>{{ props.toMap[name].toUpperCase() }}</td>
           <td>
-            <v-select :items="props.columnList" v-model="mappedColumns[name]" return-object variant="plain" :disabled="props.readonly"></v-select>
+            <v-select :items="props.columnList" v-model="mappedColumns[name]" return-object variant="plain"
+                      :disabled="props.readonly"></v-select>
           </td>
           <td>
-            {{mappedColumns[name]?.sqlType}}
+            {{ mappedColumns[name]?.sqlType }}
           </td>
           <td>
-            <v-chip :color="getRequiredType(props.toMap[name]) === mappedColumns[name]?.inferredType ? 'green' : 'red'">
+            <v-chip :color="getRequiredType(props.mitmDef, props.toMap[name]) === mappedColumns[name]?.inferredType ? 'green' : 'red'">
               {{ mappedColumns[name]?.inferredType }}
             </v-chip>
           </td>
-          <td>{{ getRequiredType(props.toMap[name]) }}</td>
-          <td><v-checkbox-btn v-model="overrides" :value="name" :disabled="props.readonly"></v-checkbox-btn></td>
+          <td>{{ getRequiredType(props.mitmDef, props.toMap[name]) }}</td>
+          <td>
+            <v-checkbox-btn v-model="overrides" :value="name" :disabled="props.readonly"></v-checkbox-btn>
+          </td>
         </tr>
       </template>
       </tbody>
diff --git a/src/components/subcomponents/map/PresetMenu.vue b/src/components/subcomponents/map/PresetMenu.vue
index a1d0f7ed9089c92ecfb3d45e997eaabe98a67fc7..8f02972898bde6b3064d389b1b596785ddb2440a 100644
--- a/src/components/subcomponents/map/PresetMenu.vue
+++ b/src/components/subcomponents/map/PresetMenu.vue
@@ -64,8 +64,8 @@ async function fileDroppedIn(files) {
           </v-list-item>
           <v-list-subheader>Recreate Preset</v-list-subheader>
           <v-list-item>
-            <v-file-input variant="plain" hint="Drop a preset definition file here"
-                          @update:model-value="fileDroppedIn" label="Upload preset definition"></v-file-input>
+            <v-file-input variant="plain" tooltip="Drop a preset definition file here"
+                          @update:model-value="fileDroppedIn" label="Upload Preset Definition"></v-file-input>
           </v-list-item>
           <v-list-item v-for="item in presets" :title="item.props.title" @click="() => loadPreset(item.preset)">
           </v-list-item>
diff --git a/src/components/subcomponents/map/RelationsColumnMapper.vue b/src/components/subcomponents/map/RelationsColumnMapper.vue
index 34ac1bece065d4f8db0c3c78244f85836b839f22..530ef544fbad78a67ed3971fc01f605a1f60375b 100644
--- a/src/components/subcomponents/map/RelationsColumnMapper.vue
+++ b/src/components/subcomponents/map/RelationsColumnMapper.vue
@@ -1,14 +1,14 @@
 <script setup lang="ts">
 
 import {ExtendedColumnListItem} from "@/services/convenienceStore";
-import {Mappings, MitMDataType, MitMDefinition, TableIdentifier, TableMetaInfoResponse} from "@/services/api";
-import {Ref, ref, watch, watchEffect} from "vue";
+import {Mappings, MitMDefinition, TableIdentifier, TableMetaInfoResponse} from "@/services/api";
+import {reactive, ref, Ref, unref, watchEffect} from "vue";
 import {useMappingStore} from "@/services/mappingStore";
 import {storeToRefs} from "pinia";
 import TableSelector from "@/components/helpers/TableSelector.vue";
 import {useMainStore} from "@/services/mainStore";
-import {anyTIDtoTID, rules} from "@/services/utils"
-import {ForeignRelationMappings} from "@/services/mappingUtils"
+import {isSameTID, rules} from "@/services/utils"
+import {ForeignRelationMappings, getRequiredType} from "@/services/mappingUtils"
 
 
 const store = useMainStore()
@@ -25,8 +25,8 @@ const props = defineProps<{
 
 const foreignRelations: Ref<ForeignRelationMappings> = defineModel<ForeignRelationMappings>('foreignRelations', {required: true})
 const isValid = defineModel('isValid', {type: Boolean, default: false, required: false})
-const fkValidity = ref({requiredMappingExistence: {}, fkExistence: {}})
-const overrides = ref<{ [fkRelName: string]: Ref<[]> }>({})
+const fkValidity = reactive({requiredMappingExistence: {}, fkExistence: {}})
+const overrides = ref<{ [fkRelName: string]: string[] }>({})
 
 const fkRelationTargets = ref<{
   [fkRelName: string]: {
@@ -39,31 +39,29 @@ const fkRelationTargets = ref<{
 }>({})
 
 watchEffect(() => {
-  // const frs = foreignRelations.value
-  let temp = {}
-  if (!!props.toMap && !!props.mitmDef ) // && !!frs && Object.keys(frs).every(fkRelName => fkRelName in props.toMap)
-    temp = Object.fromEntries(Object.keys(foreignRelations.value).map(fkRelName => {
-      const fkRelInfo = props.toMap[fkRelName]
+  if (!!props.toMap && !!props.mitmDef)
+    fkRelationTargets.value = Object.fromEntries(Object.entries(props.toMap).map(([fkRelName, fkRelInfo]) => {
       const targetIdentity = props.mitmDef.concept_relations[fkRelInfo.target_concept].identity
-      const targetConcepts = Object.values(fkRelInfo.fk_relations).map(targetColName => targetIdentity[targetColName])
-      const targetTypes = targetConcepts.map(getRequiredType)
+      const targetConcepts = Object.fromEntries(Object.entries(fkRelInfo.fk_relations).map(([nameToMap, targetColName]) => [nameToMap, targetIdentity[targetColName]]))
+      const targetTypes = Object.fromEntries(Object.entries(targetConcepts).map(([nameToMap, concept]) => [nameToMap, getRequiredType(props.mitmDef, concept)]))
       const namesToMap = Object.keys(fkRelInfo.fk_relations)
       return [fkRelName, {
         targetConcept: fkRelInfo.target_concept,
         fkLength: namesToMap.length,
         namesToMap,
         targetConcepts,
-        targetTypes
+        targetTypes,
       }]
     }))
-  fkRelationTargets.value = temp
-  overrides.value = !!props.toMap ? Object.fromEntries(Object.keys(props.toMap).map(fkRelName => [fkRelName, ref([])])) : {}
+  else
+    fkRelationTargets.value = {}
+})
+
+watchEffect(() => {
+  const fkRelTargets = fkRelationTargets.value
+  overrides.value = !!fkRelTargets ? Object.fromEntries(Object.keys(fkRelTargets).map(fkRelName => [fkRelName, []])) : {}
 })
 
-//watch(props.columnList, () => {
-//  overrides.value = []
-//})
-//
 
 watchEffect(() => {
   const toSkip = overrides.value
@@ -71,136 +69,126 @@ watchEffect(() => {
   const fkRelTargets = fkRelationTargets.value
   if (!toSkip || !frs || !fkRelTargets) isValid.value = false
   else {
-    isValid.value = Object.entries(frs).map(([fkRelName, fkMapping]) => Object.entries(fkMapping.fk_columns)
-      .filter(([nameToMap]) => !toSkip[fkRelName] || !toSkip[fkRelName].some(n => n === nameToMap))
-      .every(([nameToMap, selectedCol]) => fkRelTargets[fkRelName].targetTypes[nameToMap] === selectedCol.inferredType)).every(v => v)
+    isValid.value = Object.entries(fkRelTargets).every(([fkRelName, fkRelTarget]) =>
+      fkRelName in frs
+      && Object.entries(frs[fkRelName].fk_columns)
+        .every(([nameToMap, selectedCol]) => !!selectedCol && (fkRelTarget.targetTypes[nameToMap] === selectedCol.inferredType || (fkRelName in toSkip && toSkip[fkRelName].some(n => n === nameToMap)))))
+    && Object.values(fkValidity.requiredMappingExistence).every(v => v)
   }
-})
+}, {flush: "post"})
 
 
-watchEffect( () => {
+watchEffect(() => {
   // check for existence of required concept mapping of selected table, and check for regular FK relation
   const frs = foreignRelations.value
-  console.log('validity 0')
+  const selectedTables = !!frs ? Object.fromEntries(Object.entries(frs).map(([fkRelName, fkMapping]) => [fkRelName, unref(fkMapping.referred_table)])) : {}
   const fkRelTargets = fkRelationTargets.value
-  const baseTable = props.baseTable
+  const baseTable = unref(props.baseTable)
   const tm: TableMetaInfoResponse = store.getTableMeta(baseTable)
-  const referredTables = !!frs ? Object.values(frs).map(fkMapping => fkMapping.referred_table) : []
-  console.log('validity 1')
-  console.log(frs)
-  console.log(fkRelTargets)
-  console.log(baseTable)
-  console.log(referredTables)
-  console.log(tm?.foreign_key_constraints)
-  let temp = {requiredMappingExistence: {}, fkExistence: {}}
   if (!!frs && !!baseTable && !!tm && !!fkRelTargets) {
-    //baseTable = anyTIDtoTID(baseTable)
-    const requiredMappingExistence = Object.entries(frs).map(([fkRelName, fkMapping]) =>
-      currentMappings.value.some(cme => cme.mapping.concept === fkRelTargets[fkRelName].targetConcept && cme.mapping.base_table === fkMapping.referred_table.value)
-    )
-    const fkExistence = referredTables.map(referredTable =>
-      baseTable.source === referredTable.source
-      && tm.foreign_key_constraints?.some(fkc =>
-      {
-        const tt = anyTIDtoTID(fkc.target_table, baseTable.source)
-        return tt.schema === referredTable.schema && tt.name === referredTable.name
-      }))
-    temp = {requiredMappingExistence, fkExistence}
+    const toConsider = Object.entries(fkRelTargets).map(([fkRelName]) => [fkRelName, selectedTables[fkRelName]])
+    fkValidity.fkExistence = Object.fromEntries(toConsider.map(([fkRelName, selectedTable]) =>
+      [fkRelName,
+        !!selectedTable
+        && baseTable.source === selectedTable.source
+        && tm.foreign_key_constraints?.some(fkc => isSameTID(fkc.target_table, baseTable, baseTable.source))]))
+
+    fkValidity.requiredMappingExistence = Object.fromEntries(toConsider.map(([fkRelName, selectedTable]) =>
+      [fkRelName,
+        !!selectedTable
+        && currentMappings.value.some(cme =>
+          cme.mapping.concept === fkRelTargets[fkRelName].targetConcept
+          && isSameTID(cme.mapping.base_table, selectedTable))]
+    ))
+  } else {
+    fkValidity.fkExistence = {}
+    fkValidity.requiredMappingExistence = {}
   }
-  console.log("validity 2", temp)
-  fkValidity.value = temp
-})
-
-
-function getRequiredType(concept: string): MitMDataType {
-  return props.mitmDef.weak_concepts[concept]
-}
+}, {flush: "post"})
 
 </script>
 
 <template>
   <v-card :title="props.title" variant="flat" :border="isValid ? null : 'lg error'">
     <v-list>
-      <template v-for="(fkRelTargets, fkRelName, i) in fkRelationTargets" v-if="!!fkRelationTargets" :key="fkRelName">
-        <v-list-item>
-          <v-card variant="flat" :title="`Relation: ${fkRelName}`">
-            <v-table density="compact" class="my-2">
-              <thead>
-              <tr>
-                <th>Target Concept</th>
-                <th>Target Table</th>
-                <th>Foreign Key Relationship</th>
-                <th>Mapping Existence</th>
-              </tr>
-              </thead>
-              <tbody>
+      <v-list-item v-for="(fkRelTarget, fkRelName) in fkRelationTargets" v-if="!!fkRelationTargets" :key="fkRelName">
+        <v-card variant="flat" :title="`Relation: ${fkRelName}`" v-if="fkRelName in foreignRelations">
+          <v-table density="compact" class="my-2">
+            <thead>
+            <tr>
+              <th>Target Concept</th>
+              <th>Target Table</th>
+              <th>Foreign Key Relationship</th>
+              <th>Mapping Existence</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr>
+              <td>{{ fkRelTarget.targetConcept.toUpperCase() }}</td>
+              <td>
+                <TableSelector v-model:selected-table="foreignRelations[fkRelName].referred_table"
+                               source-d-b="either" :rules="[rules.required]"
+                               :disabled="props.readonly" hide-details class="my-2"></TableSelector>
+              </td>
+              <td>
+                <v-chip :color="fkValidity.fkExistence[fkRelName] ? 'green' : 'orange'">
+                  {{ fkValidity.fkExistence[fkRelName] ? 'FK is declared' : 'there is no FK to table' }}
+                </v-chip>
+              </td>
+              <td>
+                <v-chip :color="fkValidity.requiredMappingExistence[fkRelName] ? 'green' : 'red'">
+                  {{
+                    fkValidity.requiredMappingExistence[fkRelName] ? `table is mapped to target concept` : `table is not mapped to target concept`
+                  }}
+                </v-chip>
+              </td>
+            </tr>
+            </tbody>
+          </v-table>
+          <v-table density="compact" class="my-2">
+            <thead>
+            <tr>
+              <th>Target Column</th>
+              <th>Target Concept</th>
+              <th>Selected Column</th>
+              <th>Actual SQL Type</th>
+              <th>Inferred Type</th>
+              <th>Required Type</th>
+              <th>Ignore Type Check?</th>
+            </tr>
+            </thead>
+            <tbody>
+            <template v-for="(nameToMap, i) in fkRelTarget.namesToMap" :key="nameToMap">
               <tr>
-                <td>{{ fkRelTargets.targetConcept.toUpperCase() }}</td>
+                <td>{{ nameToMap }}</td>
+                <td>{{ fkRelTarget.targetConcepts[nameToMap] }}</td>
                 <td>
-                  <TableSelector :selected-table="foreignRelations[fkRelName].referred_table"
-                                 source-d-b="either" :rules="[rules.required]"
-                                 :disabled="props.readonly" hide-details class="my-2"></TableSelector>
+                  <v-select :items="props.columnList" v-model="foreignRelations[fkRelName].fk_columns[nameToMap]"
+                            return-object variant="plain"
+                            :rules="[rules.required]"
+                            :disabled="props.readonly">
+                  </v-select>
                 </td>
                 <td>
-                  <v-chip :color="fkValidity.fkExistence[fkRelName] ? 'green' : 'orange'">
-                    {{ fkValidity.fkExistence[fkRelName] ? 'FK is declared in DB' : 'No FK to table exists' }}
-                  </v-chip>
+                  {{ foreignRelations[fkRelName]?.fk_columns[nameToMap]?.sqlType }}
                 </td>
                 <td>
-                  <v-chip :color="fkValidity.requiredMappingExistence[fkRelName] ? 'green' : 'red'">
-                    {{
-                      fkValidity.requiredMappingExistence[fkRelName] ? 'Target table is mapped as required' : 'Target table is not mapped to declared concept'
-                    }}
+                  <v-chip
+                    :color="fkRelTarget.targetTypes[nameToMap] === foreignRelations[fkRelName]?.fk_columns[nameToMap]?.inferredType ? 'green' : 'red'">
+                    {{ foreignRelations[fkRelName]?.fk_columns[nameToMap]?.inferredType }}
                   </v-chip>
                 </td>
+                <td>{{ fkRelTarget.targetTypes[nameToMap] }}</td>
+                <td>
+                  <v-checkbox-btn v-model="overrides[fkRelName]" :value="nameToMap"
+                                  :disabled="props.readonly"></v-checkbox-btn>
+                </td>
               </tr>
-              </tbody>
-            </v-table>
-            <v-table density="compact" class="my-2">
-              <thead>
-              <tr>
-                <th>Target Column</th>
-                <th>Target Concept</th>
-                <th>Selected Column</th>
-                <th>Actual SQL Type</th>
-                <th>Inferred Type</th>
-                <th>Required Type</th>
-                <th>Ignore Type Check?</th>
-              </tr>
-              </thead>
-              <tbody>
-              <template v-for="(nameToMap, i) in fkRelTargets.namesToMap" v-if="fkRelName in foreignRelations"
-                        :key="nameToMap">
-                <tr>
-                  <td>{{ nameToMap }}</td>
-                  <td>{{ fkRelTargets.targetConcepts[i] }}</td>
-                  <td>
-                    <v-select :items="props.columnList" v-model="foreignRelations[fkRelName].fk_columns[nameToMap]"
-                              return-object variant="plain"
-                              :rules="[rules.required]"
-                              :disabled="props.readonly">
-                    </v-select>
-                  </td>
-                  <td>
-                    {{ foreignRelations[fkRelName]?.fk_columns[nameToMap]?.sqlType }}
-                  </td>
-                  <td>
-                    <v-chip
-                      :color="fkRelTargets.targetTypes[i] === foreignRelations[fkRelName]?.fk_columns[nameToMap]?.inferredType ? 'green' : 'red'">
-                      {{ foreignRelations[fkRelName]?.fk_columns[nameToMap]?.inferredType }}
-                    </v-chip>
-                  </td>
-                  <td>{{ fkRelTargets.targetTypes[i] }}</td>
-                  <td>
-                    <v-checkbox-btn v-model="overrides[fkRelName]" :value="nameToMap" :disabled="props.readonly"></v-checkbox-btn>
-                  </td>
-                </tr>
-              </template>
-              </tbody>
-            </v-table>
-          </v-card>
-        </v-list-item>
-      </template>
+            </template>
+            </tbody>
+          </v-table>
+        </v-card>
+      </v-list-item>
     </v-list>
   </v-card>
 
diff --git a/src/components/subcomponents/transform/AdvancedRaw.vue b/src/components/subcomponents/transform/AdvancedRaw.vue
index d47dcaeb0de8648daa578cf3236f0c76068a4e10..4d8feeba89c5bd841eb7f77b7e409639d789d538 100644
--- a/src/components/subcomponents/transform/AdvancedRaw.vue
+++ b/src/components/subcomponents/transform/AdvancedRaw.vue
@@ -1,26 +1,41 @@
 <script setup lang="ts">
-import {ref} from "vue";
-import {Transforms, CompiledVirtualView} from "@/services/api";
+import {computed, ref, watchEffect} from "vue";
+import {Transforms} from "@/services/api";
 import {jsonToPrettyStr} from "@/services/utils";
 
 
-const isValid = defineModel("isValid", {type: Boolean, default: false, required: false})
+const isValid = defineModel({type: Boolean, default: false, required: false})
 
 const placeHolderTypedQuery: Transforms.TypedRawQuery = {
   columns: ["A", "B"],
-  column_dtypes: ["text", "numeric"],
+  column_dtypes: ["TEXT", "INTEGER"],
   dialect: "sqlite",
   compiled_sql: "SELECT 'Hi' AS A, 1 AS B FROM someSchema.someTable"
 }
 
-const text = ref(jsonToPrettyStr(placeHolderTypedQuery))
+const text = ref<string>(jsonToPrettyStr(placeHolderTypedQuery))
+const typedQuery = computed<Transforms.TypedRawQuery | null>(() => {
+  try {
+    const tq = JSON.parse(text.value)
+    if (Object.keys(placeHolderTypedQuery).every(k => k in tq))
+      return Object.fromEntries(Object.entries(tq).filter(([k]) => k in placeHolderTypedQuery))
+  } catch (e) {
+  }
+  return null
+})
+
+watchEffect(() => {
+  isValid.value = !!typedQuery.value
+})
 
-async function fileDroppedIn(files) {
-  if (files?.length > 0) {
-    const f = files[0]
-    const uploadedDefinition = JSON.parse(f)
-    if (!!uploadedDefinition) {
+async function fileDroppedIn(file: File) {
+  if (!!file) {
+    try {
+      const content = await file.text()
+      const uploadedDefinition = JSON.parse(content)
       text.value = jsonToPrettyStr(uploadedDefinition)
+    } catch (e) {
+      console.log('Uploaded Typed Query was not valid JSON')
     }
   }
 }
@@ -30,7 +45,10 @@ function resetAll() {
 }
 
 function createBase(): Transforms.Base {
-  return {operation: "raw", typed_query: text.value} as Transforms.RawCompiled
+  return {
+    operation: "raw",
+    typed_query: typedQuery.value
+  } as Transforms.RawCompiled
 }
 
 const createTransforms = () => [] as Transforms.Transform[]
@@ -44,13 +62,19 @@ defineExpose({resetAll, createTransforms, createBase})
     <v-row>
       <v-col>
         <v-file-input variant="outlined" prepend-inner-icon="mdi-code-json"
-                      label="Upload Compiled View Definition" hide-details
+                      label="Upload Typed Query Definition" hide-details
                       @update:model-value="fileDroppedIn"></v-file-input>
       </v-col>
     </v-row>
+    <v-row justify="start" align="center">
+      <v-col cols="auto"><strong>Definition</strong></v-col>
+      <v-col cols="auto">
+        <v-chip :color="isValid ? 'green' : 'red'">{{ isValid ? "valid" : "invalid" }}</v-chip>
+      </v-col>
+    </v-row>
     <v-row>
       <v-col>
-        <v-textarea :text="text" hint="Enter Raw Typed Query"></v-textarea>
+        <v-textarea v-model="text" hint="Enter Typed Query Definition"></v-textarea>
       </v-col>
     </v-row>
   </v-container>
diff --git a/src/components/subcomponents/transform/CreateVirtualView.vue b/src/components/subcomponents/transform/CreateVirtualView.vue
index 98c709c44604c9977f2f2dbbbe36d6dd7b4fa3c4..51328bcca2c0e08447fb2590acc738ffc8de9cc4 100644
--- a/src/components/subcomponents/transform/CreateVirtualView.vue
+++ b/src/components/subcomponents/transform/CreateVirtualView.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 
-import {computed, reactive, Ref, ref, watch} from "vue";
+import {computed, reactive, Ref, ref, unref, watch} from "vue";
 import {TableIdentifier, Transforms, useAPI, VirtualViewCreation} from "@/services/api";
 import {useMainStore} from "@/services/mainStore";
 import {useSelectionStore} from "@/services/selectionStore";
@@ -48,11 +48,11 @@ const widgetComponents: { title: string, value: string, kind: WidgetKind }[] = [
 
 
 const widgetInstances: { [key: string]: { ref: any, isValid: Ref<boolean>, kind: WidgetKind, cls: any } } = {
-  "editColumns": {cls: EditColumns, ref: ref(), isValid: ref<boolean>(false), kind: "transform"},
-  "extractJson": {cls: ExtractJson, ref: ref(), isValid: ref<boolean>(false), kind: "transform"},
-  "tableFilter": {cls: TableFilter, ref: ref(), isValid: ref<boolean>(false), kind: "transform"},
-  "simpleJoin": {cls: SimpleJoin, ref: ref(), isValid: ref<boolean>(false), kind: "base"},
-  "advancedRaw": {cls: AdvancedRaw, ref: ref(), isValid: ref<boolean>(false), kind: "advanced"},
+  "editColumns": {cls: EditColumns, ref: ref(), isValid: ref(false), kind: "transform"},
+  "extractJson": {cls: ExtractJson, ref: ref(), isValid: ref(false), kind: "transform"},
+  "tableFilter": {cls: TableFilter, ref: ref(), isValid: ref(false), kind: "transform"},
+  "simpleJoin":   {cls: SimpleJoin, ref: ref(), isValid: ref(false), kind: "base"},
+  "advancedRaw": {cls: AdvancedRaw, ref: ref(), isValid: ref(false), kind: "advanced"},
 }
 
 const store = useMainStore()
@@ -63,7 +63,7 @@ const {selectedTable} = storeToRefs(selection)
 
 const dialog = reactive({content: "", show: false, success: null, title: "Virtual View Creation"})
 const loading = ref(false)
-const mode = ref("transform")
+const mode = ref<WidgetKind>("transform")
 const removeBaseTable = ref(false)
 const permitOverride = ref(true)
 const viewIdentifier = reactive<TableIdentifier>({source: "virtual", schema: "virtual", name: ""})
@@ -81,11 +81,11 @@ const widgetInstance = computed(() => widgetInstances[tab.value])
 
 const widgetComponent = computed(() => widgetInstance.value.cls)
 
-const isValid = computed(() => (mode.value !== "transform" || !!selectedTable.value) && !!viewIdentifier.schema && !!viewIdentifier.name && uniqueName())
+const isValid = computed(() => (mode.value !== "transform" || !!selectedTable.value) && !!viewIdentifier.schema && !!viewIdentifier.name && !!uniqueName())
 
 const disabled = computed(() => {
   const selfValid = isValid.value
-  const widgetValid = widgetInstance.value?.isValid.value
+  const widgetValid = unref(widgetInstance.value?.isValid)
   return !selfValid || !widgetValid
 })
 
@@ -198,7 +198,7 @@ function resetWidget() {
         </v-tabs>
         <v-tabs-window v-model="tab" class="fill-height">
           <v-tabs-window-item v-for="(item, key) in widgetInstances" :value="key" :key="key">
-            <component class="mx-auto" :is="item.cls" v-model="item.isValid.value" :ref="el => item.ref = el"
+            <component class="mx-auto" :is="item.cls" @update:model-value="v => item.isValid.value = v" :ref="el => item.ref = el"
                        :table="selectedTable"></component>
           </v-tabs-window-item>
         </v-tabs-window>
diff --git a/src/components/subcomponents/transform/TimeFilter.vue b/src/components/subcomponents/transform/TimeFilter.vue
index 7cabe8e1b954059867fbd16ac4b651601035ca9c..031e7685f1ccbc874c68eeff845dfc0bc5dad05c 100644
--- a/src/components/subcomponents/transform/TimeFilter.vue
+++ b/src/components/subcomponents/transform/TimeFilter.vue
@@ -32,12 +32,16 @@ const dateTimeCol = ref()
 const comparator = ref("after")
 const timeZone = ref(IANAZone.create("Europe/Berlin"))
 const dateTimePoint = ref<DateTime>(null)
-const dateTimeRange = reactive({startDateTime: null as DateTime, endDateTime: null as DateTime})
+const startDateTime = ref<DateTime>(null)
+const endDateTime = ref<DateTime>(null)
 
 watchEffect(() => {
   const dtCol = dateTimeCol.value
   const comp = comparator.value
-  isValid.value = !!dtCol && (!!dateTimePoint.value || (comp === "between" && !!dateTimeRange.startDateTime && !!dateTimeRange.endDateTime))
+  const dtp = dateTimePoint.value
+  const sdt = startDateTime.value
+  const edt = endDateTime.value
+  isValid.value = !!dtCol && ((comp !== "between" && !!dtp) || (comp === "between" && !!sdt && !!edt))
 })
 
 function dtToCond(col: string, dt: DateTime, operator: Transforms.SimpleSQLOperator): Transforms.SimpleWhere {
@@ -48,8 +52,7 @@ function createWheres(): Transforms.SimpleWhere[] {
   const dtCol = dateTimeCol.value
   const comp = comparator.value
   if (comp === "between") {
-    console.log(dateTimeRange)
-    return [dtToCond(dtCol, dateTimeRange.startDateTime, ">="), dtToCond(dtCol, dateTimeRange.endDateTime, "<=")]
+    return [dtToCond(dtCol, startDateTime.value, ">="), dtToCond(dtCol, endDateTime.value, "<=")]
   } else {
     return [dtToCond(dtCol, dateTimePoint.value, comp === "before" ? "<" : ">")]
   }
@@ -81,12 +84,12 @@ defineExpose({
     <v-row no-gutters class="d-flex flex-nowrap" justify="start">
       <template v-if="comparator === 'between'">
         <v-col class="ma-2" cols="12">
-          <TimeRangeInput v-model:start-date-time="dateTimeRange.startDateTime" v-model:end-date-time="dateTimeRange.endDateTime" :timezone="timeZone.obj"></TimeRangeInput>
+          <TimeRangeInput v-model:start-date-time="startDateTime" v-model:end-date-time="endDateTime" :timezone="timeZone.value"></TimeRangeInput>
         </v-col>
       </template>
       <template v-else>
         <v-col class="ma-2" cols="12">
-          <TimePointInput v-model="dateTimePoint" :timezone="timeZone.obj"></TimePointInput>
+          <TimePointInput v-model="dateTimePoint" :timezone="timeZone.value"></TimePointInput>
         </v-col>
       </template>
     </v-row>
diff --git a/src/services/mappingUtils.ts b/src/services/mappingUtils.ts
index f7a1d60153df55efd1c3c4c94b812df8b09b2696..e92435014a450d05f08b99339b54af353dd62480 100644
--- a/src/services/mappingUtils.ts
+++ b/src/services/mappingUtils.ts
@@ -1,11 +1,27 @@
 import {ExtendedColumnListItem} from "@/services/convenienceStore";
-import {Ref, ref} from "vue";
-import {TableIdentifier} from "@/services/api";
+import {Ref} from "vue";
+import {MitMDataType, MitMDefinition, TableIdentifier} from "@/services/api";
 
 export type WithinTableMappings = { [key: string]: ExtendedColumnListItem }
 export type ForeignRelationMappings = {
   [fkRelName: string]: {
-    fk_columns: { [nameToMap: string]: ExtendedColumnListItem },
-    referred_table: Ref<TableIdentifier>
+    fk_columns: { [nameToMap: string]: ExtendedColumnListItem | null },
+    referred_table: Ref<TableIdentifier | null>
   }
 }
+export type TypedColumnSelection = { [key: string]: { selected: boolean, declaredType: MitMDataType | null } }
+
+export function colMapFromNames(columns?: ExtendedColumnListItem[], nameColumnMapping?: { [key: string]: string }): {
+  [key: string]: ExtendedColumnListItem
+} {
+  if (!nameColumnMapping) return {}
+  else return Object.fromEntries(Object.entries(nameColumnMapping).map(([k, v]) => [k, columns?.find(item => item.name.toLowerCase() === v.toLowerCase())]).filter(([k, v]) => !!v))
+}
+
+export function suggestCol(columns?: ExtendedColumnListItem[], name?: string, mitmType?: MitMDataType): ExtendedColumnListItem | null {
+  return columns?.find(item => item.name.toLowerCase() === name?.toLowerCase() && item.inferredType === mitmType) ?? null
+}
+
+export function getRequiredType(mitmDef: MitMDefinition, concept: string): MitMDataType | null {
+  return mitmDef?.weak_concepts[concept] ?? null
+}
diff --git a/src/services/preset-definitions/synthetic-preset.json b/src/services/preset-definitions/synthetic-preset.json
index a1ec54e271b0bf0511563842242c8b6849666a9c..abb9860ad274792527788aa869b6d40c497448c6 100644
--- a/src/services/preset-definitions/synthetic-preset.json
+++ b/src/services/preset-definitions/synthetic-preset.json
@@ -381,6 +381,20 @@
         "segment_index",
         "object"
       ],
+      "foreign_relations": {
+        "fk": {
+          "referred_table": [
+            "virtual",
+            "main",
+            "segments"
+          ],
+          "fk_columns": [
+            "concept",
+            "segment_index",
+            "object"
+          ]
+        }
+      },
       "attributes": [
         "target_geometry",
         "extrusion_temp",
@@ -410,6 +424,20 @@
         "segment_index",
         "object"
       ],
+      "foreign_relations": {
+        "fk": {
+          "referred_table": [
+            "virtual",
+            "main",
+            "segments"
+          ],
+          "fk_columns": [
+            "concept",
+            "segment_index",
+            "object"
+          ]
+        }
+      },
       "attributes": [
         "workpiece_quality"
       ],
diff --git a/src/services/utils.ts b/src/services/utils.ts
index 7e0b5d6357e0302a30c158b7b6066294e8216da3..76b33521e436b5f57d3c5e650aaa2aaf85cee088 100644
--- a/src/services/utils.ts
+++ b/src/services/utils.ts
@@ -9,13 +9,19 @@ import {useExportStore} from "@/services/exportStore";
 
 export function anyTIDtoTID(arg, source?): TableIdentifier | null {
   if (Array.isArray(arg)) return arg.length > 2 ? {source: arg[0], schema: arg[1], name: arg[2]} : {
-    source: source ? source : "original",
+    source: !!source ? source : "original",
     schema: arg[0],
     name: arg[1]
   }
   else return arg
 }
 
+export function isSameTID(arg1, arg2, source?) : boolean {
+  const tid1 = anyTIDtoTID(arg1, source)
+  const tid2 = anyTIDtoTID(arg2, source)
+  return !!tid1 && !!tid2 && tid1.source === tid2.source && tid1.schema === tid2.schema && tid1.name === tid2.name
+}
+
 export function tableIdToStr(id: TableIdentifier) {
   return `${id.source}:${id.schema}.${id.name}`
 }