Skip to content

Commit e5a888f

Browse files
committed
✨ Add is_completed column to histories
1 parent ec9ec78 commit e5a888f

7 files changed

Lines changed: 74 additions & 12 deletions

File tree

entity/src/entities/histories.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub struct Model {
1818
pub submit_history: Option<SubmitHistory>,
1919
pub original_solution: PuzzleSolution,
2020
pub is_dirty: bool,
21+
pub is_completed: bool,
2122
pub uploaded_at: DateTime,
2223
}
2324

entity/src/types/submit_word.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ impl<const N: usize> SubmitWord<N> {
7272
false
7373
}
7474

75+
pub fn all_matches(&self) -> bool {
76+
self.0.iter().all(|l| l.matches == Matches::Yes)
77+
}
78+
7579
pub fn to_vec(&self) -> Vec<&SubmitLetter> {
7680
self.0.iter().collect()
7781
}

migration/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
pub use sea_orm_migration::prelude::*;
22

33
mod m20220101_000001_create_table;
4+
mod m20250817_081620_alter_table;
45

56
pub struct Migrator;
67

78
#[async_trait::async_trait]
89
impl MigratorTrait for Migrator {
910
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
10-
vec![Box::new(m20220101_000001_create_table::Migration)]
11+
vec![
12+
Box::new(m20220101_000001_create_table::Migration),
13+
Box::new(m20250817_081620_alter_table::Migration),
14+
]
1115
}
1216
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use sea_orm_migration::{prelude::*, schema::*};
2+
3+
#[derive(DeriveMigrationName)]
4+
pub struct Migration;
5+
6+
#[async_trait::async_trait]
7+
impl MigrationTrait for Migration {
8+
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
9+
manager
10+
.alter_table(
11+
Table::alter()
12+
.table(Histories::Table)
13+
.add_column_if_not_exists(boolean(Histories::IsCompleted).default(false))
14+
.to_owned(),
15+
)
16+
.await
17+
}
18+
19+
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
20+
manager
21+
.alter_table(
22+
Table::alter()
23+
.table(Histories::Table)
24+
.drop_column(Histories::IsCompleted)
25+
.to_owned(),
26+
)
27+
.await
28+
}
29+
}
30+
31+
#[derive(DeriveIden)]
32+
enum Histories {
33+
Table,
34+
IsCompleted,
35+
}

src/database/tables/histories.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use sea_orm::{
1111
ActiveValue, ColumnTrait, Condition, DatabaseConnection, DbErr, EntityTrait, IntoActiveModel,
1212
QueryFilter, QuerySelect,
1313
};
14-
use tracing::{error, info, trace, warn};
14+
use tracing::{error, info, warn};
1515

1616
pub async fn get_history(
1717
db: &DatabaseConnection,
@@ -64,9 +64,9 @@ pub async fn create_history(
6464

6565
#[derive(Debug, Clone)]
6666
pub struct SubmitResult {
67-
pub remaining_tries: usize,
68-
pub is_dirty: bool,
6967
pub submit_history: SubmitHistory,
68+
pub is_dirty: bool,
69+
pub is_completed: bool,
7070
}
7171

7272
pub async fn submit_to_history(
@@ -83,15 +83,24 @@ pub async fn submit_to_history(
8383
.columns([
8484
histories::Column::SubmitHistory,
8585
histories::Column::IsDirty,
86+
histories::Column::IsCompleted,
8687
histories::Column::OriginalSolution,
8788
])
88-
.into_tuple::<(Option<SubmitHistory>, bool, PuzzleSolution)>()
89+
.into_tuple::<(Option<SubmitHistory>, bool, bool, PuzzleSolution)>()
8990
.one(db)
9091
.await
9192
.ok()
9293
.flatten()
9394
{
94-
Some((submit_history, is_dirty, solution)) => {
95+
Some((submit_history, is_dirty, true, _)) => {
96+
warn!("history is completed for {date} with session {session}!");
97+
return Ok(SubmitResult {
98+
submit_history: submit_history.unwrap_or_default(),
99+
is_dirty,
100+
is_completed: true,
101+
});
102+
}
103+
Some((submit_history, is_dirty, false, solution)) => {
95104
(submit_history.unwrap_or_default(), is_dirty, solution)
96105
}
97106
None => {
@@ -100,8 +109,9 @@ pub async fn submit_to_history(
100109
}
101110
};
102111

112+
let word = SubmitWord::tint(answer, &solution);
103113
submit_history
104-
.submit(SubmitWord::tint(answer, &solution))
114+
.submit(word)
105115
.map_err(|e| DbErr::Custom(e.to_string()))?;
106116

107117
let active_history = histories::ActiveModel {
@@ -110,14 +120,17 @@ pub async fn submit_to_history(
110120
submit_history: ActiveValue::Set(Some(submit_history.clone())),
111121
original_solution: ActiveValue::Unchanged(solution),
112122
is_dirty: ActiveValue::Unchanged(false),
123+
is_completed: ActiveValue::Set(word.all_matches()),
113124
uploaded_at: ActiveValue::Unchanged(Utc::now().naive_utc()),
114-
..Default::default()
115125
};
116126

117127
match Histories::insert(active_history)
118128
.on_conflict(
119129
OnConflict::columns([histories::Column::Date, histories::Column::Session])
120-
.update_column(histories::Column::SubmitHistory)
130+
.update_columns([
131+
histories::Column::SubmitHistory,
132+
histories::Column::IsCompleted,
133+
])
121134
.to_owned(),
122135
)
123136
.exec(db)
@@ -126,9 +139,9 @@ pub async fn submit_to_history(
126139
Ok(_) => {
127140
info!("submitted {answer} to history at {date} with session {session}");
128141
Ok(SubmitResult {
129-
remaining_tries: submit_history.remaining_tries(),
130-
is_dirty,
131142
submit_history,
143+
is_dirty,
144+
is_completed: word.all_matches(),
132145
})
133146
}
134147
Err(err) => {

src/endpoint/play/start/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub struct GetParams {
2828
pub struct GetResponse {
2929
remaining_tries: usize,
3030
is_dirty: bool,
31+
is_completed: bool,
3132
history: Vec<SubmitWord>,
3233
}
3334

@@ -58,6 +59,7 @@ pub async fn get(
5859
Json(GetResponse {
5960
remaining_tries: history.remaining_tries(),
6061
is_dirty: history.is_dirty,
62+
is_completed: history.is_completed,
6163
history: history
6264
.submit_history
6365
.map(SubmitHistory::into_vec)
@@ -94,6 +96,7 @@ pub async fn get(
9496
Json(GetResponse {
9597
remaining_tries: HISTORY_MAX_TRIES,
9698
is_dirty: false,
99+
is_completed: false,
97100
..Default::default()
98101
}),
99102
)

src/endpoint/play/submit/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub struct PostPayload {
2424
pub struct PostResponse {
2525
remaining_tries: usize,
2626
is_dirty: bool,
27+
is_completed: bool,
2728
history: Vec<SubmitWord>,
2829
}
2930

@@ -51,8 +52,9 @@ pub async fn post(
5152
Ok(result) => (
5253
StatusCode::ACCEPTED,
5354
Json(PostResponse {
54-
remaining_tries: result.remaining_tries,
55+
remaining_tries: result.submit_history.remaining_tries(),
5556
is_dirty: result.is_dirty,
57+
is_completed: result.is_completed,
5658
history: result.submit_history.into_vec(),
5759
}),
5860
)

0 commit comments

Comments
 (0)