module heromodels import freeflowuniverse.herolib.data.encoder import freeflowuniverse.herolib.data.ourtime import freeflowuniverse.herolib.hero.db import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_int, new_response_true } import freeflowuniverse.herolib.hero.user { UserRef } import json @[heap] pub struct Message { db.Base pub mut: // id u32 subject string message string parent u32 // id of parent message if any, 0 means none author u32 // links to user to []u32 // if message/message has been sent to someone specifically cc []u32 // like to but then for cc send_log []SendLog } pub struct SendLog { pub mut: to []u32 // if message/message has been sent to someone specifically cc []u32 // like to but then for cc status SendStatus timestamp u64 // when was it done } enum SendStatus { sent received acknowledged } //////////TO BE GENERATED BY AI//////////////////////////////// ///BASIC CRUD FUNCTIONS pub struct DBMessages { pub mut: db &db.DB @[skip; str: skip] } @[params] pub struct MessageListArg { pub mut: parent u32 author u32 limit int = 100 // Default limit is 100 } pub fn (self Message) type_name() string { return 'messages' } // return example rpc call and result for each methodname pub fn (self Message) description(methodname string) string { match methodname { 'set' { return 'Create or update a message. Returns the ID of the message.' } 'get' { return 'Retrieve a message by ID. Returns the message object.' } 'delete' { return 'Delete a message by ID. Returns true if successful.' } 'exist' { return 'Check if a message exists by ID. Returns true or false.' } 'list' { return 'List all messages. Returns an array of message objects.' } else { return 'This is generic method for the root object, TODO fill in, ...' } } } // return example rpc call and result for each methodname pub fn (self Message) example(methodname string) (string, string) { match methodname { 'set' { return '{"message": {"subject": "Test Subject", "message": "This is a test message.", "parent": 0, "author": 1, "to": [2, 3], "cc": [4], "send_log": [{"to": [2], "cc": [], "status": "sent", "timestamp": 1678886400}]}}', '1' } 'get' { return '{"id": 1}', '{"subject": "Test Subject", "message": "This is a test message.", "parent": 0, "author": 1, "to": [2, 3], "cc": [4], "send_log": [{"to": [2], "cc": [], "status": "sent", "timestamp": 1678886400}]}' } 'delete' { return '{"id": 1}', 'true' } 'exist' { return '{"id": 1}', 'true' } 'list' { return '{}', '[{"subject": "Test Subject", "message": "This is a test message.", "parent": 0, "author": 1, "to": [2, 3], "cc": [4], "send_log": [{"to": [2], "cc": [], "status": "sent", "timestamp": 1678886400}]}]' } else { return '{}', '{}' } } } pub fn (self Message) dump(mut e encoder.Encoder) ! { e.add_string(self.subject) e.add_string(self.message) e.add_u32(self.parent) e.add_u32(self.author) e.add_list_u32(self.to) e.add_list_u32(self.cc) // Encode send_log array e.add_u16(u16(self.send_log.len)) for log_entry in self.send_log { e.add_list_u32(log_entry.to) e.add_list_u32(log_entry.cc) e.add_u8(u8(log_entry.status)) e.add_u64(log_entry.timestamp) } } pub fn (mut self DBMessages) load(mut o Message, mut e encoder.Decoder) ! { o.subject = e.get_string()! o.message = e.get_string()! o.parent = e.get_u32()! o.author = e.get_u32()! o.to = e.get_list_u32()! o.cc = e.get_list_u32()! // Decode send_log array send_log_len := e.get_u16()! mut send_logs := []SendLog{} for _ in 0 .. send_log_len { to_list := e.get_list_u32()! cc_list := e.get_list_u32()! status := unsafe { SendStatus(e.get_u8()!) } timestamp := e.get_u64()! send_logs << SendLog{ to: to_list cc: cc_list status: status timestamp: timestamp } } o.send_log = send_logs } @[params] pub struct MessageArg { pub mut: subject string message string @[required] parent u32 author u32 to []u32 cc []u32 } // get new message, not from the DB pub fn (mut self DBMessages) new(args MessageArg) !Message { mut o := Message{ subject: args.subject message: args.message parent: args.parent author: args.author to: args.to cc: args.cc send_log: []SendLog{} // Initialize as empty updated_at: ourtime.now().unix() } return o } pub fn (mut self DBMessages) set(o Message) !Message { // Use db set function which returns the object with assigned ID return self.db.set[Message](o)! } pub fn (mut self DBMessages) delete(id u32) !bool { // Check if the item exists before trying to delete if !self.db.exists[Message](id)! { return false } self.db.delete[Message](id)! return true } pub fn (mut self DBMessages) exist(id u32) !bool { return self.db.exists[Message](id)! } pub fn (mut self DBMessages) get(id u32) !Message { mut o, data := self.db.get_data[Message](id)! mut e_decoder := encoder.decoder_new(data) self.load(mut o, mut e_decoder)! return o } pub fn (mut self DBMessages) list(args MessageListArg) ![]Message { // Get all messages from the database all_messages := self.db.list[Message]()!.map(self.get(it)!) // Apply filters mut filtered_messages := []Message{} for message in all_messages { // Filter by parent if provided if args.parent != 0 && message.parent != args.parent { continue } // Filter by author if provided if args.author != 0 && message.author != args.author { continue } filtered_messages << message } // Limit results to 100 or the specified limit mut limit := args.limit if limit > 100 { limit = 100 } if filtered_messages.len > limit { return filtered_messages[..limit] } return filtered_messages } pub fn message_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response { match method { 'get' { id := db.decode_u32(params)! res := f.messages.get(id)! return new_response(rpcid, json.encode(res)) } 'set' { mut o := db.decode_generic[Message](params)! o = f.messages.set(o)! return new_response_int(rpcid, int(o.id)) } 'delete' { id := db.decode_u32(params)! deleted := f.messages.delete(id)! if deleted { return new_response_true(rpcid) } else { return new_error(rpcid, code: 404 message: 'Message with ID ${id} not found' ) } } 'exist' { id := db.decode_u32(params)! if f.messages.exist(id)! { return new_response_true(rpcid) } else { return new_response_false(rpcid) } } 'list' { args := db.decode_generic[MessageListArg](params)! res := f.messages.list(args)! return new_response(rpcid, json.encode(res)) } else { return new_error(rpcid, code: 32601 message: 'Method ${method} not found on message' ) } } }