feat: added new confidence question in annotation and data modell
This commit is contained in:
1
drizzle/0014_groovy_patriot.sql
Normal file
1
drizzle/0014_groovy_patriot.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `annotation` ADD `confidence` integer NOT NULL;
|
||||
954
drizzle/meta/0014_snapshot.json
Normal file
954
drizzle/meta/0014_snapshot.json
Normal file
@@ -0,0 +1,954 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "1413326b-8df5-4c48-9460-9c60528d0393",
|
||||
"prevId": "a27062e1-cbe8-4669-95fd-2cda4cbaf569",
|
||||
"tables": {
|
||||
"annotation": {
|
||||
"name": "annotation",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"dataset_entry_id": {
|
||||
"name": "dataset_entry_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"experiment_id": {
|
||||
"name": "experiment_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"rating": {
|
||||
"name": "rating",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"confidence": {
|
||||
"name": "confidence",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"dialect_label": {
|
||||
"name": "dialect_label",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"unique_annotation": {
|
||||
"name": "unique_annotation",
|
||||
"columns": [
|
||||
"dataset_entry_id",
|
||||
"experiment_id",
|
||||
"user_id"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"annotation_dataset_entry_id_dataset_entry_id_fk": {
|
||||
"name": "annotation_dataset_entry_id_dataset_entry_id_fk",
|
||||
"tableFrom": "annotation",
|
||||
"tableTo": "dataset_entry",
|
||||
"columnsFrom": [
|
||||
"dataset_entry_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"annotation_experiment_id_experiment_id_fk": {
|
||||
"name": "annotation_experiment_id_experiment_id_fk",
|
||||
"tableFrom": "annotation",
|
||||
"tableTo": "experiment",
|
||||
"columnsFrom": [
|
||||
"experiment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"account": {
|
||||
"name": "account",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"account_id": {
|
||||
"name": "account_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"provider_id": {
|
||||
"name": "provider_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"access_token": {
|
||||
"name": "access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"refresh_token": {
|
||||
"name": "refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"id_token": {
|
||||
"name": "id_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"access_token_expires_at": {
|
||||
"name": "access_token_expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"refresh_token_expires_at": {
|
||||
"name": "refresh_token_expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"scope": {
|
||||
"name": "scope",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"password": {
|
||||
"name": "password",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(cast(unixepoch('subsecond') * 1000 as integer))"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"account_userId_idx": {
|
||||
"name": "account_userId_idx",
|
||||
"columns": [
|
||||
"user_id"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"account_user_id_user_id_fk": {
|
||||
"name": "account_user_id_user_id_fk",
|
||||
"tableFrom": "account",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"session": {
|
||||
"name": "session",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"token": {
|
||||
"name": "token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(cast(unixepoch('subsecond') * 1000 as integer))"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"ip_address": {
|
||||
"name": "ip_address",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_agent": {
|
||||
"name": "user_agent",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"session_token_unique": {
|
||||
"name": "session_token_unique",
|
||||
"columns": [
|
||||
"token"
|
||||
],
|
||||
"isUnique": true
|
||||
},
|
||||
"session_userId_idx": {
|
||||
"name": "session_userId_idx",
|
||||
"columns": [
|
||||
"user_id"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"session_user_id_user_id_fk": {
|
||||
"name": "session_user_id_user_id_fk",
|
||||
"tableFrom": "session",
|
||||
"tableTo": "user",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"user": {
|
||||
"name": "user",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email_verified": {
|
||||
"name": "email_verified",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"image": {
|
||||
"name": "image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"admin": {
|
||||
"name": "admin",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(cast(unixepoch('subsecond') * 1000 as integer))"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(cast(unixepoch('subsecond') * 1000 as integer))"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"user_email_unique": {
|
||||
"name": "user_email_unique",
|
||||
"columns": [
|
||||
"email"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"verification": {
|
||||
"name": "verification",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"identifier": {
|
||||
"name": "identifier",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(cast(unixepoch('subsecond') * 1000 as integer))"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(cast(unixepoch('subsecond') * 1000 as integer))"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"verification_identifier_idx": {
|
||||
"name": "verification_identifier_idx",
|
||||
"columns": [
|
||||
"identifier"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"dataset_entry": {
|
||||
"name": "dataset_entry",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"external_id": {
|
||||
"name": "external_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"speaker_id": {
|
||||
"name": "speaker_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"model_name": {
|
||||
"name": "model_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"utterance_id": {
|
||||
"name": "utterance_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"utterance_text": {
|
||||
"name": "utterance_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"dataset_id": {
|
||||
"name": "dataset_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file_name": {
|
||||
"name": "file_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"dialect": {
|
||||
"name": "dialect",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"iteration": {
|
||||
"name": "iteration",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"duration_ms": {
|
||||
"name": "duration_ms",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"rms_value": {
|
||||
"name": "rms_value",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"longest_pause": {
|
||||
"name": "longest_pause",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"utmos_score": {
|
||||
"name": "utmos_score",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"wer_score": {
|
||||
"name": "wer_score",
|
||||
"type": "real",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"dataset_entry_dataset_id_dataset_id_fk": {
|
||||
"name": "dataset_entry_dataset_id_dataset_id_fk",
|
||||
"tableFrom": "dataset_entry",
|
||||
"tableTo": "dataset",
|
||||
"columnsFrom": [
|
||||
"dataset_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"dataset": {
|
||||
"name": "dataset",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"experiment_calibration": {
|
||||
"name": "experiment_calibration",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"experiment_id": {
|
||||
"name": "experiment_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"dialect_label": {
|
||||
"name": "dialect_label",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"utterance_id": {
|
||||
"name": "utterance_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"utterance_text": {
|
||||
"name": "utterance_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"order": {
|
||||
"name": "order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"file": {
|
||||
"name": "file",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"experiment_calibration_experiment_id_experiment_id_fk": {
|
||||
"name": "experiment_calibration_experiment_id_experiment_id_fk",
|
||||
"tableFrom": "experiment_calibration",
|
||||
"tableTo": "experiment",
|
||||
"columnsFrom": [
|
||||
"experiment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"experiment": {
|
||||
"name": "experiment",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"published": {
|
||||
"name": "published",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"annotation_tool": {
|
||||
"name": "annotation_tool",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"onboarding_enabled": {
|
||||
"name": "onboarding_enabled",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"calibration_enabled": {
|
||||
"name": "calibration_enabled",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": false
|
||||
},
|
||||
"dataset_id": {
|
||||
"name": "dataset_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"experiment_dataset_id_dataset_id_fk": {
|
||||
"name": "experiment_dataset_id_dataset_id_fk",
|
||||
"tableFrom": "experiment",
|
||||
"tableTo": "dataset",
|
||||
"columnsFrom": [
|
||||
"dataset_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"participant": {
|
||||
"name": "participant",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"experiment_id": {
|
||||
"name": "experiment_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"calibration_answers": {
|
||||
"name": "calibration_answers",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"onboarding_answers": {
|
||||
"name": "onboarding_answers",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(unixepoch())"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"unique_participant": {
|
||||
"name": "unique_participant",
|
||||
"columns": [
|
||||
"experiment_id",
|
||||
"user_id"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"participant_experiment_id_experiment_id_fk": {
|
||||
"name": "participant_experiment_id_experiment_id_fk",
|
||||
"tableFrom": "participant",
|
||||
"tableTo": "experiment",
|
||||
"columnsFrom": [
|
||||
"experiment_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,13 @@
|
||||
"when": 1775796301988,
|
||||
"tag": "0013_mute_black_widow",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "6",
|
||||
"when": 1775807031115,
|
||||
"tag": "0014_groovy_patriot",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -156,6 +156,7 @@ export async function getAnnotationEntries(experimentId: number): Promise<Datase
|
||||
experimentId: experimentId,
|
||||
datasetId: e.datasetId,
|
||||
annotation: annotationEntries.find((a) => a.datasetEntryId === e.id)?.rating || null,
|
||||
confidence: annotationEntries.find((a) => a.datasetEntryId === e.id)?.confidence || null,
|
||||
utteranceText: e.utteranceText,
|
||||
}));
|
||||
|
||||
@@ -167,7 +168,7 @@ export async function getAnnotationEntries(experimentId: number): Promise<Datase
|
||||
* Updates existing annotations with the same userId, experimentId, and datasetEntryId.
|
||||
*/
|
||||
export async function saveAnnotations(
|
||||
ratings: { entryId: number; rating: number; dialectLabel: string }[],
|
||||
ratings: { entryId: number; rating: number; dialectLabel: string; confidence: number }[],
|
||||
experimentId: number
|
||||
): Promise<void> {
|
||||
const session = await auth.api.getSession({ headers: await headers() });
|
||||
@@ -175,15 +176,16 @@ export async function saveAnnotations(
|
||||
|
||||
if (ratings.length === 0) return;
|
||||
|
||||
for (const { entryId, rating, dialectLabel } of ratings) {
|
||||
for (const { entryId, rating, dialectLabel, confidence } of ratings) {
|
||||
await db
|
||||
.insert(annotation)
|
||||
.values({experimentId, datasetEntryId: entryId, userId: session.user.id, rating, dialectLabel })
|
||||
.values({experimentId, datasetEntryId: entryId, userId: session.user.id, rating, dialectLabel, confidence })
|
||||
.onConflictDoUpdate({
|
||||
target: [annotation.userId, annotation.experimentId, annotation.datasetEntryId],
|
||||
set: {
|
||||
rating,
|
||||
dialectLabel,
|
||||
confidence
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ import CalibrationScoresModal from '@/components/CalibrationScoresModal';
|
||||
export interface EntryViewProps {
|
||||
entry: DatasetEntryForAnnotation;
|
||||
index: number;
|
||||
onSave: (rating: number) => Promise<void>;
|
||||
onSave: (rating: number, confidence: number) => Promise<void>;
|
||||
isSaving: boolean;
|
||||
ratingOptions?: { value: number; label: JSX.Element | string }[];
|
||||
confidenceOptions?: { value: number; label: JSX.Element | string }[];
|
||||
question?: JSX.Element | string;
|
||||
}
|
||||
|
||||
@@ -68,6 +69,12 @@ export default function AnnotationPageView({
|
||||
{ value: 4, label: `Klingt eindeutig nach ${DIALECT_LABELS[dialectLabel]}` },
|
||||
],
|
||||
question: <div>Wie authentisch klingt diese Aufnahme nach dem Dialekt der Region <span className="text-blue-600">{DIALECT_LABELS[dialectLabel]}</span>?</div>,
|
||||
confidenceOptions: [
|
||||
{ value: 1, label: 'Sehr unsicher' },
|
||||
{ value: 2, label: 'Eher unsicher' },
|
||||
{ value: 3, label: 'Eher sicher' },
|
||||
{ value: 4, label: 'Sehr sicher' },
|
||||
]
|
||||
};
|
||||
case 'binary':
|
||||
return {
|
||||
@@ -99,6 +106,7 @@ export default function AnnotationPageView({
|
||||
isSaving={isPending}
|
||||
ratingOptions={config.ratingOptions}
|
||||
question={config.question}
|
||||
confidenceOptions={config.confidenceOptions}
|
||||
/>
|
||||
);
|
||||
case 'binary':
|
||||
@@ -147,12 +155,16 @@ export default function AnnotationPageView({
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveEntry = async (rating: number) => {
|
||||
const handleSaveEntry = async (rating: number, confidence: number) => {
|
||||
startTransition(async () => {
|
||||
const batch = [{ entryId: currentEntry!.id, rating, dialectLabel: currentEntry!.dialect }];
|
||||
const batch = [{ entryId: currentEntry!.id, rating, dialectLabel: currentEntry!.dialect, confidence }]; // Using max confidence for now, can be changed to user input if needed
|
||||
await saveAnnotations(batch, experimentId);
|
||||
const isNewAnnotation = entries[currentIndex].annotation === null && entries[currentIndex].confidence === null; // Check if this is the first time annotating this entry
|
||||
entries[currentIndex].annotation = rating; // Update local state optimistically
|
||||
handleNext();
|
||||
entries[currentIndex].confidence = confidence; // Update confidence in local state
|
||||
if (isNewAnnotation) {
|
||||
handleNext();
|
||||
}
|
||||
});
|
||||
};
|
||||
// Calculate progress: count already-annotated entries
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function SingleChoiceBinaryEntryView({
|
||||
if (answer === entry.annotation) return; // No change, don't save
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
onSave(answer);
|
||||
onSave(answer, -1); // Using max confidence for now, can be changed to user input if needed
|
||||
}, AUTO_ADVANCE_DELAY_MS);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
|
||||
@@ -7,42 +7,47 @@ import { type EntryViewProps } from './AnnotationPageView';
|
||||
|
||||
const AUTO_ADVANCE_DELAY_MS = 600;
|
||||
|
||||
|
||||
|
||||
export default function SingleChoiceEntryView({
|
||||
entry,
|
||||
index,
|
||||
onSave,
|
||||
isSaving,
|
||||
ratingOptions,
|
||||
confidenceOptions,
|
||||
question,
|
||||
}: EntryViewProps) {
|
||||
const [answer, setAnswer] = useState<number | null>(null);
|
||||
const [answerRating, setAnswerRating] = useState<number | null>(null);
|
||||
const [answerConfidence, setAnswerConfidence] = useState<number | null>(null);
|
||||
const [fullyPlayed, setFullyPlayed] = useState<boolean>(false);
|
||||
|
||||
const fileExt = entry.fileName.substring(entry.fileName.lastIndexOf('.'));
|
||||
const audioSrc = `/public/datasets/${entry.datasetId}/${entry.externalId}${fileExt}`;
|
||||
|
||||
// Auto-save when answer is selected
|
||||
// Auto-save when both answer and confidence are selected
|
||||
useEffect(() => {
|
||||
if (answer === null || isSaving) return;
|
||||
if (answer === entry.annotation) return; // No change, don't save
|
||||
if (answerRating === null || answerConfidence === null || isSaving) return;
|
||||
if (answerRating === entry.annotation && answerConfidence === entry.confidence) return; // No change, don't save
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
onSave(answer);
|
||||
onSave(answerRating, answerConfidence);
|
||||
}, AUTO_ADVANCE_DELAY_MS);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [answer, onSave, entry.annotation, isSaving]);
|
||||
}, [answerRating, answerConfidence, onSave, entry.annotation, entry.confidence, isSaving]);
|
||||
|
||||
useEffect(() => {
|
||||
// Reset state when entry changes
|
||||
setAnswer(entry.annotation);
|
||||
setFullyPlayed(entry.annotation !== null); // If already annotated, mark as fully played to allow changing answer
|
||||
setAnswerRating(entry.annotation);
|
||||
setAnswerConfidence(entry.confidence);
|
||||
setFullyPlayed(entry.annotation !== null && entry.confidence !== null); // If already annotated, mark as fully played to allow changing answer
|
||||
}, [entry]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`border rounded-xl p-5 bg-white shadow-sm transition-colors duration-300 mt-4 ${
|
||||
fullyPlayed && answer !== null ? 'border-green-300' : 'border-gray-200'
|
||||
fullyPlayed && answerRating !== null && answerConfidence !== null ? 'border-green-300' : 'border-gray-200'
|
||||
}`}
|
||||
>
|
||||
{/* Sample header */}
|
||||
@@ -79,44 +84,83 @@ export default function SingleChoiceEntryView({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Dialect + question */}
|
||||
<div className="mt-4 mb-3">
|
||||
<div className="text-s font-semibold text-gray-700">
|
||||
{question}
|
||||
{/* Questions container */}
|
||||
<div className="mt-6 flex flex-col lg:flex-row gap-6">
|
||||
{/* Rating question */}
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-semibold text-gray-700 mb-3">
|
||||
{question}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
{ratingOptions?.map(({ value, label }) => {
|
||||
const selected = answerRating === value;
|
||||
const disabled = !fullyPlayed || isSaving;
|
||||
return (
|
||||
<button
|
||||
key={value}
|
||||
disabled={disabled}
|
||||
onClick={() => setAnswerRating(value)}
|
||||
className={`flex items-center gap-3 w-full text-left px-4 py-2.5 rounded-lg border text-sm transition-colors ${
|
||||
disabled
|
||||
? 'opacity-40 cursor-not-allowed border-gray-200 bg-gray-50 text-gray-500'
|
||||
: selected
|
||||
? 'border-blue-500 bg-blue-50 text-blue-800 font-medium'
|
||||
: 'border-gray-200 hover:border-blue-300 hover:bg-blue-50 text-gray-700'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`flex-shrink-0 w-6 h-6 rounded-full border-2 flex items-center justify-center text-xs font-bold ${
|
||||
selected
|
||||
? 'border-blue-500 bg-blue-500 text-white'
|
||||
: 'border-gray-300 text-gray-400'
|
||||
}`}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Rating buttons */}
|
||||
<div className="flex flex-col gap-2">
|
||||
{ratingOptions?.map(({ value, label }) => {
|
||||
const selected = answer === value;
|
||||
const disabled = !fullyPlayed || isSaving;
|
||||
return (
|
||||
<button
|
||||
key={value}
|
||||
disabled={disabled}
|
||||
onClick={() => setAnswer(value)}
|
||||
className={`flex items-center gap-3 w-full text-left px-4 py-2.5 rounded-lg border text-sm transition-colors ${
|
||||
disabled
|
||||
? 'opacity-40 cursor-not-allowed border-gray-200 bg-gray-50 text-gray-500'
|
||||
: selected
|
||||
? 'border-blue-500 bg-blue-50 text-blue-800 font-medium'
|
||||
: 'border-gray-200 hover:border-blue-300 hover:bg-blue-50 text-gray-700'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`flex-shrink-0 w-6 h-6 rounded-full border-2 flex items-center justify-center text-xs font-bold ${
|
||||
selected
|
||||
? 'border-blue-500 bg-blue-500 text-white'
|
||||
: 'border-gray-300 text-gray-400'
|
||||
}`}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
{/* Confidence question */}
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-semibold text-gray-700 mb-3">
|
||||
Wie sicher bist du?
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
{confidenceOptions?.map(({ value, label }) => {
|
||||
const selected = answerConfidence === value;
|
||||
const disabled = !fullyPlayed || isSaving;
|
||||
return (
|
||||
<button
|
||||
key={value}
|
||||
disabled={disabled}
|
||||
onClick={() => setAnswerConfidence(value)}
|
||||
className={`flex items-center gap-3 w-full text-left px-4 py-2.5 rounded-lg border text-sm transition-colors ${
|
||||
disabled
|
||||
? 'opacity-40 cursor-not-allowed border-gray-200 bg-gray-50 text-gray-500'
|
||||
: selected
|
||||
? 'border-blue-500 bg-blue-50 text-blue-800 font-medium'
|
||||
: 'border-gray-200 hover:border-blue-300 hover:bg-blue-50 text-gray-700'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`flex-shrink-0 w-6 h-6 rounded-full border-2 flex items-center justify-center text-xs font-bold ${
|
||||
selected
|
||||
? 'border-blue-500 bg-blue-500 text-white'
|
||||
: 'border-gray-300 text-gray-400'
|
||||
}`}
|
||||
>
|
||||
{selected ? '✓' : ''}
|
||||
</span>
|
||||
<span>{label}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footnote */}
|
||||
|
||||
@@ -28,5 +28,6 @@ export type DatasetEntryForAnnotation = {
|
||||
datasetId: number;
|
||||
experimentId: number;
|
||||
annotation: number | null;
|
||||
confidence: number | null;
|
||||
utteranceText: string | null;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,8 @@ export const annotation = sqliteTable(
|
||||
experimentId: integer('experiment_id')
|
||||
.references(() => experiment.id),
|
||||
userId: text('user_id').notNull(),
|
||||
rating: integer('rating').notNull(), // 1–5
|
||||
rating: integer('rating').notNull(), // 1–4
|
||||
confidence: integer('confidence').notNull(), // 1-4
|
||||
dialectLabel: text('dialect_label').notNull(), // e.g. 'ch_be', 'ch_zh', …
|
||||
createdAt: integer('created_at', { mode: 'timestamp' })
|
||||
.notNull()
|
||||
|
||||
Reference in New Issue
Block a user