feat: Add seed_test_data script to populate initial test data for events, testimonials, hackathons, and mentors
This commit is contained in:
@@ -27,6 +27,17 @@ impl<'a> HackathonRepository<'a> {
|
||||
pub fn new(state: &'a AppState) -> Self {
|
||||
Self { state }
|
||||
}
|
||||
|
||||
// Normalize an incoming id so callers can pass either the full thing string
|
||||
// (e.g. "app_hackathons:1") or the raw id ("1"). If the id starts with
|
||||
// the table prefix ("{table}:") the prefix is stripped.
|
||||
fn normalize_id(&self, table: &str, id: &str) -> String {
|
||||
if id.starts_with(&format!("{}:", table)) {
|
||||
id.splitn(2, ':').nth(1).unwrap_or(id).to_string()
|
||||
} else {
|
||||
id.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hackathon CRUD operations
|
||||
@@ -94,10 +105,12 @@ impl<'a> HackathonRepository<'a> {
|
||||
let table = ResourceEnum::Hackathons.to_string();
|
||||
info!(query = %format!("SELECT * FROM {} WHERE id = '{}'", table, id), "Executing SurrealDB query");
|
||||
|
||||
let normalized_id = self.normalize_id(&table, &id);
|
||||
|
||||
let record: Option<HackathonSchema> = self
|
||||
.state
|
||||
.surrealdb_ws
|
||||
.select((table, id))
|
||||
.select((table, normalized_id.clone()))
|
||||
.await?;
|
||||
|
||||
match record {
|
||||
@@ -210,9 +223,11 @@ impl<'a> HackathonRepository<'a> {
|
||||
]);
|
||||
|
||||
info!(query = %format!("UPDATE {} SET is_deleted = true WHERE id = '{}'", table, id), "Executing SurrealDB query");
|
||||
let normalized_id = self.normalize_id(&table, &id);
|
||||
info!(query = %format!("UPDATE {} SET is_deleted = true WHERE id = '{}'", table, normalized_id), "Executing SurrealDB query");
|
||||
let record: Option<HackathonSchema> = self
|
||||
.state.surrealdb_ws
|
||||
.update((table, id))
|
||||
.update((table, normalized_id.clone()))
|
||||
.merge(serde_json::to_value(updates)?)
|
||||
.await?;
|
||||
|
||||
@@ -230,9 +245,11 @@ impl<'a> HackathonRepository<'a> {
|
||||
let table = ResourceEnum::HackathonEvents.to_string();
|
||||
let id = surrealdb::Uuid::new_v4().to_string();
|
||||
|
||||
let normalized_hackathon_id = self.normalize_id("app_hackathons", &hackathon_id);
|
||||
|
||||
let schema = HackathonEventsSchema {
|
||||
id: Thing::from((table.clone(), id.clone())),
|
||||
hackathon_id: Thing::from(("app_hackathons".to_string(), hackathon_id)),
|
||||
hackathon_id: Thing::from(("app_hackathons".to_string(), normalized_hackathon_id)),
|
||||
title: event.title,
|
||||
description: event.description,
|
||||
event_type: event.event_type,
|
||||
@@ -264,9 +281,11 @@ impl<'a> HackathonRepository<'a> {
|
||||
pub async fn list_hackathon_events(&self, meta: imphnen_libs::MetaRequestDto, hackathon_id: String) -> Result<imphnen_libs::ResponseListSuccessDto<Vec<HackathonEventsSchema>>> {
|
||||
let table = ResourceEnum::HackathonEvents.to_string();
|
||||
|
||||
let normalized_hackathon_id = self.normalize_id("app_hackathons", &hackathon_id);
|
||||
|
||||
let builder = QueryListBuilder::new(&self.state.surrealdb_ws, &table, &meta)
|
||||
.with_condition("is_deleted = false")
|
||||
.with_condition(&format!("hackathon_id = type::thing('app_hackathons', '{}')", hackathon_id))
|
||||
.with_condition(&format!("hackathon_id = type::thing('app_hackathons', '{}')", normalized_hackathon_id))
|
||||
.search_field("title")
|
||||
.select_fields(vec!["*"]);
|
||||
|
||||
@@ -360,9 +379,11 @@ impl<'a> HackathonRepository<'a> {
|
||||
let table = ResourceEnum::HackathonTimeline.to_string();
|
||||
let id = surrealdb::Uuid::new_v4().to_string();
|
||||
|
||||
let normalized_hackathon_id = self.normalize_id("app_hackathons", &hackathon_id);
|
||||
|
||||
let schema = HackathonTimelineSchema {
|
||||
id: Thing::from((table.clone(), id.clone())),
|
||||
hackathon_id: Thing::from(("app_hackathons".to_string(), hackathon_id)),
|
||||
hackathon_id: Thing::from(("app_hackathons".to_string(), normalized_hackathon_id)),
|
||||
phase: timeline.phase,
|
||||
title: timeline.title,
|
||||
description: timeline.description,
|
||||
@@ -392,9 +413,11 @@ impl<'a> HackathonRepository<'a> {
|
||||
pub async fn list_hackathon_timeline(&self, meta: imphnen_libs::MetaRequestDto, hackathon_id: String) -> Result<imphnen_libs::ResponseListSuccessDto<Vec<HackathonTimelineSchema>>> {
|
||||
let table = ResourceEnum::HackathonTimeline.to_string();
|
||||
|
||||
let normalized_hackathon_id = self.normalize_id("app_hackathons", &hackathon_id);
|
||||
|
||||
let builder = QueryListBuilder::new(&self.state.surrealdb_ws, &table, &meta)
|
||||
.with_condition("is_deleted = false")
|
||||
.with_condition(&format!("hackathon_id = type::thing('app_hackathons', '{}')", hackathon_id))
|
||||
.with_condition(&format!("hackathon_id = type::thing('app_hackathons', '{}')", normalized_hackathon_id))
|
||||
.search_field("title")
|
||||
.select_fields(vec!["*"]);
|
||||
|
||||
@@ -481,10 +504,13 @@ impl<'a> HackathonRepository<'a> {
|
||||
let table = ResourceEnum::HackathonSubmissions.to_string();
|
||||
let id = surrealdb::Uuid::new_v4().to_string();
|
||||
|
||||
let normalized_hackathon_id = self.normalize_id("app_hackathons", &hackathon_id);
|
||||
let normalized_team_id = self.normalize_id("app_teams", &team_id);
|
||||
|
||||
let schema = HackathonSubmissionsSchema {
|
||||
id: Thing::from((table.clone(), id.clone())),
|
||||
hackathon_id: Thing::from(("app_hackathons".to_string(), hackathon_id)),
|
||||
team_id: Thing::from(("app_teams".to_string(), team_id)),
|
||||
hackathon_id: Thing::from(("app_hackathons".to_string(), normalized_hackathon_id)),
|
||||
team_id: Thing::from(("app_teams".to_string(), normalized_team_id)),
|
||||
project_name: submission.project_name,
|
||||
description: submission.description,
|
||||
repository_url: submission.repository_url,
|
||||
@@ -515,9 +541,11 @@ impl<'a> HackathonRepository<'a> {
|
||||
pub async fn list_hackathon_submissions(&self, meta: imphnen_libs::MetaRequestDto, hackathon_id: String) -> Result<imphnen_libs::ResponseListSuccessDto<Vec<HackathonSubmissionsSchema>>> {
|
||||
let table = ResourceEnum::HackathonSubmissions.to_string();
|
||||
|
||||
let normalized_hackathon_id = self.normalize_id("app_hackathons", &hackathon_id);
|
||||
|
||||
let builder = QueryListBuilder::new(&self.state.surrealdb_ws, &table, &meta)
|
||||
.with_condition("is_deleted = false")
|
||||
.with_condition(&format!("hackathon_id = type::thing('app_hackathons', '{}')", hackathon_id))
|
||||
.with_condition(&format!("hackathon_id = type::thing('app_hackathons', '{}')", normalized_hackathon_id))
|
||||
.search_field("project_name")
|
||||
.select_fields(vec!["*"]);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize, Deserializer};
|
||||
use std::str::FromStr;
|
||||
use serde::de;
|
||||
use surrealdb::sql::Thing;
|
||||
|
||||
use imphnen_utils::make_thing;
|
||||
@@ -104,7 +106,38 @@ pub enum HackathonStatus {
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, utoipa::ToSchema, strum::Display)]
|
||||
#[derive(Clone, Debug, Serialize, PartialEq, utoipa::ToSchema, strum::Display)]
|
||||
pub enum HackathonPhase {
|
||||
Registration,
|
||||
Ideation,
|
||||
Development,
|
||||
Submission,
|
||||
Judging,
|
||||
Awards,
|
||||
}
|
||||
|
||||
// Manual Deserialize implementation for case-insensitive support
|
||||
impl<'de> Deserialize<'de> for HackathonPhase {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
let normalized = s.to_lowercase();
|
||||
|
||||
match normalized.as_str() {
|
||||
"registration" => Ok(HackathonPhase::Registration),
|
||||
"ideation" => Ok(HackathonPhase::Ideation),
|
||||
"development" => Ok(HackathonPhase::Development),
|
||||
"submission" => Ok(HackathonPhase::Submission),
|
||||
"judging" => Ok(HackathonPhase::Judging),
|
||||
"awards" => Ok(HackathonPhase::Awards),
|
||||
_ => Err(serde::de::Error::custom(format!("Invalid HackathonPhase: {}", s)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, PartialEq, utoipa::ToSchema, strum::Display)]
|
||||
pub enum HackathonEventType {
|
||||
Workshop,
|
||||
Keynote,
|
||||
@@ -114,14 +147,31 @@ pub enum HackathonEventType {
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, utoipa::ToSchema, strum::Display)]
|
||||
pub enum HackathonPhase {
|
||||
Registration,
|
||||
Ideation,
|
||||
Development,
|
||||
Submission,
|
||||
Judging,
|
||||
Awards,
|
||||
// Implement case-insensitive string parsing for HackathonEventType
|
||||
impl FromStr for HackathonEventType {
|
||||
type Err = String;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"workshop" => Ok(Self::Workshop),
|
||||
"keynote" => Ok(Self::Keynote),
|
||||
"networking" => Ok(Self::Networking),
|
||||
"judging" => Ok(Self::Judging),
|
||||
"ceremony" => Ok(Self::Ceremony),
|
||||
"other" => Ok(Self::Other),
|
||||
_ => Err(format!("Invalid HackathonEventType: {}", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Manual Deserialize implementation for case-insensitive support
|
||||
impl<'de> Deserialize<'de> for HackathonEventType {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Self::from_str(&s).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, utoipa::ToSchema, strum::Display)]
|
||||
|
||||
Reference in New Issue
Block a user