diff --git a/docs/attendance.md b/docs/attendance.md index b895fe6..54598cb 100644 --- a/docs/attendance.md +++ b/docs/attendance.md @@ -32,6 +32,38 @@ struct AttendanceSummary { ## Queries +### Get Attendance +Retrieve attendance records by member ID or date. + +```graphql +# Get attendance by member ID +query { + attendance(memberId: 1) { + attendanceId + date + isPresent + timeIn + timeOut + } +} +``` + +Get all attendance for a specific date + +```graphql +query { + attendanceByDate(date: "2025-02-27") { + attendanceId + memberId + name + year + isPresent + timeIn + timeOut + } +} +``` + ### Mark Attendance Record a member's attendance for the day. diff --git a/src/graphql/queries/attendance_queries.rs b/src/graphql/queries/attendance_queries.rs index 576fdab..c2ffb91 100644 --- a/src/graphql/queries/attendance_queries.rs +++ b/src/graphql/queries/attendance_queries.rs @@ -1,12 +1,15 @@ use std::sync::Arc; +use crate::models::{ + attendance::{Attendance, AttendanceWithMember}, + member::Member, +}; use async_graphql::{Context, Object, Result}; +use chrono::NaiveDate; use sqlx::PgPool; -use crate::models::{attendance::Attendance, member::Member}; - /// Sub-query for the [`Attendance`] table. The queries are: -/// * attendance - get a specific member's attendance details using their member_id, roll_no or discord_id +/// * attendance - get a specific member's attendance details using their member_id, roll_no or discord_id, or by date for all members. #[derive(Default)] pub struct AttendanceQueries; @@ -66,4 +69,26 @@ impl AttendanceQueries { Ok(attendance_query) } + + // Query to get attendance by date + async fn attendance_by_date( + &self, + ctx: &Context<'_>, + date: NaiveDate, + ) -> Result> { + let pool = ctx.data::>().expect("Pool must be in context."); + + let records = sqlx::query_as::<_, AttendanceWithMember>( + "SELECT a.attendance_id, a.member_id, a.date, a.is_present, + a.time_in, a.time_out, m.name, m.year + FROM Attendance a + JOIN Member m ON a.member_id = m.member_id + WHERE a.date = $1", + ) + .bind(date) + .fetch_all(pool.as_ref()) + .await?; + + Ok(records) + } } diff --git a/src/models/attendance.rs b/src/models/attendance.rs index d9a3668..1511eb7 100644 --- a/src/models/attendance.rs +++ b/src/models/attendance.rs @@ -48,3 +48,17 @@ pub struct MarkAttendanceInput { pub date: NaiveDate, pub hmac_signature: String, } + +/// This struct combines attendance data with member name for queries that need both. +/// It joins the Attendance table with Member to include the member's name. +#[derive(SimpleObject, FromRow)] +pub struct AttendanceWithMember { + pub attendance_id: i32, + pub member_id: i32, + pub date: NaiveDate, + pub is_present: bool, + pub time_in: Option, + pub time_out: Option, + pub name: String, + pub year: i32, +}