From 54077e1f33887c0884b0e928bd0f598cb8a6d6eb Mon Sep 17 00:00:00 2001 From: despiegk Date: Thu, 18 Sep 2025 07:07:43 +0200 Subject: [PATCH] ... --- lib/hero/heromodels/calendar_event.v | 59 ++++++++----- lib/hero/heromodels/registration_desk.v | 61 +++++++++++--- lib/hero/heromodels/registration_desk_test.v | 87 +++++++++++++++++++- 3 files changed, 174 insertions(+), 33 deletions(-) diff --git a/lib/hero/heromodels/calendar_event.v b/lib/hero/heromodels/calendar_event.v index a94e0b2f..94f86240 100644 --- a/lib/hero/heromodels/calendar_event.v +++ b/lib/hero/heromodels/calendar_event.v @@ -15,7 +15,7 @@ pub mut: location string registration_desks []u32 //link to object for registration, is where we track invitees, are not attendee unless accepted attendees []Attendee - fs_items []FileAttachment // link to docs + docs []EventDoc // link to docs calendar_id u32 // Associated calendar status EventStatus is_all_day bool @@ -26,6 +26,7 @@ pub mut: timezone string priority EventPriority public bool + locations []EventLocation } @@ -37,6 +38,7 @@ pub mut: admin bool // if set can manage the main elements of the event = description, can accept invitee... organizer bool // if set means others can ask for support, doesn't mean is admin log []AttendeeLog + location string //optional if user wants to select a location } pub enum EventPriority { @@ -84,7 +86,7 @@ pub enum RecurrenceFreq { yearly } -pub struct FileAttachment { +pub struct EventDoc { pub mut: fs_item u32 cat string // can be freely chosen, will always be made lowercase e.g. agenda @@ -100,6 +102,23 @@ pub mut: limit int = 100 // Default limit is 100 } + +pub struct EventLocation { +pub mut: + name string + description string + cat EventLocationCat + docs []EventDoc +} + +pub enum EventLocationCat { + online + physical + hybrid +} + + + pub struct DBCalendarEvent { pub mut: db &db.DB @[skip; str: skip] @@ -137,10 +156,10 @@ pub fn (self CalendarEvent) description(methodname string) string { pub fn (self CalendarEvent) example(methodname string) (string, string) { match methodname { 'set' { - return '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}}', '1' + return '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}}', '1' } 'get' { - return '{"id": 1}', '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}' + return '{"id": 1}', '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}' } 'delete' { return '{"id": 1}', 'true' @@ -149,7 +168,7 @@ pub fn (self CalendarEvent) example(methodname string) (string, string) { return '{"id": 1}', 'true' } 'list' { - return '{}', '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}]' + return '{}', '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}]' } else { return '{}', '{}' @@ -184,9 +203,9 @@ pub fn (self CalendarEvent) dump(mut e encoder.Encoder) ! { } } - // Encode fs_items array - e.add_u16(u16(self.fs_items.len)) - for fs_item in self.fs_items { + // Encode docs array + e.add_u16(u16(self.docs.len)) + for fs_item in self.docs { e.add_u32(fs_item.fs_item) e.add_string(fs_item.cat) e.add_bool(fs_item.public) @@ -260,21 +279,21 @@ pub fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decode } o.attendees = attendees - // Decode fs_items array - fs_items_len := e.get_u16()! - mut fs_items := []FileAttachment{} - for _ in 0 .. fs_items_len { + // Decode docs array + docs_len := e.get_u16()! + mut docs := []EventDoc{} + for _ in 0 .. docs_len { fs_item := e.get_u32()! cat := e.get_string()! public := e.get_bool()! - fs_items << FileAttachment{ + docs << EventDoc{ fs_item: fs_item cat: cat public: public } } - o.fs_items = fs_items + o.docs = docs o.calendar_id = e.get_u32()! o.status = unsafe { EventStatus(e.get_u8()!) } // TODO: is there no better way? @@ -320,7 +339,7 @@ pub mut: end_time string // use ourtime module to go from string to epoch location string attendees []u32 // IDs of user groups - fs_items []u32 // IDs of linked files or dirs + docs []u32 // IDs of linked files or dirs calendar_id u32 // Associated calendar status EventStatus is_all_day bool @@ -337,10 +356,10 @@ pub mut: // get new calendar event, not from the DB pub fn (mut self DBCalendarEvent) new(args CalendarEventArg) !CalendarEvent { - // Convert fs_items from []u32 to []FileAttachment - mut fs_attachments := []FileAttachment{} - for fs_item_id in args.fs_items { - fs_attachments << FileAttachment{ + // Convert docs from []u32 to []EventDoc + mut fs_attachments := []EventDoc{} + for fs_item_id in args.docs { + fs_attachments << EventDoc{ fs_item: fs_item_id cat: '' public: false @@ -351,7 +370,7 @@ pub fn (mut self DBCalendarEvent) new(args CalendarEventArg) !CalendarEvent { title: args.title location: args.location attendees: []Attendee{} - fs_items: fs_attachments + docs: fs_attachments calendar_id: args.calendar_id status: args.status is_all_day: args.is_all_day diff --git a/lib/hero/heromodels/registration_desk.v b/lib/hero/heromodels/registration_desk.v index f542e310..43bc934b 100644 --- a/lib/hero/heromodels/registration_desk.v +++ b/lib/hero/heromodels/registration_desk.v @@ -11,7 +11,7 @@ pub struct RegistrationDesk { pub mut: name string description string //probably in markdown - fs_items []u32 // link to docs + fs_items []RegistrationFileAttachment // link to docs white_list []u32 // users who can enter, if 1 specified then people need to be in this list white_list_accepted []u32 // if in this list automatically accepted black_list []u32 // users not allowed @@ -24,12 +24,19 @@ pub mut: pub struct Registration { pub mut: user_id u32 - accepted bool // an administrator needs to accept this person, now becomes an attendee + accepted bool // an administrator has accepted accepted_by u32 // the user who did the acceptance timestamp u64 // time when registration happened timestamp_acceptation u64 // when acceptation was done } +pub struct RegistrationFileAttachment { +pub mut: + fs_item u32 + cat string // can be freely chosen, will always be made lowercase e.g. agenda + public bool // everyone can see the file, otherwise only the organizers, attendees +} + pub struct DBRegistrationDesk { pub mut: db &db.DB @[skip; str: skip] @@ -90,7 +97,15 @@ pub fn (self RegistrationDesk) example(methodname string) (string, string) { pub fn (self RegistrationDesk) dump(mut e encoder.Encoder) ! { e.add_string(self.name) e.add_string(self.description) - e.add_list_u32(self.fs_items) + + // Encode fs_items array (RegistrationFileAttachment objects) + e.add_u16(u16(self.fs_items.len)) + for fs_item in self.fs_items { + e.add_u32(fs_item.fs_item) + e.add_string(fs_item.cat) + e.add_bool(fs_item.public) + } + e.add_list_u32(self.white_list) e.add_list_u32(self.white_list_accepted) e.add_list_u32(self.black_list) @@ -112,7 +127,23 @@ pub fn (self RegistrationDesk) dump(mut e encoder.Encoder) ! { pub fn (mut self DBRegistrationDesk) load(mut o RegistrationDesk, mut e encoder.Decoder) ! { o.name = e.get_string()! o.description = e.get_string()! - o.fs_items = e.get_list_u32()! + + // Decode fs_items array (RegistrationFileAttachment objects) + fs_items_len := e.get_u16()! + mut fs_items := []RegistrationFileAttachment{} + for _ in 0 .. fs_items_len { + fs_item := e.get_u32()! + cat := e.get_string()! + public := e.get_bool()! + + fs_items << RegistrationFileAttachment{ + fs_item: fs_item + cat: cat + public: public + } + } + o.fs_items = fs_items + o.white_list = e.get_list_u32()! o.white_list_accepted = e.get_list_u32()! o.black_list = e.get_list_u32()! @@ -159,15 +190,25 @@ pub mut: } pub fn (mut self DBRegistrationDesk) new(args RegistrationDeskArg) !RegistrationDesk { + // Convert fs_items from []u32 to []RegistrationFileAttachment + mut fs_attachments := []RegistrationFileAttachment{} + for fs_item_id in args.fs_items { + fs_attachments << RegistrationFileAttachment{ + fs_item: fs_item_id + cat: "" + public: false + } + } + mut o := RegistrationDesk{ - name: args.name - description: args.description - fs_items: args.fs_items - white_list: args.white_list + name: args.name + description: args.description + fs_items: fs_attachments + white_list: args.white_list white_list_accepted: args.white_list_accepted - black_list: args.black_list + black_list: args.black_list acceptance_required: args.acceptance_required - registrations: []Registration{} + registrations: []Registration{} } // Set base fields diff --git a/lib/hero/heromodels/registration_desk_test.v b/lib/hero/heromodels/registration_desk_test.v index cfa08de8..13a5ee15 100644 --- a/lib/hero/heromodels/registration_desk_test.v +++ b/lib/hero/heromodels/registration_desk_test.v @@ -30,7 +30,13 @@ fn test_registration_desk_new() ! { assert registration_desk.name == "test_registration_desk" assert registration_desk.description == "Test registration desk for unit testing" - assert registration_desk.fs_items == [u32(1001), u32(1002)] + assert registration_desk.fs_items.len == 2 + assert registration_desk.fs_items[0].fs_item == 1001 + assert registration_desk.fs_items[0].cat == "" + assert registration_desk.fs_items[0].public == false + assert registration_desk.fs_items[1].fs_item == 1002 + assert registration_desk.fs_items[1].cat == "" + assert registration_desk.fs_items[1].public == false assert registration_desk.white_list == [u32(2001), u32(2002), u32(2003)] assert registration_desk.white_list_accepted == [u32(3001)] assert registration_desk.black_list == [u32(4001), u32(4002)] @@ -73,7 +79,13 @@ fn test_registration_desk_crud_operations() ! { retrieved_desk := db_registration_desk.get(original_id)! assert retrieved_desk.name == "crud_test_registration_desk" assert retrieved_desk.description == "Test registration desk for CRUD operations" - assert retrieved_desk.fs_items == [u32(1001), u32(1002)] + assert retrieved_desk.fs_items.len == 2 + assert retrieved_desk.fs_items[0].fs_item == 1001 + assert retrieved_desk.fs_items[0].cat == "" + assert retrieved_desk.fs_items[0].public == false + assert retrieved_desk.fs_items[1].fs_item == 1002 + assert retrieved_desk.fs_items[1].cat == "" + assert retrieved_desk.fs_items[1].public == false assert retrieved_desk.white_list == [u32(2001), u32(2002)] assert retrieved_desk.white_list_accepted == [u32(3001)] assert retrieved_desk.black_list == [u32(4001)] @@ -109,7 +121,10 @@ fn test_registration_desk_crud_operations() ! { final_desk := db_registration_desk.get(original_id)! assert final_desk.name == "updated_registration_desk" assert final_desk.description == "Updated test registration desk" - assert final_desk.fs_items == [u32(1003)] + assert final_desk.fs_items.len == 1 + assert final_desk.fs_items[0].fs_item == 1003 + assert final_desk.fs_items[0].cat == "" + assert final_desk.fs_items[0].public == false assert final_desk.white_list == [u32(2003), u32(2004)] assert final_desk.white_list_accepted == [u32(3002)] assert final_desk.black_list == [u32(4002), u32(4003)] @@ -317,6 +332,10 @@ fn test_registration_desk_example() ! { } fn test_registration_desk_list() ! { + // Clear the test database first + mut mydb_clear := db.new_test()! + mydb_clear.redis.flushdb()! + // Initialize DBRegistrationDesk for testing mut mydb := db.new_test()! mut db_registration_desk := DBRegistrationDesk{ @@ -386,3 +405,65 @@ fn test_registration_desk_list() ! { println("✓ RegistrationDesk list test passed!") } + +fn test_registration_desk_fs_items_encoding_decoding() ! { + // Initialize DBRegistrationDesk for testing + mut mydb := db.new_test()! + mut db_registration_desk := DBRegistrationDesk{ + db: &mydb + } + + // Create a new registration desk + mut args := RegistrationDeskArg{ + name: "fs_items_test_desk" + description: "Test registration desk for fs_items encoding/decoding" + fs_items: [u32(1001), u32(1002)] + white_list: [] + white_list_accepted: [] + black_list: [] + start_time: "2025-01-01 10:00:00" + end_time: "2025-01-01 11:00:00" + acceptance_required: false + securitypolicy: 0 + tags: [] + comments: [] + } + + mut registration_desk := db_registration_desk.new(args)! + + // Add file attachments manually with custom values + mut fs_item1 := RegistrationFileAttachment{ + fs_item: 1001 + cat: "agenda" + public: true + } + + mut fs_item2 := RegistrationFileAttachment{ + fs_item: 2002 + cat: "minutes" + public: false + } + + registration_desk.fs_items = [fs_item1, fs_item2] + + // Save the registration desk + registration_desk = db_registration_desk.set(registration_desk)! + registration_desk_id := registration_desk.id + + // Retrieve and verify all fields were properly encoded/decoded + retrieved_desk := db_registration_desk.get(registration_desk_id)! + + assert retrieved_desk.fs_items.len == 2 + + // Verify first file attachment details + assert retrieved_desk.fs_items[0].fs_item == 1001 + assert retrieved_desk.fs_items[0].cat == "agenda" + assert retrieved_desk.fs_items[0].public == true + + // Verify second file attachment details + assert retrieved_desk.fs_items[1].fs_item == 2002 + assert retrieved_desk.fs_items[1].cat == "minutes" + assert retrieved_desk.fs_items[1].public == false + + println("✓ RegistrationDesk fs_items encoding/decoding test passed!") +}