From ea9e4e5d4d48599bdfce0c629a106e2fe90ea6d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr>
Date: Mon, 4 Apr 2022 16:59:22 +0200
Subject: [PATCH] Add primary key attribute property + fixed bugs

---
 .../attribute/add-attribute.component.ts      |  26 +-
 .../criteria/table-criteria.component.html    |   4 +-
 .../design/table-design.component.html        |   4 +-
 .../attribute/design/tr-design.component.html |   9 +-
 .../attribute/design/tr-design.component.ts   |   4 +-
 ...ml => detail-link-renderer.component.html} |   0
 ...t.ts => detail-link-renderer.component.ts} |   6 +-
 .../attribute/result/renderers/index.ts       |   4 +-
 .../result/renderers/renderer-form-factory.ts |   2 +-
 .../result/table-result.component.html        |   1 -
 .../attribute/result/tr-result.component.html |   5 +-
 .../attribute/result/tr-result.component.ts   |   3 +-
 .../containers/attribute-list.component.html  |  30 +-
 .../detail/object-data.component.html         |   4 +-
 .../detail/object-data.component.ts           |  11 -
 .../spectra/spectra-object.component.ts       |  14 +-
 .../result/datatable.component.html           |  12 +-
 .../result/datatable.component.spec.ts        |  10 +-
 .../components/result/datatable.component.ts  |  27 +-
 ...ml => detail-link-renderer.component.html} |   0
 ...=> detail-link-renderer.component.spec.ts} |  10 +-
 ...t.ts => detail-link-renderer.component.ts} |  12 +-
 .../components/result/renderer/index.ts       |   4 +-
 .../search/containers/detail.component.ts     |  12 +-
 .../store/effects/download-file.effects.ts    |   4 +-
 .../app/metamodel/models/attribute.model.ts   |  53 ++--
 .../detail-renderer-config.model.ts           |  17 ++
 .../models/detail-renderers/index.ts          |   1 +
 client/src/app/metamodel/models/index.ts      |   1 +
 ...s => detail-link-renderer-config.model.ts} |   4 +-
 .../app/metamodel/models/renderers/index.ts   |   2 +-
 conf-dev/create-db.sh                         | 123 ++++----
 .../__CG__AppEntityAttribute.php              | 274 ++++++++----------
 server/src/Action/AttributeAction.php         |  15 +-
 server/src/Action/AttributeListAction.php     |  24 +-
 server/src/Entity/Attribute.php               | 214 +++++++-------
 server/tests/Action/AttributeActionTest.php   |   2 +
 .../tests/Action/AttributeListActionTest.php  |   2 +
 38 files changed, 462 insertions(+), 488 deletions(-)
 rename client/src/app/admin/instance/dataset/components/attribute/result/renderers/{detail-renderer.component.html => detail-link-renderer.component.html} (100%)
 rename client/src/app/admin/instance/dataset/components/attribute/result/renderers/{detail-renderer.component.ts => detail-link-renderer.component.ts} (77%)
 rename client/src/app/instance/search/components/result/renderer/{detail-renderer.component.html => detail-link-renderer.component.html} (100%)
 rename client/src/app/instance/search/components/result/renderer/{detail-renderer.component.spec.ts => detail-link-renderer.component.spec.ts} (60%)
 rename client/src/app/instance/search/components/result/renderer/{detail-renderer.component.ts => detail-link-renderer.component.ts} (64%)
 create mode 100644 client/src/app/metamodel/models/detail-renderers/detail-renderer-config.model.ts
 create mode 100644 client/src/app/metamodel/models/detail-renderers/index.ts
 rename client/src/app/metamodel/models/renderers/{detail-renderer-config.model.ts => detail-link-renderer-config.model.ts} (80%)

diff --git a/client/src/app/admin/instance/dataset/components/attribute/add-attribute.component.ts b/client/src/app/admin/instance/dataset/components/attribute/add-attribute.component.ts
index 007d75dc..9ba139ef 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/add-attribute.component.ts
+++ b/client/src/app/admin/instance/dataset/components/attribute/add-attribute.component.ts
@@ -52,12 +52,34 @@ export class AddAttributeComponent {
             name: column.name,
             label: column.name,
             form_label: column.name,
+            description: null,
+            primary_key: false,
             type: column.type,
+            search_type: null,
+            operator: null,
+            min: null,
+            max: null,
+            placeholder_min: null,
+            placeholder_max: null,
             criteria_display: id * 10,
             output_display: id * 10,
+            selected: true,
+            renderer: null,
+            renderer_config: null,
+            order_by: true,
+            detail: true,
             display_detail: id * 10,
-            order_display: id * 10,
-            selected: true
+            renderer_detail: null,
+            renderer_detail_config: null,
+            options: null,
+            vo_utype: null,
+            vo_ucd: null,
+            vo_unit: null,
+            vo_description: null,
+            vo_datatype: null,
+            vo_size: null,
+            id_criteria_family: null,
+            id_output_category: null
         })
     }
 }
diff --git a/client/src/app/admin/instance/dataset/components/attribute/criteria/table-criteria.component.html b/client/src/app/admin/instance/dataset/components/attribute/criteria/table-criteria.component.html
index a204389c..f0c3ed80 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/criteria/table-criteria.component.html
+++ b/client/src/app/admin/instance/dataset/components/attribute/criteria/table-criteria.component.html
@@ -5,9 +5,9 @@
                 <th scope="col" style="min-width:150px">Name</th>
                 <th scope="col" style="min-width:110px">Type</th>
                 <th scope="col" style="min-width:150px">Criteria family</th>
-                <th scope="col" style="min-width:150px">Search Type</th>
+                <th scope="col" style="min-width:150px">Search type</th>
                 <th scope="col" style="width:50px">Operator</th>
-                <th scope="col" style="min-width:350px">Default Value(s)</th>
+                <th scope="col" style="min-width:350px">Default value(s)</th>
                 <th scope="col" style="min-width:150px">Placeholder</th>
                 <th scope="col" style="min-width:100px;width:100px;">Display</th>
                 <th scope="col" style="width:50px">Save</th>
diff --git a/client/src/app/admin/instance/dataset/components/attribute/design/table-design.component.html b/client/src/app/admin/instance/dataset/components/attribute/design/table-design.component.html
index a3ce2d1b..f1f6179a 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/design/table-design.component.html
+++ b/client/src/app/admin/instance/dataset/components/attribute/design/table-design.component.html
@@ -4,10 +4,10 @@
             <tr>
                 <th scope="col" style="min-width:50px">ID</th>
                 <th scope="col" style="min-width:150px">Name</th>
-                <th scope="col" style="min-width:150px">Search flag</th>
                 <th scope="col" style="min-width:150px">Label</th>
-                <th scope="col" style="min-width:150px">FormLabel</th>
+                <th scope="col" style="min-width:150px">Form label</th>
                 <th scope="col" style="min-width:150px">Description</th>
+                <th scope="col" style="min-width:120px;width:120px">Primary key</th>
                 <th scope="col" style="width:50px">Save</th>
                 <th scope="col" style="width:50px">Delete</th>
             </tr>
diff --git a/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.html b/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.html
index fc92db72..f27f023f 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.html
+++ b/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.html
@@ -5,12 +5,6 @@
     <td>
         <input type="text" class="form-control" name="name" formControlName="name">
     </td>
-    <td>
-        <select class="form-control" name="search_flag" formControlName="search_flag">
-            <option></option>
-            <option *ngFor="let flag of searchFlags" [ngValue]="flag.value">{{flag.label}}</option>
-        </select>
-    </td>
     <td>
         <input type="text" class="form-control" name="label" formControlName="label">
     </td>
@@ -20,6 +14,9 @@
     <td>
         <input type="text" class="form-control" name="description" formControlName="description">
     </td>
+    <td>
+        <input type="checkbox" class="form-control" name="primary_key" formControlName="primary_key">
+    </td>
     <td class="text-center align-middle">
         <button (click)="submit()" [disabled]="form.invalid || form.pristine" class="btn btn-outline-primary">
             <span class="fas fa-save"></span>
diff --git a/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.ts b/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.ts
index f9a42f6f..a1a67897 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.ts
+++ b/client/src/app/admin/instance/dataset/components/attribute/design/tr-design.component.ts
@@ -27,10 +27,10 @@ export class TrDesignComponent implements OnInit {
     public form = new FormGroup({
         id: new FormControl({value: '', disabled: true}),
         name: new FormControl('', [Validators.required]),
-        search_flag: new FormControl(),
         label: new FormControl('', [Validators.required]),
         form_label: new FormControl('', [Validators.required]),
-        description: new FormControl()
+        description: new FormControl(),
+        primary_key: new FormControl()
     });
 
     ngOnInit() {
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-renderer.component.html b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-link-renderer.component.html
similarity index 100%
rename from client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-renderer.component.html
rename to client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-link-renderer.component.html
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-renderer.component.ts b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-link-renderer.component.ts
similarity index 77%
rename from client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-renderer.component.ts
rename to client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-link-renderer.component.ts
index 4dfc1917..19be114a 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-renderer.component.ts
+++ b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/detail-link-renderer.component.ts
@@ -11,11 +11,11 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
 @Component({
-    selector: 'app-detail-renderer',
-    templateUrl: 'detail-renderer.component.html',
+    selector: 'app-detail-link-renderer',
+    templateUrl: 'detail-link-renderer.component.html',
     changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class DetailRendererComponent {
+export class DetailLinkRendererComponent {
     @Input() id: number;
     @Input() form: FormGroup;
 }
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/index.ts b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/index.ts
index 89c8ed9d..218957fe 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/index.ts
+++ b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/index.ts
@@ -7,13 +7,13 @@
  * file that was distributed with this source code.
  */
 
-import { DetailRendererComponent } from './detail-renderer.component';
+import { DetailLinkRendererComponent } from './detail-link-renderer.component';
 import { DownloadRendererComponent } from './download-renderer.component';
 import { ImageRendererComponent } from './image-renderer.component';
 import { LinkRendererComponent } from './link-renderer.component';
 
 export const renderers = [
-    DetailRendererComponent,
+    DetailLinkRendererComponent,
     DownloadRendererComponent,
     ImageRendererComponent,
     LinkRendererComponent
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/renderer-form-factory.ts b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/renderer-form-factory.ts
index 22c2f5e3..3c150c12 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/result/renderers/renderer-form-factory.ts
+++ b/client/src/app/admin/instance/dataset/components/attribute/result/renderers/renderer-form-factory.ts
@@ -12,7 +12,7 @@ import { FormControl } from "@angular/forms";
 export abstract class RendererFormFactory {
     static create(renderer: string) {
         switch (renderer) {
-            case 'detail':
+            case 'detail-link':
                 return {
                     display: new FormControl('text'),
                     blank: new FormControl(true)
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/table-result.component.html b/client/src/app/admin/instance/dataset/components/attribute/result/table-result.component.html
index efa3e786..a5e62755 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/result/table-result.component.html
+++ b/client/src/app/admin/instance/dataset/components/attribute/result/table-result.component.html
@@ -6,7 +6,6 @@
                 <th scope="col" style="min-width:150px">Renderer</th>
                 <th scope="col" style="min-width:200px">Renderer config</th>
                 <th scope="col" style="min-width:100px;width:100px">Order by</th>
-                <th scope="col" style="min-width:130px;width:130px;">Order display</th>
                 <th scope="col" style="width:50px">Save</th>
             </tr>
         </thead>
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.html b/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.html
index 1aebfa3a..6dd67ee0 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.html
+++ b/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.html
@@ -11,7 +11,7 @@
     </td>
     <td>
         <ng-container *ngIf="form.controls.renderer.value" [ngSwitch]="form.controls.renderer.value">
-            <app-detail-renderer *ngSwitchCase="'detail'" [id]="attribute.id" [form]="getRendererConfigForm()"></app-detail-renderer>
+            <app-detail-link-renderer *ngSwitchCase="'detail-link'" [id]="attribute.id" [form]="getRendererConfigForm()"></app-detail-link-renderer>
             <app-link-renderer *ngSwitchCase="'link'" [id]="attribute.id" [form]="getRendererConfigForm()"></app-link-renderer>
             <app-download-renderer *ngSwitchCase="'download'" [id]="attribute.id" [form]="getRendererConfigForm()"></app-download-renderer>
             <app-image-renderer *ngSwitchCase="'image'" [id]="attribute.id" [form]="getRendererConfigForm()"></app-image-renderer>
@@ -20,9 +20,6 @@
     <td>
         <input *ngIf="attribute.id_output_category" type="checkbox" class="form-control" name="order_by" formControlName="order_by">
     </td>
-    <td>
-        <input *ngIf="form.controls.order_by.value" type="number" class="form-control" name="order_display" formControlName="order_display">
-    </td>
     <td class="text-center align-middle">
         <button (click)="submit()" [disabled]="form.invalid || form.pristine" class="btn btn-outline-primary">
             <span class="fas fa-save"></span>
diff --git a/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.ts b/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.ts
index fe0aa76e..20f11bc4 100644
--- a/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.ts
+++ b/client/src/app/admin/instance/dataset/components/attribute/result/tr-result.component.ts
@@ -27,8 +27,7 @@ export class TrResultComponent implements OnInit {
     public form = new FormGroup({
         name: new FormControl({ value: '', disabled: true }),
         renderer: new FormControl(),
-        order_by: new FormControl(),
-        order_display: new FormControl()
+        order_by: new FormControl()
     });
 
     ngOnInit() {
diff --git a/client/src/app/admin/instance/dataset/containers/attribute-list.component.html b/client/src/app/admin/instance/dataset/containers/attribute-list.component.html
index 86a8ee83..ed23b573 100644
--- a/client/src/app/admin/instance/dataset/containers/attribute-list.component.html
+++ b/client/src/app/admin/instance/dataset/containers/attribute-list.component.html
@@ -1,4 +1,17 @@
-<div class="container-fluid">
+<app-spinner *ngIf="(attributeListIsLoading | async) 
+    || (datasetListIsLoading | async)
+    || (criteriaFamilyListIsLoading | async)
+    || (outputFamilyListIsLoading | async)
+    || (outputCategoryListIsLoading | async)
+    || (selectOptionListIsLoading | async)">
+</app-spinner>
+
+<div *ngIf="(attributeListIsLoaded | async) 
+    && (datasetListIsLoaded | async)
+    && (criteriaFamilyListIsLoaded | async)
+    && (outputFamilyListIsLoaded | async)
+    && (outputCategoryListIsLoaded | async)
+    && (selectOptionListIsLoaded | async)" class="container-fluid">
     <nav aria-label="breadcrumb">
         <ol class="breadcrumb">
             <li class="breadcrumb-item">
@@ -15,20 +28,7 @@
         </ol>
     </nav>
 
-    <app-spinner *ngIf="(attributeListIsLoading | async) 
-        || (datasetListIsLoading | async)
-        || (criteriaFamilyListIsLoading | async)
-        || (outputFamilyListIsLoading | async)
-        || (outputCategoryListIsLoading | async)
-        || (selectOptionListIsLoading | async)">
-    </app-spinner>
-
-    <div *ngIf="(attributeListIsLoaded | async) 
-        && (datasetListIsLoaded | async)
-        && (criteriaFamilyListIsLoaded | async)
-        && (outputFamilyListIsLoaded | async)
-        && (outputCategoryListIsLoaded | async)
-        && (selectOptionListIsLoaded | async)" class="row mt-1">
+    <div class="row mt-1">
         <div class="col-12">
             <div class="btn-toolbar mb-3" role="toolbar" aria-label="Toolbar with button groups">
                 <app-add-attribute
diff --git a/client/src/app/instance/search/components/detail/object-data.component.html b/client/src/app/instance/search/components/detail/object-data.component.html
index cfd31ddf..83450f9e 100644
--- a/client/src/app/instance/search/components/detail/object-data.component.html
+++ b/client/src/app/instance/search/components/detail/object-data.component.html
@@ -1,4 +1,4 @@
-<div *ngIf="getAttributeBySearchFlag('RA') && getAttributeBySearchFlag('DEC')" class="row">
+<!-- <div *ngIf="getAttributeBySearchFlag('RA') && getAttributeBySearchFlag('DEC')" class="row">
     <div class="col-12">
         <table class="table mb-1" aria-describedby="Object coordinates">
             <tr>
@@ -13,7 +13,7 @@
         </table>
         <hr class="mt-0 mb-4">
     </div>
-</div>
+</div> -->
 
 <!-- Accordion families -->
 <accordion [isAnimated]="true">
diff --git a/client/src/app/instance/search/components/detail/object-data.component.ts b/client/src/app/instance/search/components/detail/object-data.component.ts
index e4453a75..3e37f81d 100644
--- a/client/src/app/instance/search/components/detail/object-data.component.ts
+++ b/client/src/app/instance/search/components/detail/object-data.component.ts
@@ -65,17 +65,6 @@ export class ObjectDataComponent {
         return this.attributeList.filter(a => a.detail);
     }
 
-    /**
-     * Returns attribute for the given search flag.
-     *
-     * @param  {string} searchFlag - The search flag.
-     *
-     * @return Attribute
-     */
-    getAttributeBySearchFlag(searchFlag: string): Attribute {
-        return this.getAttributesVisible().find(attribute => attribute.search_flag === searchFlag);
-    }
-
     /**
      * Returns URL where download object.
      *
diff --git a/client/src/app/instance/search/components/detail/spectra/spectra-object.component.ts b/client/src/app/instance/search/components/detail/spectra/spectra-object.component.ts
index e3f1f400..468ab14c 100644
--- a/client/src/app/instance/search/components/detail/spectra/spectra-object.component.ts
+++ b/client/src/app/instance/search/components/detail/spectra/spectra-object.component.ts
@@ -51,9 +51,10 @@ export class SpectraObjectComponent implements OnInit {
      * @return string
      */
     getSpectra(): string {
-        const spectraAttribute: Attribute = this.attributeList
-            .filter(a => a.detail)
-            .find(attribute => attribute.search_flag === 'SPECTRUM_1D');
+        // const spectraAttribute: Attribute = this.attributeList
+        //     .filter(a => a.detail)
+        //     .find(attribute => attribute.search_flag === 'SPECTRUM_1D');
+        const spectraAttribute = this.attributeList[0];
         return `${getHost(this.appConfig.apiUrl)}/download-file/${this.datasetSelected}/${this.object[spectraAttribute.label]}`;
     }
 
@@ -74,9 +75,10 @@ export class SpectraObjectComponent implements OnInit {
      * @return number
      */
     getZ(): number {
-        const attributeZ = this.attributeList
-            .filter(a => a.detail)
-            .find(attribute => attribute.search_flag === 'Z');
+        // const attributeZ = this.attributeList
+        //     .filter(a => a.detail)
+        //     .find(attribute => attribute.search_flag === 'Z');
+        const attributeZ = this.attributeList[0];
         if (attributeZ) {
             return +this.object[attributeZ.label];
         } else {
diff --git a/client/src/app/instance/search/components/result/datatable.component.html b/client/src/app/instance/search/components/result/datatable.component.html
index 7533c540..ab328df5 100644
--- a/client/src/app/instance/search/components/result/datatable.component.html
+++ b/client/src/app/instance/search/components/result/datatable.component.html
@@ -5,9 +5,9 @@
         <thead>
             <tr>
                 <th *ngIf="dataset.datatable_selectable_rows" scope="col">#</th>
-                <th *ngFor="let attribute of getOutputList()" scope="col" class="clickable" (click)="sort(attribute.id)">
+                <th *ngFor="let attribute of getOutputList()" scope="col">
                     {{ attribute.label }}
-                    <span *ngIf="attribute.id === sortedCol" class="pl-2">
+                    <span *ngIf="attribute.id === sortedCol && attribute.order_by" class="pl-2" class="clickable" (click)="sort(attribute.id)">
                         <span [ngClass]="{'active': sortedOrder === 'a', 'inactive': sortedOrder === 'd'}">
                             <span class="fas fa-fw fa-sort-amount-down-alt"></span>
                         </span>
@@ -15,7 +15,7 @@
                             <span class="fas fa-fw fa-sort-amount-up"></span>
                         </span>
                     </span>
-                    <span *ngIf="attribute.id !== sortedCol" class="pl-2">
+                    <span *ngIf="attribute.id !== sortedCol && attribute.order_by" class="pl-2" class="clickable" (click)="sort(attribute.id)">
                         <span class="unsorted">
                             <span class="fas fa-fw fa-arrows-alt-v"></span>
                         </span>
@@ -41,14 +41,14 @@
                 </td>
                 <td *ngFor="let attribute of getOutputList()" class="align-middle">
                     <div *ngIf="datum[attribute.label]" [ngSwitch]="attribute.renderer">
-                        <div *ngSwitchCase="'detail'">
-                            <app-detail-renderer
+                        <div *ngSwitchCase="'detail-link'">
+                            <app-detail-link-renderer
                                 [value]="datum[attribute.label]"
                                 [datasetName]="dataset.name"
                                 [instanceSelected]="instance.name"
                                 [queryParams]="queryParams"
                                 [config]="getRendererConfig(attribute)">
-                            </app-detail-renderer>
+                            </app-detail-link-renderer>
                         </div>
                         <div *ngSwitchCase="'link'">
                             <app-link-renderer
diff --git a/client/src/app/instance/search/components/result/datatable.component.spec.ts b/client/src/app/instance/search/components/result/datatable.component.spec.ts
index 327261cc..370f7aa4 100644
--- a/client/src/app/instance/search/components/result/datatable.component.spec.ts
+++ b/client/src/app/instance/search/components/result/datatable.component.spec.ts
@@ -5,7 +5,7 @@ import { FormsModule } from '@angular/forms';
 import { DatatableComponent } from './datatable.component';
 import { Pagination, PaginationOrder, SearchQueryParams } from '../../../store/models';
 import {
-    DetailRendererConfig,
+    DetailLinkRendererConfig,
     DownloadRendererConfig,
     ImageRendererConfig,
     LinkRendererConfig,
@@ -24,7 +24,7 @@ describe('[Instance][Search][Component][Result] DatatableComponent', () => {
         @Input() datasetName: string;
         @Input() instanceSelected: string;
         @Input() queryParams: SearchQueryParams;
-        @Input() config: DetailRendererConfig;
+        @Input() config: DetailLinkRendererConfig;
     }
 
     @Component({ selector: 'app-link-renderer', template: '' })
@@ -122,15 +122,15 @@ describe('[Instance][Search][Component][Result] DatatableComponent', () => {
             display_detail: 1
         };
         expect(component.getRendererConfig(attribute)).toBeNull();
-        const detailRendererConfig: DetailRendererConfig = {
+        const detailLinkRendererConfig: DetailLinkRendererConfig = {
             id: 'renderer-config',
             display: 'display',
             icon_button: 'icon',
             blank: true
         };
         attribute.renderer = 'detail';
-        attribute.renderer_config = detailRendererConfig;
-        expect(component.getRendererConfig(attribute)).toEqual(detailRendererConfig);
+        attribute.renderer_config = detailLinkRendererConfig;
+        expect(component.getRendererConfig(attribute)).toEqual(detailLinkRendererConfig);
         const linkRendererConfig: LinkRendererConfig = {
             id: 'renderer-config',
             href: 'href',
diff --git a/client/src/app/instance/search/components/result/datatable.component.ts b/client/src/app/instance/search/components/result/datatable.component.ts
index 0718b70e..32d1a1b5 100644
--- a/client/src/app/instance/search/components/result/datatable.component.ts
+++ b/client/src/app/instance/search/components/result/datatable.component.ts
@@ -13,7 +13,7 @@ import {
     Instance,
     Attribute,
     Dataset,
-    DetailRendererConfig,
+    DetailLinkRendererConfig,
     DownloadRendererConfig,
     ImageRendererConfig,
     LinkRendererConfig } from 'src/app/metamodel/models';
@@ -52,7 +52,7 @@ export class DatatableComponent implements OnInit {
     public sortedOrder: PaginationOrder = PaginationOrder.a;
 
     ngOnInit(): void {
-        this.sortedCol = this.attributeList.find(a => a.order_by).id;
+        this.sortedCol = this.attributeList.find(a => a.primary_key).id;
         Promise.resolve(null).then(() => this.retrieveData.emit({
             dname: this.dataset.name,
             page: this.page,
@@ -68,12 +68,12 @@ export class DatatableComponent implements OnInit {
      * @param  {Attribute} attribute - The attribute.
      *
      */
-    // getRendererConfig(attribute: Attribute): DetailRendererConfig | LinkRendererConfig | DownloadRendererConfig | ImageRendererConfig | RendererConfig | null {
+    // getRendererConfig(attribute: Attribute): DetailLinkRendererConfig | LinkRendererConfig | DownloadRendererConfig | ImageRendererConfig | RendererConfig | null {
     getRendererConfig(attribute: Attribute) {
         let config = null;
         switch(attribute.renderer) {
-            case 'detail':
-                config = attribute.renderer_config as DetailRendererConfig;
+            case 'detail-link':
+                config = attribute.renderer_config as DetailLinkRendererConfig;
                 break;
             case 'link':
                 config = attribute.renderer_config as LinkRendererConfig;
@@ -113,12 +113,15 @@ export class DatatableComponent implements OnInit {
      * @fires EventEmitter<number | string>
      */
     toggleSelection(datum: any): void {
-        const attribute = this.attributeList.find(a => a.search_flag === 'ID');
-        const index = this.selectedData.indexOf(datum[attribute.label]);
+        const attribute = this.attributeList
+            .find(attribute => attribute.primary_key);
+        const pk = datum[attribute.label];
+
+        const index = this.selectedData.indexOf(pk);
         if (index > -1) {
-            this.deleteSelectedData.emit(datum[attribute.label]);
+            this.deleteSelectedData.emit(pk);
         } else {
-            this.addSelectedData.emit(datum[attribute.label]);
+            this.addSelectedData.emit(pk);
         }
     }
 
@@ -130,9 +133,11 @@ export class DatatableComponent implements OnInit {
      * @return boolean
      */
     isSelected(datum: any): boolean {
-        const attribute = this.attributeList.find(a => a.search_flag === 'ID');
+        const attribute = this.attributeList
+            .find(attribute => attribute.primary_key);
+        const pk = datum[attribute.label];
 
-        if (this.selectedData.indexOf(datum[attribute.label]) > -1) {
+        if (this.selectedData.indexOf(pk) > -1) {
             return true;
         }
         return false;
diff --git a/client/src/app/instance/search/components/result/renderer/detail-renderer.component.html b/client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.html
similarity index 100%
rename from client/src/app/instance/search/components/result/renderer/detail-renderer.component.html
rename to client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.html
diff --git a/client/src/app/instance/search/components/result/renderer/detail-renderer.component.spec.ts b/client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.spec.ts
similarity index 60%
rename from client/src/app/instance/search/components/result/renderer/detail-renderer.component.spec.ts
rename to client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.spec.ts
index 2087f1fc..fbecf087 100644
--- a/client/src/app/instance/search/components/result/renderer/detail-renderer.component.spec.ts
+++ b/client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.spec.ts
@@ -1,18 +1,18 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { DetailRendererComponent } from './detail-renderer.component';
+import { DetailLinkRendererComponent } from './detail-link-renderer.component';
 import { RouterTestingModule } from '@angular/router/testing';
 
 describe('[Instance][Search][Component][Result][Renderer] DetailRendererComponent', () => {
-    let component: DetailRendererComponent;
-    let fixture: ComponentFixture<DetailRendererComponent>;
+    let component: DetailLinkRendererComponent;
+    let fixture: ComponentFixture<DetailLinkRendererComponent>;
 
     beforeEach(() => {
         TestBed.configureTestingModule({
             imports: [RouterTestingModule],
-            declarations: [DetailRendererComponent]
+            declarations: [DetailLinkRendererComponent]
         });
-        fixture = TestBed.createComponent(DetailRendererComponent);
+        fixture = TestBed.createComponent(DetailLinkRendererComponent);
         component = fixture.componentInstance;
     });
 
diff --git a/client/src/app/instance/search/components/result/renderer/detail-renderer.component.ts b/client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.ts
similarity index 64%
rename from client/src/app/instance/search/components/result/renderer/detail-renderer.component.ts
rename to client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.ts
index 50d753c7..32fc626a 100644
--- a/client/src/app/instance/search/components/result/renderer/detail-renderer.component.ts
+++ b/client/src/app/instance/search/components/result/renderer/detail-link-renderer.component.ts
@@ -10,21 +10,21 @@
 import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
 
 import { SearchQueryParams } from 'src/app/instance/store/models';
-import { DetailRendererConfig } from 'src/app/metamodel/models/renderers/detail-renderer-config.model';
+import { DetailLinkRendererConfig } from 'src/app/metamodel/models/renderers/detail-link-renderer-config.model';
 
 /**
  * @class
- * @classdesc Detail renderer component.
+ * @classdesc Detail link renderer component.
  */
 @Component({
-    selector: 'app-detail-renderer',
-    templateUrl: 'detail-renderer.component.html',
+    selector: 'app-detail-link-renderer',
+    templateUrl: 'detail-link-renderer.component.html',
     changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class DetailRendererComponent {
+export class DetailLinkRendererComponent {
     @Input() value: string | number;
     @Input() datasetName: string;
     @Input() instanceSelected: string;
     @Input() queryParams: SearchQueryParams;
-    @Input() config: DetailRendererConfig;
+    @Input() config: DetailLinkRendererConfig;
 }
diff --git a/client/src/app/instance/search/components/result/renderer/index.ts b/client/src/app/instance/search/components/result/renderer/index.ts
index 01630ce7..fd7c9673 100644
--- a/client/src/app/instance/search/components/result/renderer/index.ts
+++ b/client/src/app/instance/search/components/result/renderer/index.ts
@@ -1,11 +1,11 @@
-import { DetailRendererComponent } from './detail-renderer.component';
+import { DetailLinkRendererComponent } from './detail-link-renderer.component';
 import { DownloadRendererComponent } from './download-renderer.component';
 import { ImageRendererComponent } from './image-renderer.component';
 import { JsonRendererComponent } from './json-renderer.component';
 import { LinkRendererComponent } from './link-renderer.component';
 
 export const rendererComponents = [
-    DetailRendererComponent,
+    DetailLinkRendererComponent,
     DownloadRendererComponent,
     ImageRendererComponent,
     JsonRendererComponent,
diff --git a/client/src/app/instance/search/containers/detail.component.ts b/client/src/app/instance/search/containers/detail.component.ts
index 0a238296..4de2dd24 100644
--- a/client/src/app/instance/search/containers/detail.component.ts
+++ b/client/src/app/instance/search/containers/detail.component.ts
@@ -105,12 +105,12 @@ export class DetailComponent implements OnInit, OnDestroy {
      * @return string
      */
     getObjectType(attributeList: Attribute[]): string {
-        const spectrumAttribute: Attribute = attributeList
-            .filter(a => a.detail)
-            .find(attribute => attribute.search_flag === 'SPECTRUM_1D');
-        if (spectrumAttribute) {
-            return 'spectra';
-        }
+        // const spectrumAttribute: Attribute = attributeList
+        //     .filter(a => a.detail)
+        //     .find(attribute => attribute.search_flag === 'SPECTRUM_1D');
+        // if (spectrumAttribute) {
+        //     return 'spectra';
+        // }
         return 'default';
     }
 
diff --git a/client/src/app/instance/store/effects/download-file.effects.ts b/client/src/app/instance/store/effects/download-file.effects.ts
index 1cb58cd4..437e0eb6 100644
--- a/client/src/app/instance/store/effects/download-file.effects.ts
+++ b/client/src/app/instance/store/effects/download-file.effects.ts
@@ -42,7 +42,7 @@ export class DownloadFileEffects {
                 this.store.select(searchSelector.selectSelectedData)
             ]),
             mergeMap(([action, currentDataset, attributeList, criteriaList, coneSearch, outputList, selectedData]) => {
-                const attributeId = attributeList.find(a => a.search_flag === 'ID');
+                const attributeId = attributeList.find(a => a.primary_key);
                 let query: string = `${currentDataset}?a=${outputList}`;
                 if (criteriaList) {
                     query += `&c=${criteriaList}`;
@@ -145,7 +145,7 @@ export class DownloadFileEffects {
                 this.store.select(searchSelector.selectSelectedData)
             ]),
             mergeMap(([action, currentDataset, attributeList, criteriaList, coneSearch, outputList, selectedData]) => {
-                const attributeId = attributeList.find(a => a.search_flag === 'ID');
+                const attributeId = attributeList.find(a => a.primary_key);
                 let query: string = `${currentDataset}?a=${outputList}`;
                 if (criteriaList) {
                     query += `&c=${criteriaList}`;
diff --git a/client/src/app/metamodel/models/attribute.model.ts b/client/src/app/metamodel/models/attribute.model.ts
index f58acd2c..6634b10c 100644
--- a/client/src/app/metamodel/models/attribute.model.ts
+++ b/client/src/app/metamodel/models/attribute.model.ts
@@ -9,6 +9,7 @@
 
 import { Option } from './option.model';
 import { RendererConfig } from './renderers';
+import { DetailRendererConfig } from './detail-renderers';
 
 /**
  * Interface for attribute.
@@ -20,32 +21,32 @@ export interface Attribute {
     name: string;
     label: string;
     form_label: string;
-    description?: string;
-    output_display: number;
-    criteria_display: number;
-    search_flag?: string;
-    search_type?: string;
-    operator?: string;
+    description: string;
+    primary_key: boolean;
     type: string;
-    min?: string;
-    max?: string;
-    placeholder_min?: string;
-    placeholder_max?: string;
-    renderer?: string;
-    renderer_config?: RendererConfig;
+    search_type: string;
+    operator: string;
+    min: string;
+    max: string;
+    placeholder_min: string;
+    placeholder_max: string;
+    criteria_display: number;
+    output_display: number;
+    selected: boolean;
+    renderer: string;
+    renderer_config: RendererConfig;
+    order_by: boolean;
+    detail: boolean;
     display_detail: number;
-    selected?: boolean;
-    order_by?: boolean;
-    order_display?: number;
-    detail?: boolean;
-    renderer_detail?: string;
-    options?: Option[];
-    vo_utype?: string;
-    vo_ucd?: string;
-    vo_unit?: string;
-    vo_description?: string;
-    vo_datatype?: string;
-    vo_size?: number;
-    id_criteria_family?: number;
-    id_output_category?: number;
+    renderer_detail: string;
+    renderer_detail_config: DetailRendererConfig;
+    options: Option[];
+    vo_utype: string;
+    vo_ucd: string;
+    vo_unit: string;
+    vo_description: string;
+    vo_datatype: string;
+    vo_size: number;
+    id_criteria_family: number;
+    id_output_category: number;
 }
diff --git a/client/src/app/metamodel/models/detail-renderers/detail-renderer-config.model.ts b/client/src/app/metamodel/models/detail-renderers/detail-renderer-config.model.ts
new file mode 100644
index 00000000..2eca974a
--- /dev/null
+++ b/client/src/app/metamodel/models/detail-renderers/detail-renderer-config.model.ts
@@ -0,0 +1,17 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for renderer config.
+ *
+ * @interface DetailRendererConfig
+ */
+export interface DetailRendererConfig {
+    id: 'detail-renderer-config';
+}
diff --git a/client/src/app/metamodel/models/detail-renderers/index.ts b/client/src/app/metamodel/models/detail-renderers/index.ts
new file mode 100644
index 00000000..19114050
--- /dev/null
+++ b/client/src/app/metamodel/models/detail-renderers/index.ts
@@ -0,0 +1 @@
+export * from './detail-renderer-config.model';
diff --git a/client/src/app/metamodel/models/index.ts b/client/src/app/metamodel/models/index.ts
index 0a03d5e6..29bb401f 100644
--- a/client/src/app/metamodel/models/index.ts
+++ b/client/src/app/metamodel/models/index.ts
@@ -23,3 +23,4 @@ export * from './select.model';
 export * from './select-option.model';
 export * from './image.model';
 export * from './renderers';
+export * from './detail-renderers';
\ No newline at end of file
diff --git a/client/src/app/metamodel/models/renderers/detail-renderer-config.model.ts b/client/src/app/metamodel/models/renderers/detail-link-renderer-config.model.ts
similarity index 80%
rename from client/src/app/metamodel/models/renderers/detail-renderer-config.model.ts
rename to client/src/app/metamodel/models/renderers/detail-link-renderer-config.model.ts
index 921abadd..bf5db5ec 100644
--- a/client/src/app/metamodel/models/renderers/detail-renderer-config.model.ts
+++ b/client/src/app/metamodel/models/renderers/detail-link-renderer-config.model.ts
@@ -12,10 +12,10 @@ import { RendererConfig } from './renderer-config.model';
 /**
  * Interface for detail renderer config.
  *
- * @interface DetailRendererConfig
+ * @interface DetailLinkRendererConfig
  * @extends RendererConfig
  */
-export interface DetailRendererConfig extends RendererConfig {
+export interface DetailLinkRendererConfig extends RendererConfig {
     display: string;
     icon_button: string;
     blank: boolean;
diff --git a/client/src/app/metamodel/models/renderers/index.ts b/client/src/app/metamodel/models/renderers/index.ts
index 57688b44..70236ef1 100644
--- a/client/src/app/metamodel/models/renderers/index.ts
+++ b/client/src/app/metamodel/models/renderers/index.ts
@@ -1,5 +1,5 @@
 export * from './renderer-config.model';
-export * from './detail-renderer-config.model';
+export * from './detail-link-renderer-config.model';
 export * from './link-renderer-config.model';
 export * from './download-renderer-config.model';
 export * from './image-renderer-config.model';
diff --git a/conf-dev/create-db.sh b/conf-dev/create-db.sh
index 92e8206d..162b7966 100644
--- a/conf-dev/create-db.sh
+++ b/conf-dev/create-db.sh
@@ -5,22 +5,11 @@ set -e
 ./vendor/bin/doctrine orm:schema-tool:create
 
 # Add settings for anis-admin GUI
-curl -d '{"name":"search_flag","label":"Search flag"}' --header 'Content-Type: application/json' -X POST http://localhost/select
 curl -d '{"name":"search_type","label":"Search Type"}' --header 'Content-Type: application/json' -X POST http://localhost/select
 curl -d '{"name":"operator","label":"Operator"}' --header 'Content-Type: application/json' -X POST http://localhost/select
 curl -d '{"name":"renderer","label":"Renderer"}' --header 'Content-Type: application/json' -X POST http://localhost/select
 curl -d '{"name":"renderer_detail","label":"Renderer detail"}' --header 'Content-Type: application/json' -X POST http://localhost/select
 
-curl -d '{"label":"ID","value":"ID","display":10,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"RA","value":"RA","display":20,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"DEC","value":"DEC","display":30,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"Z","value":"Z","display":40,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"Z_FLAG","value":"Z_FLAG","display":50,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"SPECTRUM_1D","value":"SPECTRUM_1D","display":60,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"SPECTRUM_1D_NOISE","value":"SPECTRUM_1D_NOISE","display":70,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"SPECTRUM_1D_SKY","value":"SPECTRUM_1D_SKY","display":80,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-curl -d '{"label":"SPECTRUM_2D","value":"SPECTRUM_2D","display":90,"select_name":"search_flag"}' --header 'Content-Type: application/json' -X POST http://localhost/option
-
 curl -d '{"label":"Field","value":"field","display":10,"select_name":"search_type"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 curl -d '{"label":"Between","value":"between","display":20,"select_name":"search_type"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 curl -d '{"label":"Select","value":"select","display":30,"select_name":"search_type"}' --header 'Content-Type: application/json' -X POST http://localhost/option
@@ -47,7 +36,7 @@ curl -d '{"label":"not like","value":"nlk","display":80,"select_name":"operator"
 curl -d '{"label":"in","value":"in","display":90,"select_name":"operator"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 curl -d '{"label":"not in","value":"nin","display":100,"select_name":"operator"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 
-curl -d '{"label":"Detail page","value":"detail","display":10,"select_name":"renderer"}' --header 'Content-Type: application/json' -X POST http://localhost/option
+curl -d '{"label":"Link detail page","value":"detail-link","display":10,"select_name":"renderer"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 curl -d '{"label":"Download file","value":"download","display":20,"select_name":"renderer"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 curl -d '{"label":"Link (file, web page...)","value":"link","display":30,"select_name":"renderer"}' --header 'Content-Type: application/json' -X POST http://localhost/option
 curl -d '{"label":"Display image (png, jpg...)","value":"image","display":40,"select_name":"renderer"}' --header 'Content-Type: application/json' -X POST http://localhost/option
@@ -84,36 +73,36 @@ curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type:
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/output-family
 curl -d '{"label":"Default","display":10}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/1/output-category
 
-curl -d '{"id":1,"name":"num","label":"num","form_label":"num","description":null,"output_display":10,"criteria_display":10,"search_flag":"ID","search_type":"field","type":"decimal","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"detail","renderer_config":{"display":"text","blank":true},"display_detail":10,"selected":true,"order_by":false,"order_display":10,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":2,"name":"alpha","label":"alpha","form_label":"alpha","description":null,"output_display":20,"criteria_display":20,"search_flag":"RA","search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":false,"order_display":20,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":3,"name":"delta","label":"delta","form_label":"delta","description":null,"output_display":30,"criteria_display":30,"search_flag":"DEC","search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":false,"order_display":30,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":4,"name":"selmag","label":"selmag","form_label":"selmag","description":null,"output_display":40,"criteria_display":40,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":false,"order_display":40,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":5,"name":"errselmag","label":"errselmag","form_label":"errselmag","description":null,"output_display":50,"criteria_display":50,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":false,"order_display":50,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":6,"name":"pointing","label":"pointing","form_label":"pointing","description":null,"output_display":60,"criteria_display":60,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":false,"order_display":60,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":7,"name":"quadrant","label":"quadrant","form_label":"quadrant","description":null,"output_display":70,"criteria_display":70,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":70,"selected":true,"order_by":false,"order_display":70,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":8,"name":"zspec","label":"zspec","form_label":"zspec","description":null,"output_display":80,"criteria_display":80,"search_flag":null,"search_type":"between","type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":80,"selected":true,"order_by":false,"order_display":80,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":9,"name":"zflg","label":"zflg","form_label":"zflg","description":null,"output_display":90,"criteria_display":90,"search_flag":"Z_FLAG","search_type":"datalist","type":"decimal","operator":"in","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":90,"selected":true,"order_by":false,"order_display":90,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"1,2,3,4,9","value":"1,2,3,4,9","display":10},{"label":"2,3,4,9","value":"2,3,4,9","display":20},{"label":"3,4","value":"3,4","display":30},{"label":"1,2,3,4,9,21,22,23,24,29","value":"1,2,3,4,9,21,22,23,24,29","display":40},{"label":"2,3,4,9,22,23,24,29","value":"2,3,4,9,22,23,24,29","display":50}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":10,"name":"norm","label":"norm","form_label":"norm","description":null,"output_display":100,"criteria_display":100,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":100,"selected":true,"order_by":false,"order_display":100,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":11,"name":"epoch","label":"epoch","form_label":"epoch","description":null,"output_display":110,"criteria_display":110,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":110,"selected":true,"order_by":false,"order_display":110,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":12,"name":"photomask","label":"photomask","form_label":"photomask","description":null,"output_display":120,"criteria_display":120,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":120,"selected":true,"order_by":false,"order_display":120,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":56,"name":"spec1d","label":"spec1d","form_label":"spec1d","description":null,"output_display":560,"criteria_display":560,"search_flag":"SPECTRUM_1D","search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":560,"selected":true,"order_by":false,"order_display":560,"detail":true,"renderer_detail":"spectra_graph","options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":57,"name":"spec1dnoise","label":"spec1dnoise","form_label":"spec1dnoise","description":null,"output_display":570,"criteria_display":570,"search_flag":null,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":570,"selected":true,"order_by":false,"order_display":570,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
-curl -d '{"id":58,"name":"spec1dsky","label":"spec1dsky","form_label":"spec1dsky","description":null,"output_display":580,"criteria_display":580,"search_flag":null,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":580,"selected":true,"order_by":false,"order_display":580,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":1,"name":"num","label":"num","form_label":"num","description":null,"primary_key":true,"output_display":10,"criteria_display":10,"search_type":"field","type":"decimal","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"detail-link","renderer_config":{"display":"text","blank":true},"display_detail":10,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":2,"name":"alpha","label":"alpha","form_label":"alpha","description":null,"primary_key":false,"output_display":20,"criteria_display":20,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":3,"name":"delta","label":"delta","form_label":"delta","description":null,"primary_key":false,"output_display":30,"criteria_display":30,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":4,"name":"selmag","label":"selmag","form_label":"selmag","description":null,"primary_key":false,"output_display":40,"criteria_display":40,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":5,"name":"errselmag","label":"errselmag","form_label":"errselmag","description":null,"primary_key":false,"output_display":50,"criteria_display":50,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":6,"name":"pointing","label":"pointing","form_label":"pointing","description":null,"primary_key":false,"output_display":60,"criteria_display":60,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":7,"name":"quadrant","label":"quadrant","form_label":"quadrant","description":null,"primary_key":false,"output_display":70,"criteria_display":70,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":70,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":8,"name":"zspec","label":"zspec","form_label":"zspec","description":null,"primary_key":false,"output_display":80,"criteria_display":80,"search_type":"between","type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":80,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":9,"name":"zflg","label":"zflg","form_label":"zflg","description":null,"primary_key":false,"output_display":90,"criteria_display":90,"search_type":"datalist","type":"decimal","operator":"in","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":90,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"1,2,3,4,9","value":"1,2,3,4,9","display":10},{"label":"2,3,4,9","value":"2,3,4,9","display":20},{"label":"3,4","value":"3,4","display":30},{"label":"1,2,3,4,9,21,22,23,24,29","value":"1,2,3,4,9,21,22,23,24,29","display":40},{"label":"2,3,4,9,22,23,24,29","value":"2,3,4,9,22,23,24,29","display":50}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":10,"name":"norm","label":"norm","form_label":"norm","description":null,"primary_key":false,"output_display":100,"criteria_display":100,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":100,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":11,"name":"epoch","label":"epoch","form_label":"epoch","description":null,"primary_key":false,"output_display":110,"criteria_display":110,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":110,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":12,"name":"photomask","label":"photomask","form_label":"photomask","description":null,"primary_key":false,"output_display":120,"criteria_display":120,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":120,"selected":true,"order_by":true,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":56,"name":"spec1d","label":"spec1d","form_label":"spec1d","description":null,"primary_key":false,"output_display":560,"criteria_display":560,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":560,"selected":true,"order_by":false,"detail":true,"renderer_detail":"spectra_graph","options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":57,"name":"spec1dnoise","label":"spec1dnoise","form_label":"spec1dnoise","description":null,"primary_key":false,"output_display":570,"criteria_display":570,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":570,"selected":true,"order_by":false,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
+curl -d '{"id":58,"name":"spec1dsky","label":"spec1dsky","form_label":"spec1dsky","description":null,"primary_key":false,"output_display":580,"criteria_display":580,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":580,"selected":true,"order_by":false,"detail":true,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":1}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vipers_dr2_w1/attribute
 
 # Add sp_cards attributes
 curl -d '{"label":"Card","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/criteria-family
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/output-family
 curl -d '{"label":"Default","display":10}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/2/output-category
 
-curl -d '{"id":1,"name":"acronym","label":"acronym","form_label":"Product Acronym","description":null,"output_display":10,"criteria_display":10,"search_flag":"ID","search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":[],"display_detail":10,"selected":true,"order_by":false,"order_display":10,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"LAMTEST","value":"LAMTEST","display":10},{"label":"LAMTEST_DC1","value":"LAMTEST_DC1","display":20},{"label":"MXT-EVT-CAL","value":"MXT-EVT-CAL","display":30},{"label":"OBLC_ECL","value":"OBLC_ECL","display":40}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":2,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":2,"name":"sp_id","label":"sp_id","form_label":"SP IAP ID","description":null,"output_display":20,"criteria_display":20,"search_flag":null,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":false,"order_display":20,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":3,"name":"version","label":"version","form_label":"Version","description":null,"output_display":30,"criteria_display":30,"search_flag":null,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":false,"order_display":30,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":4,"name":"program","label":"program","form_label":"Program","description":null,"output_display":40,"criteria_display":40,"search_flag":null,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":false,"order_display":40,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"CP","value":"CP","display":10},{"label":"GP","value":"GP","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":2,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":5,"name":"instrument","label":"instrument","form_label":"Instrument","description":null,"output_display":50,"criteria_display":50,"search_flag":null,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":false,"order_display":50,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"ALL","value":"ALL","display":10},{"label":"MXT","value":"MXT","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":2,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":6,"name":"type","label":"type","form_label":"Type","description":null,"output_display":60,"criteria_display":60,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":false,"order_display":60,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":7,"name":"json_schema","label":"json_schema","form_label":"JSON Schema (original)","description":null,"output_display":70,"criteria_display":70,"search_flag":null,"search_type":null,"type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"json","renderer_config":[],"display_detail":70,"selected":true,"order_by":false,"order_display":70,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":8,"name":"search_kw","label":"search_kw","form_label":"KWs searchable","description":null,"output_display":80,"criteria_display":80,"search_flag":null,"search_type":null,"type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"json","renderer_config":[],"display_detail":80,"selected":true,"order_by":false,"order_display":80,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
-curl -d '{"id":9,"name":"json_schema_uploaded","label":"json_schema_uploaded","form_label":"json_schema_uploaded","description":null,"output_display":90,"criteria_display":90,"search_flag":null,"search_type":null,"type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":90,"selected":true,"order_by":false,"order_display":90,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":1,"name":"acronym","label":"acronym","form_label":"Product Acronym","description":null,"primary_key":true,"output_display":10,"criteria_display":10,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":[],"display_detail":10,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"LAMTEST","value":"LAMTEST","display":10},{"label":"LAMTEST_DC1","value":"LAMTEST_DC1","display":20},{"label":"MXT-EVT-CAL","value":"MXT-EVT-CAL","display":30},{"label":"OBLC_ECL","value":"OBLC_ECL","display":40}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":2,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":2,"name":"sp_id","label":"sp_id","form_label":"SP IAP ID","description":null,"primary_key":false,"output_display":20,"criteria_display":20,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":3,"name":"version","label":"version","form_label":"Version","description":null,"primary_key":false,"output_display":30,"criteria_display":30,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":4,"name":"program","label":"program","form_label":"Program","description":null,"primary_key":false,"output_display":40,"criteria_display":40,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"CP","value":"CP","display":10},{"label":"GP","value":"GP","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":2,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":5,"name":"instrument","label":"instrument","form_label":"Instrument","description":null,"primary_key":false,"output_display":50,"criteria_display":50,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"ALL","value":"ALL","display":10},{"label":"MXT","value":"MXT","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":2,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":6,"name":"type","label":"type","form_label":"Type","description":null,"primary_key":false,"output_display":60,"criteria_display":60,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":7,"name":"json_schema","label":"json_schema","form_label":"JSON Schema (original)","description":null,"primary_key":false,"output_display":70,"criteria_display":70,"search_type":null,"type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"json","renderer_config":[],"display_detail":70,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":8,"name":"search_kw","label":"search_kw","form_label":"KWs searchable","description":null,"primary_key":false,"output_display":80,"criteria_display":80,"search_type":null,"type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"json","renderer_config":[],"display_detail":80,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":2}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
+curl -d '{"id":9,"name":"json_schema_uploaded","label":"json_schema_uploaded","form_label":"json_schema_uploaded","description":null,"primary_key":false,"output_display":90,"criteria_display":90,"search_type":null,"type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":90,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/sp_cards/attribute
 
 # Add observations attributes
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/criteria-family
@@ -121,28 +110,28 @@ curl -d '{"label":"Default parameters","display":10,"opened":true}' --header 'Co
 curl -d '{"label":"Astrometry","display":10}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/3/output-category
 curl -d '{"label":"Observation","display":10}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/3/output-category
 
-curl -d '{"id":1,"name":"id","label":"id","form_label":"id","description":"Observation Ident","output_display":10,"criteria_display":10,"search_flag":"ID","search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":10,"selected":true,"order_by":false,"order_display":10,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":3}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":2,"name":"ra","label":"ra","form_label":"Alpha J2000","description":"Alpha J2000","output_display":20,"criteria_display":20,"search_flag":"RA","search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":false,"order_display":20,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":3}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":3,"name":"dec","label":"dec","form_label":"Delta J2000","description":"Delta J2000","output_display":30,"criteria_display":30,"search_flag":"DEC","search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":false,"order_display":30,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":3}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":4,"name":"date_time","label":"date_time","form_label":"Date Time","description":"Date Time","output_display":40,"criteria_display":40,"search_flag":null,"search_type":"between-date","type":"datetime","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":false,"order_display":40,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":5,"name":"exposure_time","label":"exposure_time","form_label":"Exposure Time","description":"Exposure Time","output_display":50,"criteria_display":50,"search_flag":null,"search_type":"between","type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":false,"order_display":50,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":6,"name":"filter","label":"filter","form_label":"Filter","description":"Filter","output_display":60,"criteria_display":60,"search_flag":null,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":false,"order_display":60,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"Halpha","value":"Halpha","display":10},{"label":"SDSS g","value":"SDSS g","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":7,"name":"object_name","label":"object_name","form_label":"Object name","description":"Object name","output_display":70,"criteria_display":70,"search_flag":null,"search_type":"field","type":"string","operator":"lk","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"link","renderer_config":{"href":"http:\/\/cdsportal.u-strasbg.fr\/?target=$value","display":"text","text":"$value","icon":"fas fa-link","blank":true},"display_detail":70,"selected":true,"order_by":false,"order_display":70,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":8,"name":"fits_file","label":"fits_file","form_label":"fits_file","description":null,"output_display":80,"criteria_display":80,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":80,"selected":true,"order_by":false,"order_display":80,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
-curl -d '{"id":9,"name":"fits_png","label":"fits_png","form_label":"fits_png","description":null,"output_display":90,"criteria_display":90,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"image","renderer_config":{"type":"fits","display":"modal","width":"50","height":"50"},"display_detail":90,"selected":true,"order_by":false,"order_display":90,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":1,"name":"id","label":"id","form_label":"id","description":"Observation Ident","primary_key":true,"output_display":10,"criteria_display":10,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":10,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":3}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":2,"name":"ra","label":"ra","form_label":"Alpha J2000","description":"Alpha J2000","primary_key":false,"output_display":20,"criteria_display":20,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":3}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":3,"name":"dec","label":"dec","form_label":"Delta J2000","description":"Delta J2000","primary_key":false,"output_display":30,"criteria_display":30,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":3}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":4,"name":"date_time","label":"date_time","form_label":"Date Time","description":"Date Time","primary_key":false,"output_display":40,"criteria_display":40,"search_type":"between-date","type":"datetime","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":5,"name":"exposure_time","label":"exposure_time","form_label":"Exposure Time","description":"Exposure Time","primary_key":false,"output_display":50,"criteria_display":50,"search_type":"between","type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":6,"name":"filter","label":"filter","form_label":"Filter","description":"Filter","primary_key":false,"output_display":60,"criteria_display":60,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"Halpha","value":"Halpha","display":10},{"label":"SDSS g","value":"SDSS g","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":7,"name":"object_name","label":"object_name","form_label":"Object name","description":"Object name","primary_key":false,"output_display":70,"criteria_display":70,"search_type":"field","type":"string","operator":"lk","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"link","renderer_config":{"href":"http:\/\/cdsportal.u-strasbg.fr\/?target=$value","display":"text","text":"$value","icon":"fas fa-link","blank":true},"display_detail":70,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":1,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":8,"name":"fits_file","label":"fits_file","form_label":"fits_file","description":null,"primary_key":false,"output_display":80,"criteria_display":80,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"download","renderer_config":{"display":"icon-button","text":"DOWNLOAD","icon":"fas fa-download"},"display_detail":80,"selected":true,"order_by":false,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
+curl -d '{"id":9,"name":"fits_png","label":"fits_png","form_label":"fits_png","description":null,"primary_key":false,"output_display":90,"criteria_display":90,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"image","renderer_config":{"type":"fits","display":"modal","width":"50","height":"50"},"display_detail":90,"selected":true,"order_by":false,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":4}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
 
 # Add vvds_f02_udeep attributes
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/criteria-family
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/output-family
 curl -d '{"label":"Default","display":10}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/4/output-category
 
-curl -d '{"id":1,"name":"vvds_ident","label":"vvds_ident","form_label":"vvds_ident","description":null,"output_display":10,"criteria_display":10,"search_flag":"ID","search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":10,"selected":true,"order_by":false,"order_display":10,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
-curl -d '{"id":2,"name":"id_iau","label":"id_iau","form_label":"id_iau","description":null,"output_display":20,"criteria_display":20,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":false,"order_display":20,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
-curl -d '{"id":3,"name":"alpha","label":"alpha","form_label":"alpha","description":null,"output_display":30,"criteria_display":30,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":false,"order_display":30,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
-curl -d '{"id":4,"name":"delta","label":"delta","form_label":"delta","description":null,"output_display":40,"criteria_display":40,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":false,"order_display":40,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
-curl -d '{"id":5,"name":"z_spec","label":"z_spec","form_label":"z_spec","description":null,"output_display":50,"criteria_display":50,"search_flag":null,"search_type":"between","type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":false,"order_display":50,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":4,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
-curl -d '{"id":6,"name":"zflag","label":"zflag","form_label":"zflag","description":null,"output_display":60,"criteria_display":60,"search_flag":null,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":false,"order_display":60,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
-curl -d '{"id":7,"name":"sel_mag","label":"sel_mag","form_label":"sel_mag","description":null,"output_display":70,"criteria_display":70,"search_flag":null,"search_type":"between","type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":70,"selected":true,"order_by":false,"order_display":70,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":4,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":1,"name":"vvds_ident","label":"vvds_ident","form_label":"vvds_ident","description":null,"primary_key":true,"output_display":10,"criteria_display":10,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":10,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":2,"name":"id_iau","label":"id_iau","form_label":"id_iau","description":null,"primary_key":false,"output_display":20,"criteria_display":20,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":20,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":3,"name":"alpha","label":"alpha","form_label":"alpha","description":null,"primary_key":false,"output_display":30,"criteria_display":30,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":30,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":4,"name":"delta","label":"delta","form_label":"delta","description":null,"primary_key":false,"output_display":40,"criteria_display":40,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":40,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":5,"name":"z_spec","label":"z_spec","form_label":"z_spec","description":null,"primary_key":false,"output_display":50,"criteria_display":50,"search_type":"between","type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":50,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":4,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":6,"name":"zflag","label":"zflag","form_label":"zflag","description":null,"primary_key":false,"output_display":60,"criteria_display":60,"search_type":null,"type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":60,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
+curl -d '{"id":7,"name":"sel_mag","label":"sel_mag","form_label":"sel_mag","description":null,"primary_key":false,"output_display":70,"criteria_display":70,"search_type":"between","type":"decimal","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"display_detail":70,"selected":true,"order_by":true,"detail":false,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":4,"id_output_category":5}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/attribute
 
 # Add products attributes
 curl -d '{"label":"Obs","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/criteria-family
@@ -151,18 +140,18 @@ curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type:
 curl -d '{"label":"Default","display":10}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/5/output-category
 curl -d '{"label":"Additionnal","display":20}' --header 'Content-Type: application/json' -X POST http://localhost/output-family/5/output-category
 
-curl -d '{"id":1,"name":"product_id","label":"product_id","form_label":"Product ID","description":null,"output_display":10,"criteria_display":10,"search_flag":null,"search_type":"field","type":"integer","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":[],"selected":true,"order_by":true,"order_display":10,"detail":false,"display_detail":10,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":2,"name":"obs_id","label":"obs_id","form_label":"Observation ID","description":null,"output_display":20,"criteria_display":20,"search_flag":null,"search_type":"field","type":"bigint","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":false,"order_display":20,"detail":false,"display_detail":20,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":3,"name":"acronym","label":"acronym","form_label":"Product Acronym","description":null,"output_display":30,"criteria_display":30,"search_flag":null,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":false,"order_display":30,"detail":false,"display_detail":30,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"ECL-DET-UBC","value":"ECL-DET-UBC","display":10},{"label":"OBLC_ECL","value":"OBLC_ECL","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":4,"name":"url","label":"url","form_label":"Product URL","description":null,"output_display":40,"criteria_display":40,"search_flag":null,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"link","renderer_config":{"href":"$value","display":"text","text":"$value","icon":"fas fa-link","blank":true},"selected":true,"order_by":false,"order_display":40,"detail":false,"display_detail":40,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":5,"name":"criteria","label":"criteria","form_label":"Product criteria (based on KWs searchables)","description":null,"output_display":50,"criteria_display":50,"search_flag":null,"search_type":"svom_json_kw","type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"json","renderer_config":[],"selected":false,"order_by":false,"order_display":50,"detail":false,"display_detail":50,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":6,"name":"added_at","label":"added_at","form_label":"Added at","description":null,"output_display":60,"criteria_display":60,"search_flag":null,"search_type":"between-date","type":"datetime","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":false,"order_display":60,"detail":false,"display_detail":60,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":7,"name":"product_version","label":"product_version","form_label":"Version","description":null,"output_display":70,"criteria_display":70,"search_flag":null,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":false,"order_display":70,"detail":false,"display_detail":70,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":8,"name":"program","label":"program","form_label":"Program","description":null,"output_display":80,"criteria_display":80,"search_flag":null,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":false,"order_display":80,"detail":false,"display_detail":80,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"CoreProgram","value":"CoreProgram","display":10},{"label":"GeneralProgram","value":"GeneralProgram","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":9,"name":"instrument","label":"instrument","form_label":"Instrument","description":null,"output_display":90,"criteria_display":90,"search_flag":null,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":false,"order_display":90,"detail":false,"display_detail":90,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"ECL","value":"ECL","display":10}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":10,"name":"type","label":"type","form_label":"Type","description":null,"output_display":100,"criteria_display":100,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":false,"order_display":100,"detail":false,"display_detail":100,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":11,"name":"upload_filename","label":"upload_filename","form_label":"Filename","description":null,"output_display":110,"criteria_display":110,"search_flag":null,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":false,"order_display":110,"detail":false,"display_detail":110,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":12,"name":"burst_id","label":"burst_id","form_label":"Burst ID","description":null,"output_display":120,"criteria_display":120,"search_flag":null,"search_type":"field","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":false,"order_display":120,"detail":false,"display_detail":120,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":13,"name":"pipeline_version","label":"pipeline_version","form_label":"Pipeline version","description":null,"output_display":130,"criteria_display":130,"search_flag":null,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":false,"order_display":130,"detail":false,"display_detail":130,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":14,"name":"schema_version","label":"schema_version","form_label":"Schema version","description":null,"output_display":140,"criteria_display":140,"search_flag":null,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":false,"order_display":140,"detail":false,"display_detail":140,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
-curl -d '{"id":15,"name":"src_id","label":"src_id","form_label":"SRC ID","description":null,"output_display":150,"criteria_display":150,"search_flag":null,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":false,"order_display":150,"detail":false,"display_detail":150,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":1,"name":"product_id","label":"product_id","form_label":"Product ID","description":null,"primary_key":true,"output_display":10,"criteria_display":10,"search_type":"field","type":"integer","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":[],"selected":true,"order_by":true,"detail":false,"display_detail":10,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":2,"name":"obs_id","label":"obs_id","form_label":"Observation ID","description":null,"primary_key":false,"output_display":20,"criteria_display":20,"search_type":"field","type":"bigint","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":true,"detail":false,"display_detail":20,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":3,"name":"acronym","label":"acronym","form_label":"Product Acronym","description":null,"primary_key":false,"output_display":30,"criteria_display":30,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":true,"detail":false,"display_detail":30,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"ECL-DET-UBC","value":"ECL-DET-UBC","display":10},{"label":"OBLC_ECL","value":"OBLC_ECL","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":4,"name":"url","label":"url","form_label":"Product URL","description":null,"primary_key":false,"output_display":40,"criteria_display":40,"search_type":null,"type":"text","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"link","renderer_config":{"href":"$value","display":"text","text":"$value","icon":"fas fa-link","blank":true},"selected":true,"order_by":true,"detail":false,"display_detail":40,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":5,"name":"criteria","label":"criteria","form_label":"Product criteria (based on KWs searchables)","description":null,"primary_key":false,"output_display":50,"criteria_display":50,"search_type":"svom_json_kw","type":"json","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":"json","renderer_config":[],"selected":false,"order_by":true,"detail":false,"display_detail":50,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":6,"name":"added_at","label":"added_at","form_label":"Added at","description":null,"primary_key":false,"output_display":60,"criteria_display":60,"search_type":"between-date","type":"datetime","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":true,"detail":false,"display_detail":60,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":7,"name":"product_version","label":"product_version","form_label":"Version","description":null,"primary_key":false,"output_display":70,"criteria_display":70,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":true,"detail":false,"display_detail":70,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":8,"name":"program","label":"program","form_label":"Program","description":null,"primary_key":false,"output_display":80,"criteria_display":80,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":true,"detail":false,"display_detail":80,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"CoreProgram","value":"CoreProgram","display":10},{"label":"GeneralProgram","value":"GeneralProgram","display":20}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":9,"name":"instrument","label":"instrument","form_label":"Instrument","description":null,"primary_key":false,"output_display":90,"criteria_display":90,"search_type":"select","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":true,"detail":false,"display_detail":90,"renderer_detail":null,"renderer_detail_config":null,"options":[{"label":"ECL","value":"ECL","display":10}],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":6,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":10,"name":"type","label":"type","form_label":"Type","description":null,"primary_key":false,"output_display":100,"criteria_display":100,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":true,"detail":false,"display_detail":100,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":11,"name":"upload_filename","label":"upload_filename","form_label":"Filename","description":null,"primary_key":false,"output_display":110,"criteria_display":110,"search_type":null,"type":"string","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":true,"detail":false,"display_detail":110,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":12,"name":"burst_id","label":"burst_id","form_label":"Burst ID","description":null,"primary_key":false,"output_display":120,"criteria_display":120,"search_type":"field","type":"string","operator":"eq","min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":true,"order_by":true,"detail":false,"display_detail":120,"renderer_detail":null,"renderer_detail_config":null,"options":[],"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":5,"id_output_category":6}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":13,"name":"pipeline_version","label":"pipeline_version","form_label":"Pipeline version","description":null,"primary_key":false,"output_display":130,"criteria_display":130,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":true,"detail":false,"display_detail":130,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":14,"name":"schema_version","label":"schema_version","form_label":"Schema version","description":null,"primary_key":false,"output_display":140,"criteria_display":140,"search_type":null,"type":"float","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":true,"detail":false,"display_detail":140,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
+curl -d '{"id":15,"name":"src_id","label":"src_id","form_label":"SRC ID","description":null,"primary_key":false,"output_display":150,"criteria_display":150,"search_type":null,"type":"integer","operator":null,"min":null,"max":null,"placeholder_min":null,"placeholder_max":null,"renderer":null,"renderer_config":null,"selected":false,"order_by":true,"detail":false,"display_detail":150,"renderer_detail":null,"renderer_detail_config":null,"options":null,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":7}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/products/attribute
diff --git a/server/doctrine-proxy/__CG__AppEntityAttribute.php b/server/doctrine-proxy/__CG__AppEntityAttribute.php
index f2c804ff..ce5f8c6f 100644
--- a/server/doctrine-proxy/__CG__AppEntityAttribute.php
+++ b/server/doctrine-proxy/__CG__AppEntityAttribute.php
@@ -67,10 +67,10 @@ class Attribute extends \App\Entity\Attribute implements \Doctrine\ORM\Proxy\Pro
     public function __sleep()
     {
         if ($this->__isInitialized__) {
-            return ['__isInitialized__', 'id', 'dataset', 'name', 'label', 'formLabel', 'description', 'outputDisplay', 'criteriaDisplay', 'searchFlag', 'searchType', 'operator', 'type', 'min', 'max', 'placeholderMin', 'placeholderMax', 'renderer', 'rendererConfig', 'selected', 'orderBy', 'orderDisplay', 'detail', 'displayDetail', 'rendererDetail', 'rendererDetailConfig', 'options', 'voUtype', 'voUcd', 'voUnit', 'voDescription', 'voDatatype', 'voSize', 'criteriaFamily', 'outputCategory'];
+            return ['__isInitialized__', 'id', 'dataset', 'name', 'label', 'formLabel', 'description', 'primaryKey', 'type', 'searchType', 'operator', 'min', 'max', 'options', 'placeholderMin', 'placeholderMax', 'criteriaDisplay', 'outputDisplay', 'selected', 'renderer', 'rendererConfig', 'orderBy', 'detail', 'displayDetail', 'rendererDetail', 'rendererDetailConfig', 'voUtype', 'voUcd', 'voUnit', 'voDescription', 'voDatatype', 'voSize', 'criteriaFamily', 'outputCategory'];
         }
 
-        return ['__isInitialized__', 'id', 'dataset', 'name', 'label', 'formLabel', 'description', 'outputDisplay', 'criteriaDisplay', 'searchFlag', 'searchType', 'operator', 'type', 'min', 'max', 'placeholderMin', 'placeholderMax', 'renderer', 'rendererConfig', 'selected', 'orderBy', 'orderDisplay', 'detail', 'displayDetail', 'rendererDetail', 'rendererDetailConfig', 'options', 'voUtype', 'voUcd', 'voUnit', 'voDescription', 'voDatatype', 'voSize', 'criteriaFamily', 'outputCategory'];
+        return ['__isInitialized__', 'id', 'dataset', 'name', 'label', 'formLabel', 'description', 'primaryKey', 'type', 'searchType', 'operator', 'min', 'max', 'options', 'placeholderMin', 'placeholderMax', 'criteriaDisplay', 'outputDisplay', 'selected', 'renderer', 'rendererConfig', 'orderBy', 'detail', 'displayDetail', 'rendererDetail', 'rendererDetailConfig', 'voUtype', 'voUcd', 'voUnit', 'voDescription', 'voDatatype', 'voSize', 'criteriaFamily', 'outputCategory'];
     }
 
     /**
@@ -305,67 +305,45 @@ class Attribute extends \App\Entity\Attribute implements \Doctrine\ORM\Proxy\Pro
     /**
      * {@inheritDoc}
      */
-    public function getOutputDisplay()
-    {
-
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOutputDisplay', []);
-
-        return parent::getOutputDisplay();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public function setOutputDisplay($outputDisplay)
-    {
-
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOutputDisplay', [$outputDisplay]);
-
-        return parent::setOutputDisplay($outputDisplay);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public function setCriteriaDisplay($criteriaDisplay)
+    public function getPrimaryKey()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setCriteriaDisplay', [$criteriaDisplay]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getPrimaryKey', []);
 
-        return parent::setCriteriaDisplay($criteriaDisplay);
+        return parent::getPrimaryKey();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getCriteriaDisplay()
+    public function setPrimaryKey($primaryKey)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getCriteriaDisplay', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setPrimaryKey', [$primaryKey]);
 
-        return parent::getCriteriaDisplay();
+        return parent::setPrimaryKey($primaryKey);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getSearchFlag()
+    public function getType()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSearchFlag', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getType', []);
 
-        return parent::getSearchFlag();
+        return parent::getType();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setSearchFlag($searchFlag)
+    public function setType($type)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSearchFlag', [$searchFlag]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setType', [$type]);
 
-        return parent::setSearchFlag($searchFlag);
+        return parent::setType($type);
     }
 
     /**
@@ -415,67 +393,67 @@ class Attribute extends \App\Entity\Attribute implements \Doctrine\ORM\Proxy\Pro
     /**
      * {@inheritDoc}
      */
-    public function getType()
+    public function getMin()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getType', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getMin', []);
 
-        return parent::getType();
+        return parent::getMin();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setType($type)
+    public function setMin($min)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setType', [$type]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setMin', [$min]);
 
-        return parent::setType($type);
+        return parent::setMin($min);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getMin()
+    public function getMax()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getMin', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getMax', []);
 
-        return parent::getMin();
+        return parent::getMax();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setMin($min)
+    public function setMax($max)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setMin', [$min]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setMax', [$max]);
 
-        return parent::setMin($min);
+        return parent::setMax($max);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getMax()
+    public function getOptions()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getMax', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOptions', []);
 
-        return parent::getMax();
+        return parent::getOptions();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setMax($max)
+    public function setOptions($options)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setMax', [$max]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOptions', [$options]);
 
-        return parent::setMax($max);
+        return parent::setOptions($options);
     }
 
     /**
@@ -525,265 +503,287 @@ class Attribute extends \App\Entity\Attribute implements \Doctrine\ORM\Proxy\Pro
     /**
      * {@inheritDoc}
      */
-    public function getRendererConfig()
+    public function setCriteriaDisplay($criteriaDisplay)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getRendererConfig', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setCriteriaDisplay', [$criteriaDisplay]);
 
-        return parent::getRendererConfig();
+        return parent::setCriteriaDisplay($criteriaDisplay);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setRendererConfig($rendererConfig)
+    public function getCriteriaDisplay()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setRendererConfig', [$rendererConfig]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getCriteriaDisplay', []);
 
-        return parent::setRendererConfig($rendererConfig);
+        return parent::getCriteriaDisplay();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getRenderer()
+    public function getOutputDisplay()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getRenderer', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOutputDisplay', []);
 
-        return parent::getRenderer();
+        return parent::getOutputDisplay();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setRenderer($renderer)
+    public function setOutputDisplay($outputDisplay)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setRenderer', [$renderer]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOutputDisplay', [$outputDisplay]);
 
-        return parent::setRenderer($renderer);
+        return parent::setOutputDisplay($outputDisplay);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getDisplayDetail()
+    public function getSelected()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDisplayDetail', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSelected', []);
 
-        return parent::getDisplayDetail();
+        return parent::getSelected();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setDisplayDetail($displayDetail)
+    public function setSelected($selected)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDisplayDetail', [$displayDetail]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSelected', [$selected]);
 
-        return parent::setDisplayDetail($displayDetail);
+        return parent::setSelected($selected);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getVoUtype()
+    public function getRenderer()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoUtype', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getRenderer', []);
 
-        return parent::getVoUtype();
+        return parent::getRenderer();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setVoUtype($voUtype)
+    public function setRenderer($renderer)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoUtype', [$voUtype]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setRenderer', [$renderer]);
 
-        return parent::setVoUtype($voUtype);
+        return parent::setRenderer($renderer);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getVoUcd()
+    public function getRendererConfig()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoUcd', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getRendererConfig', []);
 
-        return parent::getVoUcd();
+        return parent::getRendererConfig();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setVoUcd($voUcd)
+    public function setRendererConfig($rendererConfig)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoUcd', [$voUcd]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setRendererConfig', [$rendererConfig]);
 
-        return parent::setVoUcd($voUcd);
+        return parent::setRendererConfig($rendererConfig);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getVoUnit()
+    public function getOrderBy()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoUnit', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOrderBy', []);
 
-        return parent::getVoUnit();
+        return parent::getOrderBy();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setVoUnit($voUnit)
+    public function setOrderBy($orderBy)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoUnit', [$voUnit]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOrderBy', [$orderBy]);
 
-        return parent::setVoUnit($voUnit);
+        return parent::setOrderBy($orderBy);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getVoDescription()
+    public function getDisplayDetail()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoDescription', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDisplayDetail', []);
 
-        return parent::getVoDescription();
+        return parent::getDisplayDetail();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setVoDescription($voDescription)
+    public function setDisplayDetail($displayDetail)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoDescription', [$voDescription]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDisplayDetail', [$displayDetail]);
 
-        return parent::setVoDescription($voDescription);
+        return parent::setDisplayDetail($displayDetail);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getVoDatatype()
+    public function getVoUtype()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoDatatype', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoUtype', []);
 
-        return parent::getVoDatatype();
+        return parent::getVoUtype();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setVoDatatype($voDatatype)
+    public function setVoUtype($voUtype)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoDatatype', [$voDatatype]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoUtype', [$voUtype]);
 
-        return parent::setVoDatatype($voDatatype);
+        return parent::setVoUtype($voUtype);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getVoSize()
+    public function getVoUcd()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoSize', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoUcd', []);
 
-        return parent::getVoSize();
+        return parent::getVoUcd();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setVoSize($voSize)
+    public function setVoUcd($voUcd)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoSize', [$voSize]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoUcd', [$voUcd]);
 
-        return parent::setVoSize($voSize);
+        return parent::setVoUcd($voUcd);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getSelected()
+    public function getVoUnit()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSelected', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoUnit', []);
 
-        return parent::getSelected();
+        return parent::getVoUnit();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setSelected($selected)
+    public function setVoUnit($voUnit)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSelected', [$selected]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoUnit', [$voUnit]);
 
-        return parent::setSelected($selected);
+        return parent::setVoUnit($voUnit);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getOrderBy()
+    public function getVoDescription()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOrderBy', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoDescription', []);
 
-        return parent::getOrderBy();
+        return parent::getVoDescription();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setOrderBy($orderBy)
+    public function setVoDescription($voDescription)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOrderBy', [$orderBy]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoDescription', [$voDescription]);
 
-        return parent::setOrderBy($orderBy);
+        return parent::setVoDescription($voDescription);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getVoDatatype()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoDatatype', []);
+
+        return parent::getVoDatatype();
     }
 
     /**
      * {@inheritDoc}
      */
-    public function getOrderDisplay()
+    public function setVoDatatype($voDatatype)
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOrderDisplay', []);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoDatatype', [$voDatatype]);
 
-        return parent::getOrderDisplay();
+        return parent::setVoDatatype($voDatatype);
     }
 
     /**
      * {@inheritDoc}
      */
-    public function setOrderDisplay($orderDisplay)
+    public function getVoSize()
     {
 
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOrderDisplay', [$orderDisplay]);
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getVoSize', []);
 
-        return parent::setOrderDisplay($orderDisplay);
+        return parent::getVoSize();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setVoSize($voSize)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setVoSize', [$voSize]);
+
+        return parent::setVoSize($voSize);
     }
 
     /**
@@ -852,28 +852,6 @@ class Attribute extends \App\Entity\Attribute implements \Doctrine\ORM\Proxy\Pro
         return parent::setRendererDetailConfig($rendererDetailConfig);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public function getOptions()
-    {
-
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getOptions', []);
-
-        return parent::getOptions();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public function setOptions($options)
-    {
-
-        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setOptions', [$options]);
-
-        return parent::setOptions($options);
-    }
-
     /**
      * {@inheritDoc}
      */
diff --git a/server/src/Action/AttributeAction.php b/server/src/Action/AttributeAction.php
index d91d3b5e..0888fd36 100644
--- a/server/src/Action/AttributeAction.php
+++ b/server/src/Action/AttributeAction.php
@@ -88,26 +88,25 @@ final class AttributeAction extends AbstractAction
         $attribute->setLabel($parsedBody['label']);
         $attribute->setFormLabel($parsedBody['form_label']);
         $attribute->setDescription($parsedBody['description']);
-        $attribute->setOutputDisplay($parsedBody['output_display']);
-        $attribute->setCriteriaDisplay($parsedBody['criteria_display']);
-        $attribute->setSearchFlag($parsedBody['search_flag']);
+        $attribute->setPrimaryKey($parsedBody['primary_key']);
+        $attribute->setType($parsedBody['type']);
         $attribute->setSearchType($parsedBody['search_type']);
         $attribute->setOperator($parsedBody['operator']);
-        $attribute->setType($parsedBody['type']);
         $attribute->setMin($parsedBody['min']);
         $attribute->setMax($parsedBody['max']);
+        $attribute->setOptions($parsedBody['options']);
         $attribute->setPlaceholderMin($parsedBody['placeholder_min']);
         $attribute->setPlaceholderMax($parsedBody['placeholder_max']);
+        $attribute->setCriteriaDisplay($parsedBody['criteria_display']);
+        $attribute->setOutputDisplay($parsedBody['output_display']);
+        $attribute->setSelected($parsedBody['selected']);
         $attribute->setRenderer($parsedBody['renderer']);
         $attribute->setRendererConfig($parsedBody['renderer_config']);
-        $attribute->setDisplayDetail($parsedBody['display_detail']);
-        $attribute->setSelected($parsedBody['selected']);
         $attribute->setOrderBy($parsedBody['order_by']);
-        $attribute->setOrderDisplay($parsedBody['order_display']);
         $attribute->setDetail($parsedBody['detail']);
+        $attribute->setDisplayDetail($parsedBody['display_detail']);
         $attribute->setRendererDetail($parsedBody['renderer_detail']);
         $attribute->setRendererDetailConfig($parsedBody['renderer_detail_config']);
-        $attribute->setOptions($parsedBody['options']);
         $attribute->setVoUtype($parsedBody['vo_utype']);
         $attribute->setVoUcd($parsedBody['vo_ucd']);
         $attribute->setVoUnit($parsedBody['vo_unit']);
diff --git a/server/src/Action/AttributeListAction.php b/server/src/Action/AttributeListAction.php
index aa607938..16490fcf 100644
--- a/server/src/Action/AttributeListAction.php
+++ b/server/src/Action/AttributeListAction.php
@@ -73,7 +73,6 @@ final class AttributeListAction extends AbstractAction
                 'criteria_display',
                 'output_display',
                 'display_detail',
-                'order_display'
             );
             foreach ($fields as $a) {
                 if ($this->isEmptyField($a, $parsedBody)) {
@@ -108,32 +107,25 @@ final class AttributeListAction extends AbstractAction
         $attribute->setLabel($this->getValue($parsedBody, 'label'));
         $attribute->setFormLabel($this->getValue($parsedBody, 'form_label'));
         $attribute->setDescription($this->getValue($parsedBody, 'description'));
-        $attribute->setOutputDisplay($this->getValue($parsedBody, 'output_display'));
-        $attribute->setCriteriaDisplay($this->getValue($parsedBody, 'criteria_display'));
-        $attribute->setSearchFlag($this->getValue($parsedBody, 'search_flag'));
+        $attribute->setPrimaryKey($parsedBody['primary_key']);
+        $attribute->setType($this->getValue($parsedBody, 'type'));
         $attribute->setSearchType($this->getValue($parsedBody, 'search_type'));
         $attribute->setOperator($this->getValue($parsedBody, 'operator'));
-        $attribute->setType($this->getValue($parsedBody, 'type'));
         $attribute->setMin($this->getValue($parsedBody, 'min'));
         $attribute->setMax($this->getValue($parsedBody, 'max'));
+        $attribute->setOptions($this->getValue($parsedBody, 'options'));
         $attribute->setPlaceholderMin($this->getValue($parsedBody, 'placeholder_min'));
         $attribute->setPlaceholderMax($this->getValue($parsedBody, 'placeholder_max'));
+        $attribute->setCriteriaDisplay($this->getValue($parsedBody, 'criteria_display'));
+        $attribute->setOutputDisplay($this->getValue($parsedBody, 'output_display'));
+        $attribute->setSelected($this->getValue($parsedBody, 'selected'));
         $attribute->setRenderer($this->getValue($parsedBody, 'renderer'));
         $attribute->setRendererConfig($this->getValue($parsedBody, 'renderer_config'));
+        $attribute->setOrderBy($this->getValue($parsedBody, 'order_by'));
+        $attribute->setDetail($this->getValue($parsedBody, 'detail'));
         $attribute->setDisplayDetail($this->getValue($parsedBody, 'display_detail'));
-        if (!is_null($this->getValue($parsedBody, 'selected'))) {
-            $attribute->setSelected($this->getValue($parsedBody, 'selected'));
-        }
-        if (!is_null($this->getValue($parsedBody, 'order_by'))) {
-            $attribute->setOrderBy($this->getValue($parsedBody, 'order_by'));
-        }
-        $attribute->setOrderDisplay($this->getValue($parsedBody, 'order_display'));
-        if (!is_null($this->getValue($parsedBody, 'detail'))) {
-            $attribute->setDetail($this->getValue($parsedBody, 'detail'));
-        }
         $attribute->setRendererDetail($this->getValue($parsedBody, 'renderer_detail'));
         $attribute->setRendererDetailConfig($this->getValue($parsedBody, 'renderer_detail_config'));
-        $attribute->setOptions($this->getValue($parsedBody, 'options'));
         $attribute->setVoUtype($this->getValue($parsedBody, 'vo_utype'));
         $attribute->setVoUcd($this->getValue($parsedBody, 'vo_ucd'));
         $attribute->setVoUnit($this->getValue($parsedBody, 'vo_unit'));
diff --git a/server/src/Entity/Attribute.php b/server/src/Entity/Attribute.php
index 26540704..c6af3238 100644
--- a/server/src/Entity/Attribute.php
+++ b/server/src/Entity/Attribute.php
@@ -67,25 +67,18 @@ class Attribute implements \JsonSerializable
     protected $description;
 
     /**
-     * @var int
-     *
-     * @Column(type="integer", name="output_display", nullable=true)
-     */
-    protected $outputDisplay;
-
-    /**
-     * @var int
-     *
-     * @Column(type="integer", name="criteria_display", nullable=true)
+     * @var bool
+     * 
+     * @Column(type="boolean", name="primary_key", nullable=false)
      */
-    protected $criteriaDisplay;
+    protected $primaryKey;
 
     /**
      * @var string
      *
-     * @Column(type="string", name="search_flag", nullable=true)
+     * @Column(type="string", name="type", nullable=true)
      */
-    protected $searchFlag;
+    protected $type;
 
     /**
      * @var string
@@ -104,23 +97,23 @@ class Attribute implements \JsonSerializable
     /**
      * @var string
      *
-     * @Column(type="string", name="type", nullable=true)
+     * @Column(type="string", nullable=true)
      */
-    protected $type;
+    protected $min;
 
     /**
      * @var string
      *
      * @Column(type="string", nullable=true)
      */
-    protected $min;
+    protected $max;
 
     /**
      * @var string
      *
-     * @Column(type="string", nullable=true)
+     * @Column(type="json", name="options", nullable=true)
      */
-    protected $max;
+    protected $options;
 
     /**
      * @var string
@@ -137,18 +130,18 @@ class Attribute implements \JsonSerializable
     protected $placeholderMax;
 
     /**
-     * @var string
+     * @var int
      *
-     * @Column(type="string", name="renderer", nullable=true)
+     * @Column(type="integer", name="criteria_display", nullable=true)
      */
-    protected $renderer;
+    protected $criteriaDisplay;
 
     /**
-     * @var string
+     * @var int
      *
-     * @Column(type="json", name="renderer_config", nullable=true)
+     * @Column(type="integer", name="output_display", nullable=true)
      */
-    protected $rendererConfig;
+    protected $outputDisplay;
 
     /**
      * @var bool
@@ -158,18 +151,25 @@ class Attribute implements \JsonSerializable
     protected $selected = false;
 
     /**
-     * @var bool
+     * @var string
      *
-     * @Column(type="boolean", name="order_by", nullable=false, options={"default":false})
+     * @Column(type="string", name="renderer", nullable=true)
      */
-    protected $orderBy = false;
+    protected $renderer;
 
     /**
-     * @var int
+     * @var string
+     *
+     * @Column(type="json", name="renderer_config", nullable=true)
+     */
+    protected $rendererConfig;
+
+    /**
+     * @var bool
      *
-     * @Column(type="integer", name="order_display", nullable=true)
+     * @Column(type="boolean", name="order_by", nullable=false, options={"default":false})
      */
-    protected $orderDisplay;
+    protected $orderBy = false;
 
     /**
      * @var bool
@@ -199,13 +199,6 @@ class Attribute implements \JsonSerializable
      */
     protected $rendererDetailConfig;
 
-    /**
-     * @var string
-     *
-     * @Column(type="json", name="options", nullable=true)
-     */
-    protected $options;
-
     /**
      * @var string
      *
@@ -325,34 +318,24 @@ class Attribute implements \JsonSerializable
         $this->description = $description;
     }
 
-    public function getOutputDisplay()
-    {
-        return $this->outputDisplay;
-    }
-
-    public function setOutputDisplay($outputDisplay)
+    public function getPrimaryKey()
     {
-        $this->outputDisplay = $outputDisplay;
-    }
-
-    public function setCriteriaDisplay($criteriaDisplay)
-    {
-        $this->criteriaDisplay = $criteriaDisplay;
+        return $this->primaryKey;
     }
 
-    public function getCriteriaDisplay()
+    public function setPrimaryKey($primaryKey)
     {
-        return $this->criteriaDisplay;
+        $this->primaryKey = $primaryKey;
     }
 
-    public function getSearchFlag()
+    public function getType()
     {
-        return $this->searchFlag;
+        return $this->type;
     }
 
-    public function setSearchFlag($searchFlag)
+    public function setType($type)
     {
-        $this->searchFlag = $searchFlag;
+        $this->type = $type;
     }
 
     public function getSearchType()
@@ -375,16 +358,6 @@ class Attribute implements \JsonSerializable
         $this->operator = $operator;
     }
 
-    public function getType()
-    {
-        return $this->type;
-    }
-
-    public function setType($type)
-    {
-        $this->type = $type;
-    }
-
     public function getMin()
     {
         return $this->min;
@@ -405,6 +378,16 @@ class Attribute implements \JsonSerializable
         $this->max = $max;
     }
 
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    public function setOptions($options)
+    {
+        $this->options = $options;
+    }
+
     public function getPlaceholderMin()
     {
         return $this->placeholderMin;
@@ -425,14 +408,34 @@ class Attribute implements \JsonSerializable
         $this->placeholderMax = $placeholderMax;
     }
 
-    public function getRendererConfig()
+    public function setCriteriaDisplay($criteriaDisplay)
     {
-        return $this->rendererConfig;
+        $this->criteriaDisplay = $criteriaDisplay;
     }
 
-    public function setRendererConfig($rendererConfig)
+    public function getCriteriaDisplay()
     {
-        $this->rendererConfig = $rendererConfig;
+        return $this->criteriaDisplay;
+    }
+
+    public function getOutputDisplay()
+    {
+        return $this->outputDisplay;
+    }
+
+    public function setOutputDisplay($outputDisplay)
+    {
+        $this->outputDisplay = $outputDisplay;
+    }
+
+    public function getSelected()
+    {
+        return $this->selected;
+    }
+
+    public function setSelected($selected)
+    {
+        $this->selected = $selected;
     }
 
     public function getRenderer()
@@ -445,6 +448,26 @@ class Attribute implements \JsonSerializable
         $this->renderer = $renderer;
     }
 
+    public function getRendererConfig()
+    {
+        return $this->rendererConfig;
+    }
+
+    public function setRendererConfig($rendererConfig)
+    {
+        $this->rendererConfig = $rendererConfig;
+    }
+
+    public function getOrderBy()
+    {
+        return $this->orderBy;
+    }
+
+    public function setOrderBy($orderBy)
+    {
+        $this->orderBy = $orderBy;
+    }
+
     public function getDisplayDetail()
     {
         return $this->displayDetail;
@@ -515,36 +538,6 @@ class Attribute implements \JsonSerializable
         $this->voSize = $voSize;
     }
 
-    public function getSelected()
-    {
-        return $this->selected;
-    }
-
-    public function setSelected($selected)
-    {
-        $this->selected = $selected;
-    }
-
-    public function getOrderBy()
-    {
-        return $this->orderBy;
-    }
-
-    public function setOrderBy($orderBy)
-    {
-        $this->orderBy = $orderBy;
-    }
-
-    public function getOrderDisplay()
-    {
-        return $this->orderDisplay;
-    }
-
-    public function setOrderDisplay($orderDisplay)
-    {
-        $this->orderDisplay = $orderDisplay;
-    }
-
     public function getDetail()
     {
         return $this->detail;
@@ -575,16 +568,6 @@ class Attribute implements \JsonSerializable
         $this->rendererDetailConfig = $rendererDetailConfig;
     }
 
-    public function getOptions()
-    {
-        return $this->options;
-    }
-
-    public function setOptions($options)
-    {
-        $this->options = $options;
-    }
-
     public function getCriteriaFamily()
     {
         return $this->criteriaFamily;
@@ -613,26 +596,25 @@ class Attribute implements \JsonSerializable
             'label' => $this->getLabel(),
             'form_label' => $this->getFormLabel(),
             'description' => $this->getDescription(),
-            'output_display' => $this->getOutputDisplay(),
-            'criteria_display' => $this->getCriteriaDisplay(),
-            'search_flag' => $this->getSearchFlag(),
-            'search_type' => $this->getSearchType(),
+            'primary_key' => $this->getPrimaryKey(),
             'type' => $this->getType(),
+            'search_type' => $this->getSearchType(),
             'operator' => $this->getOperator(),
             'min' => $this->getMin(),
             'max' => $this->getMax(),
+            'options' => $this->getOptions(),
             'placeholder_min' => $this->getPlaceholderMin(),
             'placeholder_max' => $this->getPlaceholderMax(),
+            'criteria_display' => $this->getCriteriaDisplay(),
+            'output_display' => $this->getOutputDisplay(),
+            'selected' => $this->getSelected(),
             'renderer' => $this->getRenderer(),
             'renderer_config' => $this->getRendererConfig(),
-            'selected' => $this->getSelected(),
             'order_by' => $this->getOrderBy(),
-            'order_display' => $this->getOrderDisplay(),
             'detail' => $this->getDetail(),
             'display_detail' => $this->getDisplayDetail(),
             'renderer_detail' => $this->getRendererDetail(),
             'renderer_detail_config' => $this->getRendererDetailConfig(),
-            'options' => $this->getOptions(),
             'vo_utype' => $this->getVoUtype(),
             'vo_ucd' => $this->getVoUcd(),
             'vo_unit' => $this->getVoUnit(),
diff --git a/server/tests/Action/AttributeActionTest.php b/server/tests/Action/AttributeActionTest.php
index 091dfc85..c26b85c5 100644
--- a/server/tests/Action/AttributeActionTest.php
+++ b/server/tests/Action/AttributeActionTest.php
@@ -134,6 +134,8 @@ final class AttributeActionTest extends TestCase
             'label' => 'ID',
             'form_label' => 'ID',
             'description' => 'ID description',
+            'primary_key' => false,
+            'order_primary_key' => null,
             'output_display' => 20,
             'criteria_display' => 10,
             'search_flag' => 'ID',
diff --git a/server/tests/Action/AttributeListActionTest.php b/server/tests/Action/AttributeListActionTest.php
index 74aee26b..158c8cb5 100644
--- a/server/tests/Action/AttributeListActionTest.php
+++ b/server/tests/Action/AttributeListActionTest.php
@@ -85,6 +85,8 @@ final class AttributeListActionTest extends TestCase
             'name' => 'id',
             'label' => 'id',
             'form_label' => 'ID',
+            'primary_key' => false,
+            'order_primary_key' => null,
             'type' => 'integer',
             'criteria_display' => 10,
             'output_display' => 10,
-- 
GitLab