Skip to content

Commit 862f47f

Browse files
authored
Merge pull request #184 from MathisBurger/fix/bugs
2 parents 3aa1227 + e932757 commit 862f47f

File tree

16 files changed

+264
-121
lines changed

16 files changed

+264
-121
lines changed

docker-compose.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
services:
22
postgres:
33
image: postgres:latest
4-
ports:
4+
ports:
55
- "5434:5432"
66
volumes:
77
- db_data:/var/lib/postgresql/data
@@ -10,7 +10,7 @@ services:
1010
- POSTGRES_USER=admin
1111
mongodb:
1212
image: mongodb/mongodb-community-server:latest
13-
ports:
13+
ports:
1414
- "27017:27017"
1515
environment:
1616
- MONGO_INITDB_ROOT_USERNAME=admin
@@ -22,7 +22,7 @@ services:
2222
- "1025:1025"
2323
usernator:
2424
build: ./usernator
25-
ports:
25+
ports:
2626
- "3001:3000"
2727
- "3004:3001"
2828
environment:
@@ -45,7 +45,7 @@ services:
4545
context: ./authy
4646
args:
4747
- ARCH=aarch64
48-
ports:
48+
ports:
4949
- "3002:3000"
5050
environment:
5151
- JWT_SECRET=secret
@@ -59,7 +59,7 @@ services:
5959
context: ./tasky
6060
args:
6161
- ARCH=aarch64
62-
ports:
62+
ports:
6363
- "3005:3000"
6464
- "3006:3001"
6565
environment:
@@ -104,4 +104,4 @@ services:
104104
depends_on:
105105
- executor
106106
volumes:
107-
db_data:
107+
db_data:

executor/go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module executor
22

3-
go 1.22
4-
toolchain go1.23.7
3+
go 1.23.0
4+
5+
toolchain go1.23.9
56

67
require (
78
github.com/knadh/koanf/maps v0.1.1

tasky/src/handler/solution.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,11 @@ fn handle_questions(
188188
}
189189
}
190190
solution.question_result = serde_json::to_value(result).ok();
191-
solution.approval_status = Some(
192-
all_correct
193-
.then(|| ApprovalStatus::Successful.string())
194-
.unwrap_or(ApprovalStatus::Failed.string()),
195-
);
191+
solution.approval_status = Some(if all_correct {
192+
ApprovalStatus::Successful.string()
193+
} else {
194+
ApprovalStatus::Failed.string()
195+
});
196196
Ok(())
197197
}
198198

tasky/src/models/assignment.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::notification::NotificationRepository;
22
use super::{Paginate, PaginatedModel, DB};
33
use crate::schema::assignments::dsl;
4-
use crate::schema::{self, group_members};
4+
use crate::schema::{group_members, groups, solutions};
55
use chrono::NaiveDateTime;
66
use diesel::associations::HasTable;
77
use diesel::dsl::not;
@@ -164,21 +164,22 @@ impl AssignmentRepository {
164164
conn: &mut DB,
165165
) -> PaginatedModel<Assignment> {
166166
dsl::assignments
167-
.left_join(crate::schema::groups::table)
168-
.left_join(crate::schema::solutions::table)
169-
.left_join(
170-
schema::group_members::table.on(schema::groups::id.eq(group_members::group_id)),
171-
)
167+
.inner_join(groups::table.on(dsl::group_id.eq(groups::dsl::id)))
168+
.inner_join(group_members::table.on(groups::id.eq(group_members::group_id)))
172169
.filter(group_members::dsl::member_id.eq(student_id))
173-
.filter(not(crate::schema::solutions::dsl::submitter_id
174-
.eq(student_id)
175-
.and(
176-
crate::schema::solutions::dsl::approval_status.eq("APPROVED"),
177-
)))
170+
.filter(not(dsl::id.eq_any(
171+
solutions::dsl::solutions
172+
.filter(
173+
solutions::submitter_id
174+
.eq(student_id)
175+
.and(solutions::approval_status.eq("APPROVED")),
176+
)
177+
.select(solutions::assignment_id),
178+
)))
178179
.select(Assignment::as_select())
179180
.group_by(dsl::id)
180181
.paginate(page)
181182
.load_and_count_pages::<Assignment>(conn)
182-
.expect("Cannot fetch pending assignments for student")
183+
.expect("Cannot loading pending assignments")
183184
}
184185
}

tasky/src/models/group.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ use super::{PaginatedModel, DB};
44
use crate::schema::group_members;
55
use crate::schema::groups::dsl;
66
use chrono::NaiveDateTime;
7+
use diesel::debug_query;
78
use diesel::dsl::count_star;
9+
use diesel::pg::Pg;
810
use diesel::prelude::*;
911
use diesel::{associations::HasTable, dsl::not};
12+
use log::info;
1013
use serde::{Deserialize, Serialize};
1114

1215
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, Deserialize, Serialize, PartialEq)]
@@ -127,7 +130,7 @@ impl GroupRepository {
127130
}
128131
}
129132

130-
/// Gets all groups a user is member or tutor of
133+
/// Gets all groups a user is no member or tutor of
131134
pub fn get_groups_for_not_member(
132135
member_id: i32,
133136
page: i64,
@@ -139,17 +142,21 @@ impl GroupRepository {
139142
.map(|x| x.group_id)
140143
.collect();
141144

142-
let base_predicate = not(dsl::tutor
143-
.eq(member_id)
144-
.or(dsl::id.eq_any(requested))
145-
.or(group_members::dsl::member_id.eq(member_id)));
145+
let base_predicate = not(dsl::tutor.eq(member_id).or(dsl::id.eq_any(requested)).or(
146+
group_members::dsl::member_id
147+
.eq(member_id)
148+
.and(group_members::dsl::group_id.is_not_null()),
149+
));
146150

147151
let total_base_query = dsl::groups
148152
.left_join(group_members::dsl::group_members)
149153
.select(count_star())
150154
.filter(base_predicate.clone())
151155
.into_boxed();
152156

157+
let sql_string = debug_query::<Pg, _>(&total_base_query).to_string();
158+
println!("{}", sql_string);
159+
153160
let total = match search.clone() {
154161
None => total_base_query
155162
.get_result::<i64>(conn)
@@ -177,7 +184,8 @@ impl GroupRepository {
177184
.load::<Group>(conn),
178185
};
179186

180-
if results.is_err() {
187+
if let Err(e) = results {
188+
info!("Error from database: {}", e);
181189
return PaginatedModel {
182190
total: 0,
183191
results: vec![],

tasky/src/models/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,17 @@ impl<T> Paginated<T> {
7373
.query
7474
.clone()
7575
.select(count_star())
76-
.get_result::<i64>(conn)?;
76+
.get_result::<i64>(conn)
77+
.optional()?
78+
.unwrap_or(0);
79+
80+
if total == 0 {
81+
return Ok(PaginatedModel {
82+
results: vec![],
83+
page: self.page,
84+
total,
85+
});
86+
}
7787

7888
let results = self
7989
.query

tasky/src/models/notification.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ impl NotificationRepository {
102102
.left_join(notification_targets::table)
103103
.filter(notification_targets::user_id.eq(user_id))
104104
.select(Notification::as_select())
105+
.order(dsl::created_at.desc())
105106
.get_results::<Notification>(conn)
106107
.expect("Cannot get notifications for user")
107108
}

tasky/src/routes/group.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,13 @@ pub async fn get_enlistable_users(
218218
.into_iter()
219219
.map(|x| x.into())
220220
.collect();
221+
println!("{:?}", users);
221222
let response_uids: Vec<i32> = users.iter().map(|u| i32::try_from(u.id).unwrap()).collect();
222223
let enlisted_uids =
223224
GroupMemberRepository::get_enlisted_from_selection(group.id, response_uids, conn);
224225
let filtered_users: Vec<&User> = users
225226
.iter()
226-
.filter(|u| enlisted_uids.contains(&i32::try_from(u.id).unwrap()))
227+
.filter(|u| !enlisted_uids.contains(&i32::try_from(u.id).unwrap()))
227228
.collect();
228229
Ok(HttpResponse::Ok().json(filtered_users))
229230
}
@@ -292,7 +293,7 @@ pub async fn remove_user(
292293
});
293294
}
294295

295-
GroupMemberRepository::remove_membership(group.id, user.user_id, conn);
296+
GroupMemberRepository::remove_membership(group.id, path_data.1, conn);
296297
Ok(HttpResponse::Ok().finish())
297298
}
298299

tasky/src/routes/notifications.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,18 @@ pub async fn get_system_wide_notifications(
9999
Ok(HttpResponse::Ok().json(notifications))
100100
}
101101

102+
#[derive(Deserialize)]
103+
struct CreateNotificationForGroupRequest {
104+
pub title: String,
105+
pub content: String,
106+
}
107+
102108
/// Endpoint to create group notification
103109
#[post("/groups/{id}/notifications")]
104110
pub async fn create_group_notification(
105111
data: web::Data<AppState>,
106112
user: web::ReqData<UserData>,
107-
body: web::Json<CreateNotificationRequest>,
113+
body: web::Json<CreateNotificationForGroupRequest>,
108114
path: web::Path<(i32,)>,
109115
) -> Result<HttpResponse, ApiError> {
110116
let conn = &mut data.db.db.get().unwrap();

usernator/internal/grpc/user.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package grpc
22

33
import (
44
"context"
5-
"strings"
65
"usernator/api"
76
"usernator/internal/models"
87
"usernator/internal/shared"
@@ -42,7 +41,7 @@ func (s *GrpcServer) GetUsers(ctx context.Context, in *api.UsersRequest) (*api.U
4241
func (s *GrpcServer) SearchStudents(ctx context.Context, in *api.SearchStudentsRequest) (*api.UsersResponse, error) {
4342
var users []models.User
4443
shared.Database.Where(
45-
"roles @> ARRAY['ROLE_STUDENT'] AND to_tsvector('english', username) @@ to_tsquery('english', ?)", strings.Join(strings.Split(" ", in.Search), "&")).Limit(30).Find(&users)
44+
"roles @> ARRAY['ROLE_STUDENT'] AND username LIKE ?", "%"+in.Search+"%").Limit(30).Find(&users)
4645
var responseUsers []*api.UserResponse
4746
for _, user := range users {
4847
responseUsers = append(responseUsers, &api.UserResponse{

web/app/dashboard/page.tsx

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
"use client";
22
import useCurrentUser from "@/hooks/useCurrentUser";
3-
import {Container, Title, Text, Card, Grid, Group, Flex, Box, Blockquote} from "@mantine/core";
4-
import {IconInfoCircle, IconTrophyFilled} from "@tabler/icons-react";
3+
import {
4+
Container,
5+
Title,
6+
Text,
7+
Card,
8+
Grid,
9+
Group,
10+
Flex,
11+
Box,
12+
Blockquote,
13+
} from "@mantine/core";
14+
import { IconInfoCircle, IconTrophyFilled } from "@tabler/icons-react";
515
import { useTranslation } from "react-i18next";
616
import useApiServiceClient from "@/hooks/useApiServiceClient";
717
import useClientQuery from "@/hooks/useClientQuery";
8-
import {Carousel} from "@mantine/carousel";
18+
import { Carousel } from "@mantine/carousel";
919
import RichTextDisplay from "@/components/display/RichTextDisplay";
1020

1121
const DashboardPage = () => {
@@ -20,21 +30,29 @@ const DashboardPage = () => {
2030
{t("welcome-back")} {user?.username}!
2131
</Title>
2232
{notifications && notifications?.length > 0 && (
23-
<Carousel withIndicators height={200}>
24-
{notifications.map((notification) => (
25-
<Carousel.Slide key={notification.id}>
26-
<Card h={200}>
27-
<Box mx="xl">
28-
<Title order={2}>{notification.title}</Title>
29-
<RichTextDisplay content={notification.content} fullSize={false} />
30-
</Box>
31-
</Card>
32-
</Carousel.Slide>
33-
))}
34-
</Carousel>
33+
<Carousel withIndicators height={200}>
34+
{notifications.map((notification) => (
35+
<Carousel.Slide key={notification.id}>
36+
<Card h={200}>
37+
<Box mx="xl">
38+
<Title order={2}>{notification.title}</Title>
39+
<RichTextDisplay
40+
content={notification.content}
41+
fullSize={false}
42+
/>
43+
</Box>
44+
</Card>
45+
</Carousel.Slide>
46+
))}
47+
</Carousel>
3548
)}
36-
<Blockquote color="indigo" icon={<IconInfoCircle />} mt="xl" cite="~ Development team">
37-
{t('development-status')}
49+
<Blockquote
50+
color="indigo"
51+
icon={<IconInfoCircle />}
52+
mt="xl"
53+
cite="~ Development team"
54+
>
55+
{t("development-status")}
3856
</Blockquote>
3957
<Grid>
4058
<Grid.Col span={4}>
@@ -50,14 +68,11 @@ const DashboardPage = () => {
5068
</Grid.Col>
5169
<Grid.Col span={8}>
5270
<Card shadow="sm" padding="xl" mt={20}>
53-
<Title order={2}>Release v0.2.2-stable</Title>
71+
<Title order={2}>Release v0.2.2-fix</Title>
5472
<Text>
5573
We had some groundbreaking changes within our app for the current
5674
release:
57-
<br />
58-
- Improved scalability <br/>
59-
- Group and system wide notifications <br/>
60-
- Limited runner options for unverified groups <br/>
75+
<br />- Fixed some bugs
6176
</Text>
6277
</Card>
6378
</Grid.Col>

0 commit comments

Comments
 (0)