diff --git a/examples/clients/zinit_rpc.vsh b/examples/clients/zinit_rpc.vsh index 7c991be1..a0a78877 100755 --- a/examples/clients/zinit_rpc.vsh +++ b/examples/clients/zinit_rpc.vsh @@ -52,7 +52,6 @@ println(' - API title: ${spec.info.title}') println(' - API version: ${spec.info.version}') println(' - Methods available: ${spec.methods.len}') - // 2. List all services println('\n2. Listing all services...') services := client.service_list() or { diff --git a/lib/builder/bootstrapper.v b/lib/builder/bootstrapper.v index 90117531..5c0a73f2 100644 --- a/lib/builder/bootstrapper.v +++ b/lib/builder/bootstrapper.v @@ -3,9 +3,7 @@ module builder import os import freeflowuniverse.herolib.core.texttools import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.osal.core as osal import freeflowuniverse.herolib.ui.console -import v.embed_file const heropath_ = os.dir(@FILE) + '/../' @@ -52,10 +50,10 @@ pub mut: pub fn (mut node Node) hero_install(args HeroInstallArgs) ! { console.print_debug('install hero') - mut bs := bootstrapper() + bootstrapper() myenv := node.environ_get()! - homedir := myenv['HOME'] or { return error("can't find HOME in env") } + _ := myenv['HOME'] or { return error("can't find HOME in env") } mut todo := []string{} if !args.compile { diff --git a/lib/core/herocmds/playbook_lib.v b/lib/core/herocmds/playbook_lib.v index 518274d5..1ad2a1d9 100644 --- a/lib/core/herocmds/playbook_lib.v +++ b/lib/core/herocmds/playbook_lib.v @@ -150,21 +150,20 @@ pub fn plbook_code_get(cmd Command) !string { // same as session_run_get but will also run the plbook pub fn plbook_run(cmd Command) !(&playbook.PlayBook, string) { - heroscript := cmd.flags.get_string('heroscript') or { '' } + heroscript := cmd.flags.get_string('heroscript') or { '' } mut path := '' mut plbook := if heroscript.len > 0 { playbook.new(text: heroscript)! } else { - path - = plbook_code_get(cmd)! + path = plbook_code_get(cmd)! if path.len == 0 { return error(cmd.help_message()) } // add all actions inside to the plbook - playbook.new(path: path)! + playbook.new(path: path)! } - + dagu := cmd.flags.get_bool('dagu') or { false } playcmds.run(plbook: plbook)! diff --git a/lib/data/paramsparser/params_get_kwargs_test.v b/lib/data/paramsparser/params_get_kwargs_test.v index 5a8ac5f1..c4ffe23f 100644 --- a/lib/data/paramsparser/params_get_kwargs_test.v +++ b/lib/data/paramsparser/params_get_kwargs_test.v @@ -175,7 +175,7 @@ fn test_get_u64_default() { assert params.get_u64_default('key3', 17)! == 17 } -fn test_get_u32()! { +fn test_get_u32() ! { text := ' key1: val1 key2: 19 diff --git a/lib/develop/gittools/repository_cache.v b/lib/develop/gittools/repository_cache.v index 1f857fd5..db44a757 100644 --- a/lib/develop/gittools/repository_cache.v +++ b/lib/develop/gittools/repository_cache.v @@ -27,7 +27,7 @@ fn (mut repo GitRepo) cache_get() ! { if repo_json.len > 0 { mut cached := json.decode(GitRepo, repo_json)! cached.gs = repo.gs - cached.config.remote_check_period = 3600 * 24 * 7 + cached.config.remote_check_period = 3600 * 24 * 7 repo = cached } } diff --git a/lib/develop/gittools/repository_utils.v b/lib/develop/gittools/repository_utils.v index ae0dd97d..6c8caf24 100644 --- a/lib/develop/gittools/repository_utils.v +++ b/lib/develop/gittools/repository_utils.v @@ -182,7 +182,7 @@ pub fn (mut gs GitStructure) check_repos_exist(args ReposActionsArgs) !string { account: args.account provider: args.provider )! - + if repos.len > 0 { // Repository exists - print path and return success if !args.script { diff --git a/lib/hero/heromodels/calendar.v b/lib/hero/heromodels/calendar.v index 80c869d5..43b7e66e 100644 --- a/lib/hero/heromodels/calendar.v +++ b/lib/hero/heromodels/calendar.v @@ -6,68 +6,68 @@ import time // Calendar represents a collection of events @[heap] pub struct Calendar { - Base + Base pub mut: - group_id u32 // Associated group for permissions - events []u32 // IDs of calendar events (changed to u32 to match CalendarEvent) - color string // Hex color code - timezone string - is_public bool + group_id u32 // Associated group for permissions + events []u32 // IDs of calendar events (changed to u32 to match CalendarEvent) + color string // Hex color code + timezone string + is_public bool } @[params] pub struct CalendarArgs { - BaseArgs + BaseArgs pub mut: - group_id u32 - events []u32 - color string - timezone string - is_public bool + group_id u32 + events []u32 + color string + timezone string + is_public bool } pub fn calendar_new(args CalendarArgs) !Calendar { - mut commentids:=[]u32{} - for comment in args.comments{ - // Convert CommentArg to CommentArgExtended - extended_comment := CommentArgExtended{ - comment: comment.comment - parent: 0 - author: 0 - } - commentids << comment_set(extended_comment)! - } - mut obj := Calendar{ - id: args.id or {0} // Will be set by DB? - name: args.name - description: args.description - created_at: ourtime.now().unix() - updated_at: ourtime.now().unix() - securitypolicy: args.securitypolicy or {0} - tags: tags2id(args.tags)! - comments: commentids - group_id: args.group_id - events: args.events - color: args.color - timezone: args.timezone - is_public: args.is_public - } - return obj + mut commentids := []u32{} + for comment in args.comments { + // Convert CommentArg to CommentArgExtended + extended_comment := CommentArgExtended{ + comment: comment.comment + parent: 0 + author: 0 + } + commentids << comment_set(extended_comment)! + } + mut obj := Calendar{ + id: args.id or { 0 } // Will be set by DB? + name: args.name + description: args.description + created_at: ourtime.now().unix() + updated_at: ourtime.now().unix() + securitypolicy: args.securitypolicy or { 0 } + tags: tags2id(args.tags)! + comments: commentids + group_id: args.group_id + events: args.events + color: args.color + timezone: args.timezone + is_public: args.is_public + } + return obj } pub fn (mut c Calendar) add_event(event_id u32) { // Changed event_id to u32 - if event_id !in c.events { - c.events << event_id - c.updated_at = ourtime.now().unix() // Use Base's updated_at - } + if event_id !in c.events { + c.events << event_id + c.updated_at = ourtime.now().unix() // Use Base's updated_at + } } pub fn (mut c Calendar) dump() []u8 { - //TODO: implement based on lib/data/encoder/readme.md - return []u8{} + // TODO: implement based on lib/data/encoder/readme.md + return []u8{} } pub fn calendar_load(data []u8) Calendar { - //TODO: implement based on lib/data/encoder/readme.md - return Calendar{} -} \ No newline at end of file + // TODO: implement based on lib/data/encoder/readme.md + return Calendar{} +} diff --git a/lib/hero/heromodels/calendar_event.v b/lib/hero/heromodels/calendar_event.v index b59e1a81..db3205f1 100644 --- a/lib/hero/heromodels/calendar_event.v +++ b/lib/hero/heromodels/calendar_event.v @@ -9,256 +9,253 @@ import freeflowuniverse.herolib.core.redisclient // CalendarEvent represents a single event in a calendar @[heap] pub struct CalendarEvent { - Base + Base pub mut: - title string - start_time i64 // Unix timestamp - end_time i64 // Unix timestamp - location string - attendees []u32 // IDs of user groups - fs_items []u32 // IDs of linked files or dirs - calendar_id u32 // Associated calendar - status EventStatus - is_all_day bool - is_recurring bool - recurrence []RecurrenceRule //normally empty - reminder_mins []int // Minutes before event for reminders - color string // Hex color code - timezone string + title string + start_time i64 // Unix timestamp + end_time i64 // Unix timestamp + location string + attendees []u32 // IDs of user groups + fs_items []u32 // IDs of linked files or dirs + calendar_id u32 // Associated calendar + status EventStatus + is_all_day bool + is_recurring bool + recurrence []RecurrenceRule // normally empty + reminder_mins []int // Minutes before event for reminders + color string // Hex color code + timezone string } pub struct Attendee { pub mut: - user_id u32 - status AttendanceStatus - role AttendeeRole + user_id u32 + status AttendanceStatus + role AttendeeRole } pub enum AttendanceStatus { - no_response - accepted - declined - tentative + no_response + accepted + declined + tentative } pub enum AttendeeRole { - required - optional - organizer + required + optional + organizer } pub enum EventStatus { - draft - published - cancelled - completed + draft + published + cancelled + completed } pub struct RecurrenceRule { pub mut: - frequency RecurrenceFreq - interval int // Every N frequencies - until i64 // End date (Unix timestamp) - count int // Number of occurrences - by_weekday []int // Days of week (0=Sunday) - by_monthday []int // Days of month + frequency RecurrenceFreq + interval int // Every N frequencies + until i64 // End date (Unix timestamp) + count int // Number of occurrences + by_weekday []int // Days of week (0=Sunday) + by_monthday []int // Days of month } pub enum RecurrenceFreq { - none - daily - weekly - monthly - yearly + none + daily + weekly + monthly + yearly } - @[params] pub struct CalendarEventArgs { - BaseArgs + BaseArgs pub mut: - title string - start_time string // use ourtime module to go from string to epoch - 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 - calendar_id u32 // Associated calendar - status EventStatus - is_all_day bool - is_recurring bool - recurrence []RecurrenceRule - reminder_mins []int // Minutes before event for reminders - color string // Hex color code - timezone string + title string + start_time string // use ourtime module to go from string to epoch + 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 + calendar_id u32 // Associated calendar + status EventStatus + is_all_day bool + is_recurring bool + recurrence []RecurrenceRule + reminder_mins []int // Minutes before event for reminders + color string // Hex color code + timezone string } - pub fn calendar_event_new(args CalendarEventArgs) !CalendarEvent { - // Convert tags to u32 ID - tags_id := tags2id(args.tags)! - + // Convert tags to u32 ID + tags_id := tags2id(args.tags)! - return CalendarEvent{ - // Base fields - id: args.id or { 0 } - name: args.name - description: args.description - created_at: ourtime.now().unix() - updated_at: ourtime.now().unix() - securitypolicy: args.securitypolicy or { 0 } - tags: tags_id - comments: comments2ids(args.comments)! + return CalendarEvent{ + // Base fields + id: args.id or { 0 } + name: args.name + description: args.description + created_at: ourtime.now().unix() + updated_at: ourtime.now().unix() + securitypolicy: args.securitypolicy or { 0 } + tags: tags_id + comments: comments2ids(args.comments)! - // CalendarEvent specific fields - title: args.title - start_time: ourtime.new(args.start_time)!.unix() - end_time: ourtime.new(args.end_time)!.unix() - location: args.location - attendees: args.attendees - fs_items: args.fs_items - calendar_id: args.calendar_id - status: args.status - is_all_day: args.is_all_day - is_recurring: args.is_recurring - recurrence: args.recurrence - reminder_mins: args.reminder_mins - color: args.color - timezone: args.timezone - } + // CalendarEvent specific fields + title: args.title + start_time: ourtime.new(args.start_time)!.unix() + end_time: ourtime.new(args.end_time)!.unix() + location: args.location + attendees: args.attendees + fs_items: args.fs_items + calendar_id: args.calendar_id + status: args.status + is_all_day: args.is_all_day + is_recurring: args.is_recurring + recurrence: args.recurrence + reminder_mins: args.reminder_mins + color: args.color + timezone: args.timezone + } } pub fn (mut e CalendarEvent) dump() ![]u8 { - // Create a new encoder - mut enc := encoder.new() - - // Add version byte - enc.add_u8(1) - - // Encode Base fields - enc.add_u32(e.id) - enc.add_string(e.name) - enc.add_string(e.description) - enc.add_i64(e.created_at) - enc.add_i64(e.updated_at) - enc.add_u32(e.securitypolicy) - enc.add_u32(e.tags) - enc.add_list_u32(e.comments) - - // Encode CalendarEvent specific fields - enc.add_string(e.title) - enc.add_string(e.description) - enc.add_i64(e.start_time) - enc.add_i64(e.end_time) - enc.add_string(e.location) - enc.add_list_u32(e.attendees) - enc.add_list_u32(e.fs_items) - enc.add_u32(e.calendar_id) - enc.add_u8(u8(e.status)) - enc.add_bool(e.is_all_day) - enc.add_bool(e.is_recurring) - - // Encode recurrence array - enc.add_u16(u16(e.recurrence.len)) - for rule in e.recurrence { - enc.add_u8(u8(rule.frequency)) - enc.add_int(rule.interval) - enc.add_i64(rule.until) - enc.add_int(rule.count) - enc.add_list_int(rule.by_weekday) - enc.add_list_int(rule.by_monthday) - } - - enc.add_list_int(e.reminder_mins) - enc.add_string(e.color) - enc.add_string(e.timezone) - - return enc.data + // Create a new encoder + mut enc := encoder.new() + + // Add version byte + enc.add_u8(1) + + // Encode Base fields + enc.add_u32(e.id) + enc.add_string(e.name) + enc.add_string(e.description) + enc.add_i64(e.created_at) + enc.add_i64(e.updated_at) + enc.add_u32(e.securitypolicy) + enc.add_u32(e.tags) + enc.add_list_u32(e.comments) + + // Encode CalendarEvent specific fields + enc.add_string(e.title) + enc.add_string(e.description) + enc.add_i64(e.start_time) + enc.add_i64(e.end_time) + enc.add_string(e.location) + enc.add_list_u32(e.attendees) + enc.add_list_u32(e.fs_items) + enc.add_u32(e.calendar_id) + enc.add_u8(u8(e.status)) + enc.add_bool(e.is_all_day) + enc.add_bool(e.is_recurring) + + // Encode recurrence array + enc.add_u16(u16(e.recurrence.len)) + for rule in e.recurrence { + enc.add_u8(u8(rule.frequency)) + enc.add_int(rule.interval) + enc.add_i64(rule.until) + enc.add_int(rule.count) + enc.add_list_int(rule.by_weekday) + enc.add_list_int(rule.by_monthday) + } + + enc.add_list_int(e.reminder_mins) + enc.add_string(e.color) + enc.add_string(e.timezone) + + return enc.data } pub fn (ce CalendarEvent) load(data []u8) !CalendarEvent { - // Create a new decoder - mut dec := encoder.decoder_new(data) - - // Read version byte - version := dec.get_u8()! - if version != 1 { - return error('wrong version in calendar event load') - } - - // Decode Base fields - id := dec.get_u32()! - name := dec.get_string()! - description := dec.get_string()! - created_at := dec.get_i64()! - updated_at := dec.get_i64()! - securitypolicy := dec.get_u32()! - tags := dec.get_u32()! - comments := dec.get_list_u32()! - - // Decode CalendarEvent specific fields - title := dec.get_string()! - description2 := dec.get_string()! // Second description field - start_time := dec.get_i64()! - end_time := dec.get_i64()! - location := dec.get_string()! - attendees := dec.get_list_u32()! - fs_items := dec.get_list_u32()! - calendar_id := dec.get_u32()! - status := unsafe { EventStatus(dec.get_u8()!) } - is_all_day := dec.get_bool()! - is_recurring := dec.get_bool()! - - // Decode recurrence array - recurrence_len := dec.get_u16()! - mut recurrence := []RecurrenceRule{} - for _ in 0..recurrence_len { - frequency := unsafe{RecurrenceFreq(dec.get_u8()!)} - interval := dec.get_int()! - until := dec.get_i64()! - count := dec.get_int()! - by_weekday := dec.get_list_int()! - by_monthday := dec.get_list_int()! - - recurrence << RecurrenceRule{ - frequency: frequency - interval: interval - until: until - count: count - by_weekday: by_weekday - by_monthday: by_monthday - } - } - - reminder_mins := dec.get_list_int()! - color := dec.get_string()! - timezone := dec.get_string()! - - return CalendarEvent{ - // Base fields - id: id - name: name - description: description - created_at: created_at - updated_at: updated_at - securitypolicy: securitypolicy - tags: tags - comments: comments - - // CalendarEvent specific fields - title: title - start_time: start_time - end_time: end_time - location: location - attendees: attendees - fs_items: fs_items - calendar_id: calendar_id - status: status - is_all_day: is_all_day - is_recurring: is_recurring - recurrence: recurrence - reminder_mins: reminder_mins - color: color - timezone: timezone - } + // Create a new decoder + mut dec := encoder.decoder_new(data) + + // Read version byte + version := dec.get_u8()! + if version != 1 { + return error('wrong version in calendar event load') + } + + // Decode Base fields + id := dec.get_u32()! + name := dec.get_string()! + description := dec.get_string()! + created_at := dec.get_i64()! + updated_at := dec.get_i64()! + securitypolicy := dec.get_u32()! + tags := dec.get_u32()! + comments := dec.get_list_u32()! + + // Decode CalendarEvent specific fields + title := dec.get_string()! + description2 := dec.get_string()! // Second description field + start_time := dec.get_i64()! + end_time := dec.get_i64()! + location := dec.get_string()! + attendees := dec.get_list_u32()! + fs_items := dec.get_list_u32()! + calendar_id := dec.get_u32()! + status := unsafe { EventStatus(dec.get_u8()!) } + is_all_day := dec.get_bool()! + is_recurring := dec.get_bool()! + + // Decode recurrence array + recurrence_len := dec.get_u16()! + mut recurrence := []RecurrenceRule{} + for _ in 0 .. recurrence_len { + frequency := unsafe { RecurrenceFreq(dec.get_u8()!) } + interval := dec.get_int()! + until := dec.get_i64()! + count := dec.get_int()! + by_weekday := dec.get_list_int()! + by_monthday := dec.get_list_int()! + + recurrence << RecurrenceRule{ + frequency: frequency + interval: interval + until: until + count: count + by_weekday: by_weekday + by_monthday: by_monthday + } + } + + reminder_mins := dec.get_list_int()! + color := dec.get_string()! + timezone := dec.get_string()! + + return CalendarEvent{ + // Base fields + id: id + name: name + description: description + created_at: created_at + updated_at: updated_at + securitypolicy: securitypolicy + tags: tags + comments: comments + + // CalendarEvent specific fields + title: title + start_time: start_time + end_time: end_time + location: location + attendees: attendees + fs_items: fs_items + calendar_id: calendar_id + status: status + is_all_day: is_all_day + is_recurring: is_recurring + recurrence: recurrence + reminder_mins: reminder_mins + color: color + timezone: timezone + } } diff --git a/lib/hero/heromodels/chat_group.v b/lib/hero/heromodels/chat_group.v index b0b915d9..3b973483 100644 --- a/lib/hero/heromodels/chat_group.v +++ b/lib/hero/heromodels/chat_group.v @@ -8,57 +8,57 @@ import json @[heap] pub struct ChatGroup { pub mut: - id string // blake192 hash - name string - description string - group_id string // Associated group for permissions - chat_type ChatType - messages []string // IDs of chat messages - created_at i64 - updated_at i64 - last_activity i64 - is_archived bool - tags []string + id string // blake192 hash + name string + description string + group_id string // Associated group for permissions + chat_type ChatType + messages []string // IDs of chat messages + created_at i64 + updated_at i64 + last_activity i64 + is_archived bool + tags []string } pub enum ChatType { - public_channel - private_channel - direct_message - group_message + public_channel + private_channel + direct_message + group_message } pub fn (mut c ChatGroup) calculate_id() { - content := json.encode(ChatGroupContent{ - name: c.name - description: c.description - group_id: c.group_id - chat_type: c.chat_type - is_archived: c.is_archived - tags: c.tags - }) - hash := blake3.sum256(content.bytes()) - c.id = hash.hex()[..48] + content := json.encode(ChatGroupContent{ + name: c.name + description: c.description + group_id: c.group_id + chat_type: c.chat_type + is_archived: c.is_archived + tags: c.tags + }) + hash := blake3.sum256(content.bytes()) + c.id = hash.hex()[..48] } struct ChatGroupContent { - name string - description string - group_id string - chat_type ChatType - is_archived bool - tags []string + name string + description string + group_id string + chat_type ChatType + is_archived bool + tags []string } pub fn new_chat_group(name string, group_id string, chat_type ChatType) ChatGroup { - mut chat_group := ChatGroup{ - name: name - group_id: group_id - chat_type: chat_type - created_at: time.now().unix() - updated_at: time.now().unix() - last_activity: time.now().unix() - } - chat_group.calculate_id() - return chat_group -} \ No newline at end of file + mut chat_group := ChatGroup{ + name: name + group_id: group_id + chat_type: chat_type + created_at: time.now().unix() + updated_at: time.now().unix() + last_activity: time.now().unix() + } + chat_group.calculate_id() + return chat_group +} diff --git a/lib/hero/heromodels/chat_message.v b/lib/hero/heromodels/chat_message.v index b4f542f7..65d3fe98 100644 --- a/lib/hero/heromodels/chat_message.v +++ b/lib/hero/heromodels/chat_message.v @@ -8,97 +8,97 @@ import json @[heap] pub struct ChatMessage { pub mut: - id string // blake192 hash - content string - chat_group_id string // Associated chat group - sender_id string // User ID of sender - parent_messages []MessageLink // Referenced/replied messages - fs_files []string // IDs of linked files - message_type MessageType - status MessageStatus - created_at i64 - updated_at i64 - edited_at i64 - deleted_at i64 - reactions []MessageReaction - mentions []string // User IDs mentioned in message - tags []string + id string // blake192 hash + content string + chat_group_id string // Associated chat group + sender_id string // User ID of sender + parent_messages []MessageLink // Referenced/replied messages + fs_files []string // IDs of linked files + message_type MessageType + status MessageStatus + created_at i64 + updated_at i64 + edited_at i64 + deleted_at i64 + reactions []MessageReaction + mentions []string // User IDs mentioned in message + tags []string } pub struct MessageLink { pub mut: - message_id string - link_type MessageLinkType + message_id string + link_type MessageLinkType } pub enum MessageLinkType { - reply - reference - forward - quote + reply + reference + forward + quote } pub enum MessageType { - text - image - file - voice - video - system - announcement + text + image + file + voice + video + system + announcement } pub enum MessageStatus { - sent - delivered - read - failed - deleted + sent + delivered + read + failed + deleted } pub struct MessageReaction { pub mut: - user_id string - emoji string - timestamp i64 + user_id string + emoji string + timestamp i64 } pub fn (mut m ChatMessage) calculate_id() { - content := json.encode(MessageContent{ - content: m.content - chat_group_id: m.chat_group_id - sender_id: m.sender_id - parent_messages: m.parent_messages - fs_files: m.fs_files - message_type: m.message_type - mentions: m.mentions - tags: m.tags - }) - hash := blake3.sum256(content.bytes()) - m.id = hash.hex()[..48] + content := json.encode(MessageContent{ + content: m.content + chat_group_id: m.chat_group_id + sender_id: m.sender_id + parent_messages: m.parent_messages + fs_files: m.fs_files + message_type: m.message_type + mentions: m.mentions + tags: m.tags + }) + hash := blake3.sum256(content.bytes()) + m.id = hash.hex()[..48] } struct MessageContent { - content string - chat_group_id string - sender_id string - parent_messages []MessageLink - fs_files []string - message_type MessageType - mentions []string - tags []string + content string + chat_group_id string + sender_id string + parent_messages []MessageLink + fs_files []string + message_type MessageType + mentions []string + tags []string } pub fn new_chat_message(content string, chat_group_id string, sender_id string) ChatMessage { - mut message := ChatMessage{ - content: content - chat_group_id: chat_group_id - sender_id: sender_id - message_type: .text - status: .sent - created_at: time.now().unix() - updated_at: time.now().unix() - } - message.calculate_id() - return message -} \ No newline at end of file + mut message := ChatMessage{ + content: content + chat_group_id: chat_group_id + sender_id: sender_id + message_type: .text + status: .sent + created_at: time.now().unix() + updated_at: time.now().unix() + } + message.calculate_id() + return message +} diff --git a/lib/hero/heromodels/core_methods.v b/lib/hero/heromodels/core_methods.v index 05752bdc..d0680e30 100644 --- a/lib/hero/heromodels/core_methods.v +++ b/lib/hero/heromodels/core_methods.v @@ -4,42 +4,44 @@ import freeflowuniverse.herolib.core.redisclient import freeflowuniverse.herolib.data.encoder pub fn set[T](obj T) ! { - mut redis := redisclient.core_get()! - id := obj.id - data := encoder.encode(obj)! - redis.hset("db:${T.name}",id.str(),data.bytestr())! + mut redis := redisclient.core_get()! + id := obj.id + data := encoder.encode(obj)! + redis.hset('db:${T.name}', id.str(), data.bytestr())! } pub fn get[T](id u32) !T { - mut redis := redisclient.core_get()! - data := redis.hget("db:${T.name}",id.str())! - t := T{} - return encoder.decode[T](data.bytes())! + mut redis := redisclient.core_get()! + data := redis.hget('db:${T.name}', id.str())! + t := T{} + return encoder.decode[T](data.bytes())! } pub fn exists[T](id u32) !bool { - name := T{}.type_name() - mut redis := redisclient.core_get()! - return redis.hexists("db:${name}",id.str())! + name := T{}.type_name() + mut redis := redisclient.core_get()! + return redis.hexists('db:${name}', id.str())! } pub fn delete[T](id u32) ! { - name := T{}.type_name() - mut redis := redisclient.core_get()! - redis.hdel("db:${name}", id.str())! + name := T{}.type_name() + mut redis := redisclient.core_get()! + redis.hdel('db:${name}', id.str())! } pub fn list[T]() ![]T { - mut redis := redisclient.core_get()! - ids := redis.hkeys("db:${name}")! - mut result := []T{} - for id in ids { - result << get[T](id.u32())! - } - return result + mut redis := redisclient.core_get()! + ids := redis.hkeys('db:${name}')! + mut result := []T{} + for id in ids { + result << get[T](id.u32())! + } + return result } -//make it easy to get a base object +// make it easy to get a base object pub fn new_from_base[T](args BaseArgs) !Base { - return T { Base: new_base(args)! } -} \ No newline at end of file + return T{ + Base: new_base(args)! + } +} diff --git a/lib/hero/heromodels/examples/client_example.vsh b/lib/hero/heromodels/examples/client_example.vsh index c4822354..d5c6218f 100755 --- a/lib/hero/heromodels/examples/client_example.vsh +++ b/lib/hero/heromodels/examples/client_example.vsh @@ -5,7 +5,6 @@ import json import freeflowuniverse.herolib.ui.console import freeflowuniverse.herolib.hero.heromodels.openrpc - fn send_request(mut conn unix.StreamConn, request openrpc.JsonRpcRequest) ! { request_json := json.encode(request) conn.write_string(request_json)! @@ -31,9 +30,9 @@ console.print_item('Connected to server') console.print_header('Test 1: Discover OpenRPC Specification') discover_request := openrpc.JsonRpcRequest{ jsonrpc: '2.0' - method: 'discover' - params: 'null' - id: '1' + method: 'discover' + params: 'null' + id: '1' } send_request(mut conn, discover_request)! @@ -46,9 +45,9 @@ comment_json := '{"comment": "This is a test comment from OpenRPC client", "pare create_request := openrpc.JsonRpcRequest{ jsonrpc: '2.0' - method: 'comment_set' - params: comment_json - id: '2' + method: 'comment_set' + params: comment_json + id: '2' } send_request(mut conn, create_request)! @@ -59,9 +58,9 @@ console.print_item('Comment created: ${create_response}') console.print_header('Test 3: List All Comments') list_request := openrpc.JsonRpcRequest{ jsonrpc: '2.0' - method: 'comment_list' - params: 'null' - id: '3' + method: 'comment_list' + params: 'null' + id: '3' } send_request(mut conn, list_request)! @@ -74,9 +73,9 @@ get_args_json := '{"author": 1}' get_request := openrpc.JsonRpcRequest{ jsonrpc: '2.0' - method: 'comment_get' - params: get_args_json - id: '4' + method: 'comment_get' + params: get_args_json + id: '4' } send_request(mut conn, get_request)! @@ -84,5 +83,3 @@ get_response := read_response(mut conn)! console.print_item('Comments by author: ${get_response}') console.print_header('All tests completed successfully!') - - diff --git a/lib/hero/heromodels/examples/example1.vsh b/lib/hero/heromodels/examples/example1.vsh index c98e7f87..e490c861 100755 --- a/lib/hero/heromodels/examples/example1.vsh +++ b/lib/hero/heromodels/examples/example1.vsh @@ -1,6 +1,5 @@ #!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run - // Create a user mut user := new_user('John Doe', 'john@example.com') @@ -18,7 +17,8 @@ mut issue := new_project_issue('Fix login bug', project.id, user.id, .bug) mut calendar := new_calendar('Team Calendar', group.id) // Create an event -mut event := new_calendar_event('Sprint Planning', 1672531200, 1672534800, calendar.id, user.id) +mut event := new_calendar_event('Sprint Planning', 1672531200, 1672534800, calendar.id, + user.id) calendar.add_event(event.id) // Create a filesystem @@ -34,4 +34,4 @@ println('Issue ID: ${issue.id}') println('Calendar ID: ${calendar.id}') println('Event ID: ${event.id}') println('Filesystem ID: ${fs.id}') -println('Blob ID: ${blob.id}') \ No newline at end of file +println('Blob ID: ${blob.id}') diff --git a/lib/hero/heromodels/examples/server_example.vsh b/lib/hero/heromodels/examples/server_example.vsh index 6fa64a9b..566abab3 100755 --- a/lib/hero/heromodels/examples/server_example.vsh +++ b/lib/hero/heromodels/examples/server_example.vsh @@ -20,4 +20,4 @@ console.print_item('Press Ctrl+C to stop the server') // Keep the main thread alive for { time.sleep(1 * time.second) -} \ No newline at end of file +} diff --git a/lib/hero/heromodels/fs.v b/lib/hero/heromodels/fs.v index 7bb28212..5787fde1 100644 --- a/lib/hero/heromodels/fs.v +++ b/lib/hero/heromodels/fs.v @@ -8,45 +8,45 @@ import json @[heap] pub struct Fs { pub mut: - id string // blake192 hash - name string - description string - group_id string // Associated group for permissions - root_dir_id string // ID of root directory - created_at i64 - updated_at i64 - quota_bytes i64 // Storage quota in bytes - used_bytes i64 // Current usage in bytes - tags []string + id string // blake192 hash + name string + description string + group_id string // Associated group for permissions + root_dir_id string // ID of root directory + created_at i64 + updated_at i64 + quota_bytes i64 // Storage quota in bytes + used_bytes i64 // Current usage in bytes + tags []string } pub fn (mut f Fs) calculate_id() { - content := json.encode(FsContent{ - name: f.name - description: f.description - group_id: f.group_id - quota_bytes: f.quota_bytes - tags: f.tags - }) - hash := blake3.sum256(content.bytes()) - f.id = hash.hex()[..48] + content := json.encode(FsContent{ + name: f.name + description: f.description + group_id: f.group_id + quota_bytes: f.quota_bytes + tags: f.tags + }) + hash := blake3.sum256(content.bytes()) + f.id = hash.hex()[..48] } struct FsContent { - name string - description string - group_id string - quota_bytes i64 - tags []string + name string + description string + group_id string + quota_bytes i64 + tags []string } pub fn new_fs(name string, group_id string) Fs { - mut fs := Fs{ - name: name - group_id: group_id - created_at: time.now().unix() - updated_at: time.now().unix() - } - fs.calculate_id() - return fs -} \ No newline at end of file + mut fs := Fs{ + name: name + group_id: group_id + created_at: time.now().unix() + updated_at: time.now().unix() + } + fs.calculate_id() + return fs +} diff --git a/lib/hero/heromodels/fs_blob.v b/lib/hero/heromodels/fs_blob.v index 3d0d9aa7..d97aca66 100644 --- a/lib/hero/heromodels/fs_blob.v +++ b/lib/hero/heromodels/fs_blob.v @@ -7,35 +7,35 @@ import crypto.blake3 @[heap] pub struct FsBlob { pub mut: - id string // blake192 hash of content - data []u8 // Binary data (max 1MB) - size_bytes int // Size in bytes - created_at i64 - mime_type string - encoding string // e.g., "gzip", "none" + id string // blake192 hash of content + data []u8 // Binary data (max 1MB) + size_bytes int // Size in bytes + created_at i64 + mime_type string + encoding string // e.g., "gzip", "none" } pub fn (mut b FsBlob) calculate_id() { - hash := blake3.sum256(b.data) - b.id = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars + hash := blake3.sum256(b.data) + b.id = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars } pub fn new_fs_blob(data []u8) !FsBlob { - if data.len > 1024 * 1024 { // 1MB limit - return error('Blob size exceeds 1MB limit') - } - - mut blob := FsBlob{ - data: data - size_bytes: data.len - created_at: time.now().unix() - encoding: 'none' - } - blob.calculate_id() - return blob + if data.len > 1024 * 1024 { // 1MB limit + return error('Blob size exceeds 1MB limit') + } + + mut blob := FsBlob{ + data: data + size_bytes: data.len + created_at: time.now().unix() + encoding: 'none' + } + blob.calculate_id() + return blob } pub fn (b FsBlob) verify_integrity() bool { - hash := blake3.sum256(b.data) - return hash.hex()[..48] == b.id -} \ No newline at end of file + hash := blake3.sum256(b.data) + return hash.hex()[..48] == b.id +} diff --git a/lib/hero/heromodels/fs_dir.v b/lib/hero/heromodels/fs_dir.v index 9ebd5218..d32bf643 100644 --- a/lib/hero/heromodels/fs_dir.v +++ b/lib/hero/heromodels/fs_dir.v @@ -8,46 +8,46 @@ import json @[heap] pub struct FsDir { pub mut: - id string // blake192 hash - name string - fs_id string // Associated filesystem - parent_id string // Parent directory ID (empty for root) - group_id string // Associated group for permissions - children []string // Child directory and file IDs - created_at i64 - updated_at i64 - tags []string + id string // blake192 hash + name string + fs_id string // Associated filesystem + parent_id string // Parent directory ID (empty for root) + group_id string // Associated group for permissions + children []string // Child directory and file IDs + created_at i64 + updated_at i64 + tags []string } pub fn (mut d FsDir) calculate_id() { - content := json.encode(DirContent{ - name: d.name - fs_id: d.fs_id - parent_id: d.parent_id - group_id: d.group_id - tags: d.tags - }) - hash := blake3.sum256(content.bytes()) - d.id = hash.hex()[..48] + content := json.encode(DirContent{ + name: d.name + fs_id: d.fs_id + parent_id: d.parent_id + group_id: d.group_id + tags: d.tags + }) + hash := blake3.sum256(content.bytes()) + d.id = hash.hex()[..48] } struct DirContent { - name string - fs_id string - parent_id string - group_id string - tags []string + name string + fs_id string + parent_id string + group_id string + tags []string } pub fn new_fs_dir(name string, fs_id string, parent_id string, group_id string) FsDir { - mut dir := FsDir{ - name: name - fs_id: fs_id - parent_id: parent_id - group_id: group_id - created_at: time.now().unix() - updated_at: time.now().unix() - } - dir.calculate_id() - return dir -} \ No newline at end of file + mut dir := FsDir{ + name: name + fs_id: fs_id + parent_id: parent_id + group_id: group_id + created_at: time.now().unix() + updated_at: time.now().unix() + } + dir.calculate_id() + return dir +} diff --git a/lib/hero/heromodels/fs_file.v b/lib/hero/heromodels/fs_file.v index 0156bdbb..2e3117b0 100644 --- a/lib/hero/heromodels/fs_file.v +++ b/lib/hero/heromodels/fs_file.v @@ -8,58 +8,58 @@ import json @[heap] pub struct FsFile { pub mut: - id string // blake192 hash - name string - fs_id string // Associated filesystem - directories []string // Directory IDs where this file exists - blobs []string // Blake192 IDs of file content blobs - size_bytes i64 // Total file size - mime_type string - checksum string // Overall file checksum - created_at i64 - updated_at i64 - accessed_at i64 - tags []string - metadata map[string]string // Custom metadata + id string // blake192 hash + name string + fs_id string // Associated filesystem + directories []string // Directory IDs where this file exists + blobs []string // Blake192 IDs of file content blobs + size_bytes i64 // Total file size + mime_type string + checksum string // Overall file checksum + created_at i64 + updated_at i64 + accessed_at i64 + tags []string + metadata map[string]string // Custom metadata } pub fn (mut f FsFile) calculate_id() { - content := json.encode(FileContent{ - name: f.name - fs_id: f.fs_id - directories: f.directories - blobs: f.blobs - size_bytes: f.size_bytes - mime_type: f.mime_type - checksum: f.checksum - tags: f.tags - metadata: f.metadata - }) - hash := blake3.sum256(content.bytes()) - f.id = hash.hex()[..48] + content := json.encode(FileContent{ + name: f.name + fs_id: f.fs_id + directories: f.directories + blobs: f.blobs + size_bytes: f.size_bytes + mime_type: f.mime_type + checksum: f.checksum + tags: f.tags + metadata: f.metadata + }) + hash := blake3.sum256(content.bytes()) + f.id = hash.hex()[..48] } struct FileContent { - name string - fs_id string - directories []string - blobs []string - size_bytes i64 - mime_type string - checksum string - tags []string - metadata map[string]string + name string + fs_id string + directories []string + blobs []string + size_bytes i64 + mime_type string + checksum string + tags []string + metadata map[string]string } pub fn new_fs_file(name string, fs_id string, directories []string) FsFile { - mut file := FsFile{ - name: name - fs_id: fs_id - directories: directories - created_at: time.now().unix() - updated_at: time.now().unix() - accessed_at: time.now().unix() - } - file.calculate_id() - return file -} \ No newline at end of file + mut file := FsFile{ + name: name + fs_id: fs_id + directories: directories + created_at: time.now().unix() + updated_at: time.now().unix() + accessed_at: time.now().unix() + } + file.calculate_id() + return file +} diff --git a/lib/hero/heromodels/fs_symlink.v b/lib/hero/heromodels/fs_symlink.v index b64f073e..0996a8ef 100644 --- a/lib/hero/heromodels/fs_symlink.v +++ b/lib/hero/heromodels/fs_symlink.v @@ -8,54 +8,54 @@ import json @[heap] pub struct FsSymlink { pub mut: - id string // blake192 hash - name string - fs_id string // Associated filesystem - parent_id string // Parent directory ID - target_id string // ID of target file or directory - target_type SymlinkTargetType - created_at i64 - updated_at i64 - tags []string + id string // blake192 hash + name string + fs_id string // Associated filesystem + parent_id string // Parent directory ID + target_id string // ID of target file or directory + target_type SymlinkTargetType + created_at i64 + updated_at i64 + tags []string } pub enum SymlinkTargetType { - file - directory + file + directory } pub fn (mut s FsSymlink) calculate_id() { - content := json.encode(SymlinkContent{ - name: s.name - fs_id: s.fs_id - parent_id: s.parent_id - target_id: s.target_id - target_type: s.target_type - tags: s.tags - }) - hash := blake3.sum256(content.bytes()) - s.id = hash.hex()[..48] + content := json.encode(SymlinkContent{ + name: s.name + fs_id: s.fs_id + parent_id: s.parent_id + target_id: s.target_id + target_type: s.target_type + tags: s.tags + }) + hash := blake3.sum256(content.bytes()) + s.id = hash.hex()[..48] } struct SymlinkContent { - name string - fs_id string - parent_id string - target_id string - target_type SymlinkTargetType - tags []string + name string + fs_id string + parent_id string + target_id string + target_type SymlinkTargetType + tags []string } pub fn new_fs_symlink(name string, fs_id string, parent_id string, target_id string, target_type SymlinkTargetType) FsSymlink { - mut symlink := FsSymlink{ - name: name - fs_id: fs_id - parent_id: parent_id - target_id: target_id - target_type: target_type - created_at: time.now().unix() - updated_at: time.now().unix() - } - symlink.calculate_id() - return symlink -} \ No newline at end of file + mut symlink := FsSymlink{ + name: name + fs_id: fs_id + parent_id: parent_id + target_id: target_id + target_type: target_type + created_at: time.now().unix() + updated_at: time.now().unix() + } + symlink.calculate_id() + return symlink +} diff --git a/lib/hero/heromodels/group.v b/lib/hero/heromodels/group.v index 6831b5c3..e501d47d 100644 --- a/lib/hero/heromodels/group.v +++ b/lib/hero/heromodels/group.v @@ -8,74 +8,74 @@ import json @[heap] pub struct Group { pub mut: - id string // blake192 hash - name string - description string - members []GroupMember - subgroups []string // IDs of child groups - parent_group string // ID of parent group - created_at i64 - updated_at i64 - is_public bool - tags []string + id string // blake192 hash + name string + description string + members []GroupMember + subgroups []string // IDs of child groups + parent_group string // ID of parent group + created_at i64 + updated_at i64 + is_public bool + tags []string } pub struct GroupMember { pub mut: - user_id string - role GroupRole - joined_at i64 + user_id string + role GroupRole + joined_at i64 } pub enum GroupRole { - reader - writer - admin - owner + reader + writer + admin + owner } pub fn (mut g Group) calculate_id() { - content := json.encode(GroupContent{ - name: g.name - description: g.description - members: g.members - subgroups: g.subgroups - parent_group: g.parent_group - is_public: g.is_public - tags: g.tags - }) - hash := blake3.sum256(content.bytes()) - g.id = hash.hex()[..48] + content := json.encode(GroupContent{ + name: g.name + description: g.description + members: g.members + subgroups: g.subgroups + parent_group: g.parent_group + is_public: g.is_public + tags: g.tags + }) + hash := blake3.sum256(content.bytes()) + g.id = hash.hex()[..48] } struct GroupContent { - name string - description string - members []GroupMember - subgroups []string - parent_group string - is_public bool - tags []string + name string + description string + members []GroupMember + subgroups []string + parent_group string + is_public bool + tags []string } pub fn new_group(name string, description string) Group { - mut group := Group{ - name: name - description: description - created_at: time.now().unix() - updated_at: time.now().unix() - is_public: false - } - group.calculate_id() - return group + mut group := Group{ + name: name + description: description + created_at: time.now().unix() + updated_at: time.now().unix() + is_public: false + } + group.calculate_id() + return group } pub fn (mut g Group) add_member(user_id string, role GroupRole) { - g.members << GroupMember{ - user_id: user_id - role: role - joined_at: time.now().unix() - } - g.updated_at = time.now().unix() - g.calculate_id() -} \ No newline at end of file + g.members << GroupMember{ + user_id: user_id + role: role + joined_at: time.now().unix() + } + g.updated_at = time.now().unix() + g.calculate_id() +} diff --git a/lib/hero/heromodels/openrpc/comment.v b/lib/hero/heromodels/openrpc/comment.v index d0f90a07..84bf6c37 100644 --- a/lib/hero/heromodels/openrpc/comment.v +++ b/lib/hero/heromodels/openrpc/comment.v @@ -24,25 +24,25 @@ pub fn comment_get(params string) !string { if params == 'null' || params == '{}' { return error('No valid search criteria provided. Please specify id, author, or parent.') } - + args := json.decode(CommentGetArgs, params)! - + // If ID is provided, get specific comment if id := args.id { comment := heromodels.comment_get(id)! return json.encode(comment) } - + // If author is provided, find comments by author if author := args.author { return get_comments_by_author(author)! } - + // If parent is provided, find child comments if parent := args.parent { return get_comments_by_parent(parent)! } - + return error('No valid search criteria provided. Please specify id, author, or parent.') } @@ -50,21 +50,23 @@ pub fn comment_get(params string) !string { pub fn comment_set(params string) !string { comment_arg := json.decode(heromodels.CommentArgExtended, params)! id := heromodels.comment_set(comment_arg)! - return json.encode({'id': id}) + return json.encode({ + 'id': id + }) } // comment_delete removes a comment by ID pub fn comment_delete(params string) !string { args := json.decode(CommentDeleteArgs, params)! - + // Check if comment exists if !heromodels.exists[heromodels.Comment](args.id)! { return error('Comment with id ${args.id} does not exist') } - + // Delete using core method heromodels.delete[heromodels.Comment](args.id)! - + result_json := '{"success": true, "id": ${args.id}}' return result_json } @@ -73,11 +75,11 @@ pub fn comment_delete(params string) !string { pub fn comment_list() !string { comments := heromodels.list[heromodels.Comment]()! mut ids := []u32{} - + for comment in comments { ids << comment.id } - + return json.encode(ids) } @@ -85,13 +87,13 @@ pub fn comment_list() !string { fn get_comments_by_author(author u32) !string { all_comments := heromodels.list[heromodels.Comment]()! mut matching_comments := []heromodels.Comment{} - + for comment in all_comments { if comment.author == author { matching_comments << comment } } - + return json.encode(matching_comments) } @@ -99,12 +101,12 @@ fn get_comments_by_author(author u32) !string { fn get_comments_by_parent(parent u32) !string { all_comments := heromodels.list[heromodels.Comment]()! mut matching_comments := []heromodels.Comment{} - + for comment in all_comments { if comment.parent == parent { matching_comments << comment } } - + return json.encode(matching_comments) -} \ No newline at end of file +} diff --git a/lib/hero/heromodels/openrpc/processor.v b/lib/hero/heromodels/openrpc/processor.v index 74600cee..91001bb0 100644 --- a/lib/hero/heromodels/openrpc/processor.v +++ b/lib/hero/heromodels/openrpc/processor.v @@ -18,7 +18,7 @@ pub fn new_heromodels_server(args HeroModelsServerArgs) !&HeroModelsServer { base_server := openrpcserver.new_rpc_server( socket_path: args.socket_path )! - + return &HeroModelsServer{ RPCServer: *base_server } @@ -47,6 +47,6 @@ pub fn (mut server HeroModelsServer) process(method string, params_str string) ! return server.create_error_response(-32601, 'Method not found', method) } } - + return result -} \ No newline at end of file +} diff --git a/lib/hero/heromodels/openrpc_interface.v b/lib/hero/heromodels/openrpc_interface.v index 95ceb37f..65ee3375 100644 --- a/lib/hero/heromodels/openrpc_interface.v +++ b/lib/hero/heromodels/openrpc_interface.v @@ -23,7 +23,7 @@ pub fn new_heromodels_server(args HeroModelsServerArgs) !&HeroModelsServer { base_server := openrpcserver.new_rpc_server( socket_path: args.socket_path )! - + return &HeroModelsServer{ RPCServer: *base_server } @@ -69,4 +69,4 @@ pub fn comment2id(comment string) !u32 { pub fn new_base(args BaseArgs) !Base { return openrpcserver.new_base(args)! -} \ No newline at end of file +} diff --git a/lib/hero/heromodels/project.v b/lib/hero/heromodels/project.v index dae7361b..4602fe6c 100644 --- a/lib/hero/heromodels/project.v +++ b/lib/hero/heromodels/project.v @@ -8,96 +8,112 @@ import json @[heap] pub struct Project { pub mut: - id string // blake192 hash - name string - description string - group_id string // Associated group for permissions - swimlanes []Swimlane - milestones []Milestone - issues []string // IDs of project issues - fs_files []string // IDs of linked files - status ProjectStatus - start_date i64 - end_date i64 - created_at i64 - updated_at i64 - tags []string + id string // blake192 hash + name string + description string + group_id string // Associated group for permissions + swimlanes []Swimlane + milestones []Milestone + issues []string // IDs of project issues + fs_files []string // IDs of linked files + status ProjectStatus + start_date i64 + end_date i64 + created_at i64 + updated_at i64 + tags []string } pub struct Swimlane { pub mut: - id string - name string - description string - order int - color string - is_done bool + id string + name string + description string + order int + color string + is_done bool } pub struct Milestone { pub mut: - id string - name string - description string - due_date i64 - completed bool - issues []string // IDs of issues in this milestone + id string + name string + description string + due_date i64 + completed bool + issues []string // IDs of issues in this milestone } pub enum ProjectStatus { - planning - active - on_hold - completed - cancelled + planning + active + on_hold + completed + cancelled } pub fn (mut p Project) calculate_id() { - content := json.encode(ProjectContent{ - name: p.name - description: p.description - group_id: p.group_id - swimlanes: p.swimlanes - milestones: p.milestones - issues: p.issues - fs_files: p.fs_files - status: p.status - start_date: p.start_date - end_date: p.end_date - tags: p.tags - }) - hash := blake3.sum256(content.bytes()) - p.id = hash.hex()[..48] + content := json.encode(ProjectContent{ + name: p.name + description: p.description + group_id: p.group_id + swimlanes: p.swimlanes + milestones: p.milestones + issues: p.issues + fs_files: p.fs_files + status: p.status + start_date: p.start_date + end_date: p.end_date + tags: p.tags + }) + hash := blake3.sum256(content.bytes()) + p.id = hash.hex()[..48] } struct ProjectContent { - name string - description string - group_id string - swimlanes []Swimlane - milestones []Milestone - issues []string - fs_files []string - status ProjectStatus - start_date i64 - end_date i64 - tags []string + name string + description string + group_id string + swimlanes []Swimlane + milestones []Milestone + issues []string + fs_files []string + status ProjectStatus + start_date i64 + end_date i64 + tags []string } pub fn new_project(name string, description string, group_id string) Project { - mut project := Project{ - name: name - description: description - group_id: group_id - status: .planning - created_at: time.now().unix() - updated_at: time.now().unix() - swimlanes: [ - Swimlane{id: 'todo', name: 'To Do', order: 1, color: '#f1c40f'}, - Swimlane{id: 'in_progress', name: 'In Progress', order: 2, color: '#3498db'}, - Swimlane{id: 'done', name: 'Done', order: 3, color: '#2ecc71', is_done: true} - ] - } - project.calculate_id() - return project -} \ No newline at end of file + mut project := Project{ + name: name + description: description + group_id: group_id + status: .planning + created_at: time.now().unix() + updated_at: time.now().unix() + swimlanes: [ + Swimlane{ + id: 'todo' + name: 'To Do' + order: 1 + color: '#f1c40f' + }, + Swimlane{ + id: 'in_progress' + name: 'In Progress' + order: 2 + color: '#3498db' + }, + Swimlane{ + id: 'done' + name: 'Done' + order: 3 + color: '#2ecc71' + is_done: true + }, + ] + } + project.calculate_id() + return project +} diff --git a/lib/hero/heromodels/project_issue.v b/lib/hero/heromodels/project_issue.v index cb615eb7..e42affba 100644 --- a/lib/hero/heromodels/project_issue.v +++ b/lib/hero/heromodels/project_issue.v @@ -8,109 +8,109 @@ import json @[heap] pub struct ProjectIssue { pub mut: - id string // blake192 hash - title string - description string - project_id string // Associated project - issue_type IssueType - priority IssuePriority - status IssueStatus - swimlane_id string // Current swimlane - assignees []string // User IDs - reporter string // User ID who created the issue - milestone_id string // Associated milestone - deadline i64 // Unix timestamp - estimate int // Story points or hours - fs_files []string // IDs of linked files - parent_id string // Parent issue ID (for sub-tasks) - children []string // Child issue IDs - created_at i64 - updated_at i64 - tags []string + id string // blake192 hash + title string + description string + project_id string // Associated project + issue_type IssueType + priority IssuePriority + status IssueStatus + swimlane_id string // Current swimlane + assignees []string // User IDs + reporter string // User ID who created the issue + milestone_id string // Associated milestone + deadline i64 // Unix timestamp + estimate int // Story points or hours + fs_files []string // IDs of linked files + parent_id string // Parent issue ID (for sub-tasks) + children []string // Child issue IDs + created_at i64 + updated_at i64 + tags []string } pub enum IssueType { - task - story - bug - question - epic - subtask + task + story + bug + question + epic + subtask } pub enum IssuePriority { - lowest - low - medium - high - highest - critical + lowest + low + medium + high + highest + critical } pub enum IssueStatus { - open - in_progress - blocked - review - testing - done - closed + open + in_progress + blocked + review + testing + done + closed } pub fn (mut i ProjectIssue) calculate_id() { - content := json.encode(IssueContent{ - title: i.title - description: i.description - project_id: i.project_id - issue_type: i.issue_type - priority: i.priority - status: i.status - swimlane_id: i.swimlane_id - assignees: i.assignees - reporter: i.reporter - milestone_id: i.milestone_id - deadline: i.deadline - estimate: i.estimate - fs_files: i.fs_files - parent_id: i.parent_id - children: i.children - tags: i.tags - }) - hash := blake3.sum256(content.bytes()) - i.id = hash.hex()[..48] + content := json.encode(IssueContent{ + title: i.title + description: i.description + project_id: i.project_id + issue_type: i.issue_type + priority: i.priority + status: i.status + swimlane_id: i.swimlane_id + assignees: i.assignees + reporter: i.reporter + milestone_id: i.milestone_id + deadline: i.deadline + estimate: i.estimate + fs_files: i.fs_files + parent_id: i.parent_id + children: i.children + tags: i.tags + }) + hash := blake3.sum256(content.bytes()) + i.id = hash.hex()[..48] } struct IssueContent { - title string - description string - project_id string - issue_type IssueType - priority IssuePriority - status IssueStatus - swimlane_id string - assignees []string - reporter string - milestone_id string - deadline i64 - estimate int - fs_files []string - parent_id string - children []string - tags []string + title string + description string + project_id string + issue_type IssueType + priority IssuePriority + status IssueStatus + swimlane_id string + assignees []string + reporter string + milestone_id string + deadline i64 + estimate int + fs_files []string + parent_id string + children []string + tags []string } pub fn new_project_issue(title string, project_id string, reporter string, issue_type IssueType) ProjectIssue { - mut issue := ProjectIssue{ - title: title - project_id: project_id - reporter: reporter - issue_type: issue_type - priority: .medium - status: .open - swimlane_id: 'todo' - created_at: time.now().unix() - updated_at: time.now().unix() - } - issue.calculate_id() - return issue -} \ No newline at end of file + mut issue := ProjectIssue{ + title: title + project_id: project_id + reporter: reporter + issue_type: issue_type + priority: .medium + status: .open + swimlane_id: 'todo' + created_at: time.now().unix() + updated_at: time.now().unix() + } + issue.calculate_id() + return issue +} diff --git a/lib/hero/heromodels/user.v b/lib/hero/heromodels/user.v index eafa6b49..454a1918 100644 --- a/lib/hero/heromodels/user.v +++ b/lib/hero/heromodels/user.v @@ -8,61 +8,61 @@ import json @[heap] pub struct User { pub mut: - id string // blake192 hash - name string - email string - public_key string // for encryption/signing - phone string - address string - avatar_url string - bio string - timezone string - created_at i64 - updated_at i64 - status UserStatus + id string // blake192 hash + name string + email string + public_key string // for encryption/signing + phone string + address string + avatar_url string + bio string + timezone string + created_at i64 + updated_at i64 + status UserStatus } pub enum UserStatus { - active - inactive - suspended - pending + active + inactive + suspended + pending } pub fn (mut u User) calculate_id() { - content := json.encode(UserContent{ - name: u.name - email: u.email - public_key: u.public_key - phone: u.phone - address: u.address - bio: u.bio - timezone: u.timezone - status: u.status - }) - hash := blake3.sum256(content.bytes()) - u.id = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars + content := json.encode(UserContent{ + name: u.name + email: u.email + public_key: u.public_key + phone: u.phone + address: u.address + bio: u.bio + timezone: u.timezone + status: u.status + }) + hash := blake3.sum256(content.bytes()) + u.id = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars } struct UserContent { - name string - email string - public_key string - phone string - address string - bio string - timezone string - status UserStatus + name string + email string + public_key string + phone string + address string + bio string + timezone string + status UserStatus } pub fn new_user(name string, email string) User { - mut user := User{ - name: name - email: email - created_at: time.now().unix() - updated_at: time.now().unix() - status: .active - } - user.calculate_id() - return user -} \ No newline at end of file + mut user := User{ + name: name + email: email + created_at: time.now().unix() + updated_at: time.now().unix() + status: .active + } + user.calculate_id() + return user +} diff --git a/lib/hero/heromodels/version_history.v b/lib/hero/heromodels/version_history.v index 7c8b5ad1..b3e0fd68 100644 --- a/lib/hero/heromodels/version_history.v +++ b/lib/hero/heromodels/version_history.v @@ -6,32 +6,32 @@ import time @[heap] pub struct VersionHistory { pub mut: - current_id string // blake192 hash of current version - previous_id string // blake192 hash of previous version - next_id string // blake192 hash of next version (if exists) - object_type string // Type of object (User, Group, etc.) - change_type ChangeType - changed_by string // User ID who made the change - changed_at i64 // Unix timestamp - change_notes string // Optional description of changes + current_id string // blake192 hash of current version + previous_id string // blake192 hash of previous version + next_id string // blake192 hash of next version (if exists) + object_type string // Type of object (User, Group, etc.) + change_type ChangeType + changed_by string // User ID who made the change + changed_at i64 // Unix timestamp + change_notes string // Optional description of changes } pub enum ChangeType { - create - update - delete - restore + create + update + delete + restore } pub fn new_version_history(current_id string, previous_id string, object_type string, change_type ChangeType, changed_by string) VersionHistory { - return VersionHistory{ - current_id: current_id - previous_id: previous_id - object_type: object_type - change_type: change_type - changed_by: changed_by - changed_at: time.now().unix() - } + return VersionHistory{ + current_id: current_id + previous_id: previous_id + object_type: object_type + change_type: change_type + changed_by: changed_by + changed_at: time.now().unix() + } } // Database indexes needed: @@ -39,4 +39,4 @@ pub fn new_version_history(current_id string, previous_id string, object_type st // - Index on previous_id for walking backward // - Index on next_id for walking forward // - Index on object_type for filtering by type -// - Index on changed_by for user activity tracking \ No newline at end of file +// - Index on changed_by for user activity tracking diff --git a/lib/osal/linux/factory.v b/lib/osal/linux/factory.v index d97d0db9..31e32c7f 100644 --- a/lib/osal/linux/factory.v +++ b/lib/osal/linux/factory.v @@ -1,13 +1,5 @@ module linux -// import freeflowuniverse.herolib.osal.core as osal -import freeflowuniverse.herolib.core.texttools -// import freeflowuniverse.herolib.screen -import os -import time -// import freeflowuniverse.herolib.ui.console -import freeflowuniverse.herolib.osal.core as osal - @[heap] pub struct LinuxFactory { pub mut: diff --git a/lib/osal/osinstaller/factory.v b/lib/osal/osinstaller/factory.v index 4cdb30f7..e4d319bb 100644 --- a/lib/osal/osinstaller/factory.v +++ b/lib/osal/osinstaller/factory.v @@ -15,10 +15,10 @@ pub fn new() ServerManager { } fn (s ServerManager) execute(command string) bool { - // console.print_debug(command) + console.print_debug(command) r := os.execute(command) - // console.print_debug(r) + console.print_debug(r) return true } diff --git a/lib/osal/sshagent/agent.v b/lib/osal/sshagent/agent.v index b0c29502..d51f70a1 100644 --- a/lib/osal/sshagent/agent.v +++ b/lib/osal/sshagent/agent.v @@ -1,7 +1,6 @@ module sshagent import freeflowuniverse.herolib.ui.console -import freeflowuniverse.herolib.builder // Check if SSH agent is properly configured and all is good pub fn agent_check(mut agent SSHAgent) ! { diff --git a/lib/schemas/jsonrpc/client.v b/lib/schemas/jsonrpc/client.v index 0c5093dc..639cb412 100644 --- a/lib/schemas/jsonrpc/client.v +++ b/lib/schemas/jsonrpc/client.v @@ -94,6 +94,7 @@ pub fn (mut c Client) send[T, D](request RequestGeneric[T], params SendParams) ! myerror := response.error_ or { return error('Failed to get error from response:\nRequest: ${request.encode()}\nResponse: ${response_json}\n${err}') } + // print_backtrace() mut myreq := request.encode() if c.transport is UnixSocketTransport { diff --git a/lib/schemas/jsonrpc/transport_unixsocket.v b/lib/schemas/jsonrpc/transport_unixsocket.v index c8f82fdc..55a6d994 100644 --- a/lib/schemas/jsonrpc/transport_unixsocket.v +++ b/lib/schemas/jsonrpc/transport_unixsocket.v @@ -78,11 +78,10 @@ pub fn (mut t UnixSocketTransport) send(request string, params SendParams) !stri // Append the newly read data to the total response res_total << res[..n] - //here we need to check we are at end + // here we need to check we are at end if res.bytestr().contains('\n') { break } - } unix.shutdown(socket.sock.handle) socket.close() or {} diff --git a/lib/schemas/openrpcserver/comment.v b/lib/schemas/openrpcserver/comment.v index 3d55c30d..73adbde5 100644 --- a/lib/schemas/openrpcserver/comment.v +++ b/lib/schemas/openrpcserver/comment.v @@ -3,117 +3,115 @@ module openrpcserver import freeflowuniverse.herolib.data.encoder import freeflowuniverse.herolib.data.ourtime - @[heap] pub struct Comment { pub mut: - id u32 - comment string - parent u32 //id of parent comment if any, 0 means none - updated_at i64 - author u32 //links to user + id u32 + comment string + parent u32 // id of parent comment if any, 0 means none + updated_at i64 + author u32 // links to user } pub fn (self Comment) type_name() string { - return 'comments' + return 'comments' } pub fn (self Comment) load(data []u8) !Comment { - return comment_load(data)! + return comment_load(data)! } -pub fn (self Comment) dump() ![]u8{ - // Create a new encoder - mut e := encoder.new() - e.add_u8(1) - e.add_u32(self.id) - e.add_string(self.comment) - e.add_u32(self.parent) - e.add_i64(self.updated_at) - e.add_u32(self.author) - return e.data +pub fn (self Comment) dump() ![]u8 { + // Create a new encoder + mut e := encoder.new() + e.add_u8(1) + e.add_u32(self.id) + e.add_string(self.comment) + e.add_u32(self.parent) + e.add_i64(self.updated_at) + e.add_u32(self.author) + return e.data } - -pub fn comment_load(data []u8) !Comment{ - // Create a new decoder - mut e := encoder.decoder_new(data) - version := e.get_u8()! - if version != 1 { - panic("wrong version in comment load") - } - mut comment := Comment{} - comment.id = e.get_u32()! - comment.comment = e.get_string()! - comment.parent = e.get_u32()! - comment.updated_at = e.get_i64()! - comment.author = e.get_u32()! - return comment +pub fn comment_load(data []u8) !Comment { + // Create a new decoder + mut e := encoder.decoder_new(data) + version := e.get_u8()! + if version != 1 { + panic('wrong version in comment load') + } + mut comment := Comment{} + comment.id = e.get_u32()! + comment.comment = e.get_string()! + comment.parent = e.get_u32()! + comment.updated_at = e.get_i64()! + comment.author = e.get_u32()! + return comment } - pub struct CommentArg { pub mut: - comment string - parent u32 - author u32 + comment string + parent u32 + author u32 } pub fn comment_multiset(args []CommentArg) ![]u32 { - return comments2ids(args)! + return comments2ids(args)! } pub fn comments2ids(args []CommentArg) ![]u32 { - return args.map(comment2id(it.comment)!) + return args.map(comment2id(it.comment)!) } pub fn comment2id(comment string) !u32 { - comment_fixed := comment.to_lower_ascii().trim_space() - mut redis := redisclient.core_get()! - return if comment_fixed.len > 0{ - hash := md5.hexhash(comment_fixed) - comment_found := redis.hget("db:comments", hash)! - if comment_found == ""{ - id := u32(redis.incr("db:comments:id")!) - redis.hset("db:comments", hash, id.str())! - redis.hset("db:comments", id.str(), comment_fixed)! - id - }else{ - comment_found.u32() - } - } else { 0 } + comment_fixed := comment.to_lower_ascii().trim_space() + mut redis := redisclient.core_get()! + return if comment_fixed.len > 0 { + hash := md5.hexhash(comment_fixed) + comment_found := redis.hget('db:comments', hash)! + if comment_found == '' { + id := u32(redis.incr('db:comments:id')!) + redis.hset('db:comments', hash, id.str())! + redis.hset('db:comments', id.str(), comment_fixed)! + id + } else { + comment_found.u32() + } + } else { + 0 + } } - -//get new comment, not from the DB -pub fn comment_new(args CommentArg) !Comment{ - mut o := Comment { - comment: args.comment - parent: args.parent - updated_at: ourtime.now().unix() - author: args.author - } - return o +// get new comment, not from the DB +pub fn comment_new(args CommentArg) !Comment { + mut o := Comment{ + comment: args.comment + parent: args.parent + updated_at: ourtime.now().unix() + author: args.author + } + return o } -pub fn comment_multiset(args []CommentArg) ![]u32{ - mut ids := []u32{} - for comment in args { - ids << comment_set(comment)! - } - return ids +pub fn comment_multiset(args []CommentArg) ![]u32 { + mut ids := []u32{} + for comment in args { + ids << comment_set(comment)! + } + return ids } -pub fn comment_set(args CommentArg) !u32{ - mut o := comment_new(args)! - // Use openrpcserver set function which now returns the ID - return openrpcserver.set[Comment](mut o)! +pub fn comment_set(args CommentArg) !u32 { + mut o := comment_new(args)! + // Use openrpcserver set function which now returns the ID + return set[Comment](mut o)! } -pub fn comment_exist(id u32) !bool{ - return openrpcserver.exists[Comment](id)! +pub fn comment_exist(id u32) !bool { + return exists[Comment](id)! } -pub fn comment_get(id u32) !Comment{ - return openrpcserver.get[Comment](id)! +pub fn comment_get(id u32) !Comment { + return get[Comment](id)! } diff --git a/lib/schemas/openrpcserver/core_methods.v b/lib/schemas/openrpcserver/core_methods.v index 6688c8a3..6709c347 100644 --- a/lib/schemas/openrpcserver/core_methods.v +++ b/lib/schemas/openrpcserver/core_methods.v @@ -3,55 +3,57 @@ module openrpcserver import freeflowuniverse.herolib.core.redisclient pub fn set[T](mut obj T) !u32 { - name := T{}.type_name() - mut redis := redisclient.core_get()! - - // Generate ID if not set - if obj.id == 0 { - myid := redis.incr("db:${name}:id")! - obj.id = u32(myid) - } - - data := obj.dump()! - redis.hset("db:${name}",obj.id.str(),data.bytestr())! - return obj.id + name := T{}.type_name() + mut redis := redisclient.core_get()! + + // Generate ID if not set + if obj.id == 0 { + myid := redis.incr('db:${name}:id')! + obj.id = u32(myid) + } + + data := obj.dump()! + redis.hset('db:${name}', obj.id.str(), data.bytestr())! + return obj.id } pub fn get[T](id u32) !T { - name := T{}.type_name() - mut redis := redisclient.core_get()! - data := redis.hget("db:${name}",id.str())! - if data.len > 0 { - return T{}.load(data.bytes())! - } else { - return error("Can't find ${name} with id: ${id}") - } + name := T{}.type_name() + mut redis := redisclient.core_get()! + data := redis.hget('db:${name}', id.str())! + if data.len > 0 { + return T{}.load(data.bytes())! + } else { + return error("Can't find ${name} with id: ${id}") + } } pub fn exists[T](id u32) !bool { - name := T{}.type_name() - mut redis := redisclient.core_get()! - return redis.hexists("db:${name}",id.str())! + name := T{}.type_name() + mut redis := redisclient.core_get()! + return redis.hexists('db:${name}', id.str())! } pub fn delete[T](id u32) ! { - name := T{}.type_name() - mut redis := redisclient.core_get()! - redis.hdel("db:${name}", id.str())! + name := T{}.type_name() + mut redis := redisclient.core_get()! + redis.hdel('db:${name}', id.str())! } pub fn list[T]() ![]T { - name := T{}.type_name() - mut redis := redisclient.core_get()! - all_data := redis.hgetall("db:${name}")! - mut result := []T{} - for _, data in all_data { - result << T{}.load(data.bytes())! - } - return result + name := T{}.type_name() + mut redis := redisclient.core_get()! + all_data := redis.hgetall('db:${name}')! + mut result := []T{} + for _, data in all_data { + result << T{}.load(data.bytes())! + } + return result } -//make it easy to get a base object +// make it easy to get a base object pub fn new_from_base[T](args BaseArgs) !Base { - return T { Base: new_base(args)! } -} \ No newline at end of file + return T{ + Base: new_base(args)! + } +} diff --git a/lib/schemas/openrpcserver/core_models.v b/lib/schemas/openrpcserver/core_models.v index ea51a2bb..8ce68fda 100644 --- a/lib/schemas/openrpcserver/core_models.v +++ b/lib/schemas/openrpcserver/core_models.v @@ -1,7 +1,6 @@ module openrpcserver import crypto.md5 - import freeflowuniverse.herolib.core.redisclient import freeflowuniverse.herolib.data.ourtime @@ -9,85 +8,83 @@ import freeflowuniverse.herolib.data.ourtime @[heap] pub struct Base { pub mut: - id u32 - name string - description string - created_at i64 - updated_at i64 - securitypolicy u32 - tags u32 //when we set/get we always do as []string but this can then be sorted and md5ed this gies the unique id of tags - comments []u32 + id u32 + name string + description string + created_at i64 + updated_at i64 + securitypolicy u32 + tags u32 // when we set/get we always do as []string but this can then be sorted and md5ed this gies the unique id of tags + comments []u32 } - + @[heap] pub struct SecurityPolicy { pub mut: - id u32 - read []u32 //links to users & groups - write []u32 //links to users & groups - delete []u32 //links to users & groups - public bool - md5 string //this sorts read, write and delete u32 + hash, then do md5 hash, this allows to go from a random read/write/delete/public config to a hash + id u32 + read []u32 // links to users & groups + write []u32 // links to users & groups + delete []u32 // links to users & groups + public bool + md5 string // this sorts read, write and delete u32 + hash, then do md5 hash, this allows to go from a random read/write/delete/public config to a hash } - @[heap] pub struct Tags { pub mut: - id u32 - names []string //unique per id - md5 string //of sorted names, to make easy to find unique id, each name lowercased and made ascii + id u32 + names []string // unique per id + md5 string // of sorted names, to make easy to find unique id, each name lowercased and made ascii } - ///////////////// @[params] pub struct BaseArgs { pub mut: - id ?u32 - name string - description string - securitypolicy ?u32 - tags []string - comments []CommentArg + id ?u32 + name string + description string + securitypolicy ?u32 + tags []string + comments []CommentArg } -//make it easy to get a base object +// make it easy to get a base object pub fn new_base(args BaseArgs) !Base { - mut redis := redisclient.core_get()! + mut redis := redisclient.core_get()! - commentids:=comment_multiset(args.comments)! - tags:=tags2id(args.tags)! + commentids := comment_multiset(args.comments)! + tags := tags2id(args.tags)! - return Base { - id: args.id or { 0 } - name: args.name - description: args.description - created_at: ourtime.now().unix() - updated_at: ourtime.now().unix() - securitypolicy: args.securitypolicy or { 0 } - tags: tags - comments: commentids - } + return Base{ + id: args.id or { 0 } + name: args.name + description: args.description + created_at: ourtime.now().unix() + updated_at: ourtime.now().unix() + securitypolicy: args.securitypolicy or { 0 } + tags: tags + comments: commentids + } } pub fn tags2id(tags []string) !u32 { - mut redis := redisclient.core_get()! - return if tags.len>0{ - mut tags_fixed := tags.map(it.to_lower_ascii().trim_space()).filter(it != "") - tags_fixed.sort_ignore_case() - hash :=md5.hexhash(tags_fixed.join(",")) - tags_found := redis.hget("db:tags", hash)! - return if tags_found == ""{ - id := u32(redis.incr("db:tags:id")!) - redis.hset("db:tags", hash, id.str())! - redis.hset("db:tags", id.str(), tags_fixed.join(","))! - id - }else{ - tags_found.u32() - } - } else { - 0 - } + mut redis := redisclient.core_get()! + return if tags.len > 0 { + mut tags_fixed := tags.map(it.to_lower_ascii().trim_space()).filter(it != '') + tags_fixed.sort_ignore_case() + hash := md5.hexhash(tags_fixed.join(',')) + tags_found := redis.hget('db:tags', hash)! + return if tags_found == '' { + id := u32(redis.incr('db:tags:id')!) + redis.hset('db:tags', hash, id.str())! + redis.hset('db:tags', id.str(), tags_fixed.join(','))! + id + } else { + tags_found.u32() + } + } else { + 0 + } } diff --git a/lib/schemas/openrpcserver/openrpc_server.v b/lib/schemas/openrpcserver/openrpc_server.v index 271c6259..1bedcad0 100644 --- a/lib/schemas/openrpcserver/openrpc_server.v +++ b/lib/schemas/openrpcserver/openrpc_server.v @@ -6,7 +6,7 @@ import net.unix import os import freeflowuniverse.herolib.ui.console -//THIS IS DEFAULT NEEDED FOR EACH OPENRPC SERVER WE MAKE +// THIS IS DEFAULT NEEDED FOR EACH OPENRPC SERVER WE MAKE pub struct JsonRpcRequest { pub: @@ -33,10 +33,9 @@ pub: data string } - pub struct RPCServer { pub mut: - listener &unix.StreamListener + listener &unix.StreamListener socket_path string } @@ -59,18 +58,18 @@ pub fn new_rpc_server(args RPCServerArgs) !&RPCServer { if os.exists(args.socket_path) { os.rm(args.socket_path)! } - + listener := unix.listen_stream(args.socket_path, unix.ListenOptions{})! - + return &RPCServer{ - listener: listener + listener: listener socket_path: args.socket_path } } pub fn (mut server RPCServer) start() ! { console.print_header('Starting HeroModels OpenRPC Server on ${server.socket_path}') - + for { mut conn := server.listener.accept()! spawn server.handle_connection(mut conn) @@ -88,7 +87,7 @@ fn (mut server RPCServer) handle_connection(mut conn unix.StreamConn) { defer { conn.close() or { console.print_stderr('Error closing connection: ${err}') } } - + for { // Read JSON-RPC request mut buffer := []u8{len: 4096} @@ -96,19 +95,19 @@ fn (mut server RPCServer) handle_connection(mut conn unix.StreamConn) { console.print_debug('Connection closed or error reading: ${err}') break } - + if bytes_read == 0 { break } - + request_data := buffer[..bytes_read].bytestr() console.print_debug('Received request: ${request_data}') - + // Process the JSON-RPC request response := server.process_request(request_data) or { server.create_error_response(-32603, 'Internal error: ${err}', 'null') } - + // Send response conn.write_string(response) or { console.print_stderr('Error writing response: ${err}') @@ -145,22 +144,22 @@ pub fn (mut server RPCServer) process(method string, params_str string) !string fn (mut server RPCServer) create_success_response(result string, id string) string { response := JsonRpcResponse{ jsonrpc: '2.0' - result: result - id: id + result: result + id: id } return json.encode(response) } fn (mut server RPCServer) create_error_response(code int, message string, id string) string { error := JsonRpcError{ - code: code + code: code message: message - data: 'null' + data: 'null' } response := JsonRpcResponse{ jsonrpc: '2.0' - error: error - id: id + error: error + id: id } return json.encode(response) } @@ -169,4 +168,4 @@ fn (mut server RPCServer) create_error_response(code int, message string, id str pub fn (mut server RPCServer) discover() !string { // Return a basic OpenRPC spec - should be overridden by implementations return '{"openrpc": "1.2.6", "info": {"title": "OpenRPC Server", "version": "1.0.0"}, "methods": []}' -} \ No newline at end of file +} diff --git a/lib/threefold/models/business/company.v b/lib/threefold/models/business/company.v index d59a29d4..ca420b0b 100644 --- a/lib/threefold/models/business/company.v +++ b/lib/threefold/models/business/company.v @@ -41,21 +41,21 @@ pub mut: // new creates a new Company with default values pub fn Company.new() Company { return Company{ - id: 0 - name: '' + id: 0 + name: '' registration_number: '' - incorporation_date: 0 - fiscal_year_end: '' - email: '' - phone: '' - website: '' - address: '' - business_type: .single - industry: '' - description: '' - status: .pending_payment - created_at: 0 - updated_at: 0 + incorporation_date: 0 + fiscal_year_end: '' + email: '' + phone: '' + website: '' + address: '' + business_type: .single + industry: '' + description: '' + status: .pending_payment + created_at: 0 + updated_at: 0 } } @@ -185,4 +185,4 @@ pub fn (c Company) status_string() string { .suspended { 'Suspended' } .inactive { 'Inactive' } } -} \ No newline at end of file +} diff --git a/lib/threefold/models/business/payment.v b/lib/threefold/models/business/payment.v index 0f39aad8..1b134e7e 100644 --- a/lib/threefold/models/business/payment.v +++ b/lib/threefold/models/business/payment.v @@ -34,19 +34,19 @@ pub mut: pub fn Payment.new(payment_intent_id string, company_id u32, payment_plan string, setup_fee f64, monthly_fee f64, total_amount f64) Payment { now := time.now().unix_time() return Payment{ - id: 0 - payment_intent_id: payment_intent_id - company_id: company_id - payment_plan: payment_plan - setup_fee: setup_fee - monthly_fee: monthly_fee - total_amount: total_amount - currency: 'usd' - status: .pending + id: 0 + payment_intent_id: payment_intent_id + company_id: company_id + payment_plan: payment_plan + setup_fee: setup_fee + monthly_fee: monthly_fee + total_amount: total_amount + currency: 'usd' + status: .pending stripe_customer_id: none - created_at: now - completed_at: none - updated_at: u64(now) + created_at: now + completed_at: none + updated_at: u64(now) } } @@ -195,4 +195,4 @@ pub fn (p Payment) is_yearly_plan() bool { // is_two_year_plan checks if this is a two-year payment plan pub fn (p Payment) is_two_year_plan() bool { return p.payment_plan == 'two_year' -} \ No newline at end of file +} diff --git a/lib/threefold/models/business/product.v b/lib/threefold/models/business/product.v index b03249af..f69da89d 100644 --- a/lib/threefold/models/business/product.v +++ b/lib/threefold/models/business/product.v @@ -23,9 +23,9 @@ pub mut: // new creates a new ProductComponent with default values pub fn ProductComponent.new() ProductComponent { return ProductComponent{ - name: '' + name: '' description: '' - quantity: 1 + quantity: 1 } } @@ -51,37 +51,37 @@ pub fn (mut pc ProductComponent) quantity(quantity u32) ProductComponent { @[heap] pub struct Product { pub mut: - id u32 // Unique product ID - name string // Product name - description string // Product description - price f64 // Product price - type_ ProductType // Product type (product or service) - category string // Product category - status ProductStatus // Product status - max_amount u16 // Maximum amount available - purchase_till i64 // Purchase deadline timestamp - active_till i64 // Active until timestamp - components []ProductComponent // Product components - created_at u64 // Creation timestamp - updated_at u64 // Last update timestamp + id u32 // Unique product ID + name string // Product name + description string // Product description + price f64 // Product price + type_ ProductType // Product type (product or service) + category string // Product category + status ProductStatus // Product status + max_amount u16 // Maximum amount available + purchase_till i64 // Purchase deadline timestamp + active_till i64 // Active until timestamp + components []ProductComponent // Product components + created_at u64 // Creation timestamp + updated_at u64 // Last update timestamp } // new creates a new Product with default values pub fn Product.new() Product { return Product{ - id: 0 - name: '' - description: '' - price: 0.0 - type_: .product - category: '' - status: .available - max_amount: 0 + id: 0 + name: '' + description: '' + price: 0.0 + type_: .product + category: '' + status: .available + max_amount: 0 purchase_till: 0 - active_till: 0 - components: [] - created_at: 0 - updated_at: 0 + active_till: 0 + components: [] + created_at: 0 + updated_at: 0 } } @@ -209,4 +209,4 @@ pub fn (p Product) status_string() string { .available { 'Available' } .unavailable { 'Unavailable' } } -} \ No newline at end of file +} diff --git a/lib/threefold/models/business/sale.v b/lib/threefold/models/business/sale.v index bc03980c..9de8fd43 100644 --- a/lib/threefold/models/business/sale.v +++ b/lib/threefold/models/business/sale.v @@ -10,22 +10,22 @@ pub enum SaleStatus { // SaleItem represents an individual item within a Sale pub struct SaleItem { pub mut: - product_id u32 // Product ID - name string // Denormalized product name at time of sale - quantity i32 // Quantity purchased - unit_price f64 // Price per unit at time of sale - subtotal f64 // Subtotal for this item - service_active_until ?i64 // Optional: For services, date until this specific purchased instance is active + product_id u32 // Product ID + name string // Denormalized product name at time of sale + quantity i32 // Quantity purchased + unit_price f64 // Price per unit at time of sale + subtotal f64 // Subtotal for this item + service_active_until ?i64 // Optional: For services, date until this specific purchased instance is active } // new creates a new SaleItem with default values pub fn SaleItem.new() SaleItem { return SaleItem{ - product_id: 0 - name: '' - quantity: 0 - unit_price: 0.0 - subtotal: 0.0 + product_id: 0 + name: '' + quantity: 0 + unit_price: 0.0 + subtotal: 0.0 service_active_until: none } } @@ -91,17 +91,17 @@ pub mut: // new creates a new Sale with default values pub fn Sale.new() Sale { return Sale{ - id: 0 - company_id: 0 - buyer_id: 0 + id: 0 + company_id: 0 + buyer_id: 0 transaction_id: 0 - total_amount: 0.0 - status: .pending - sale_date: 0 - items: [] - notes: '' - created_at: 0 - updated_at: 0 + total_amount: 0.0 + status: .pending + sale_date: 0 + items: [] + notes: '' + created_at: 0 + updated_at: 0 } } @@ -219,4 +219,4 @@ pub fn (s Sale) status_string() string { .completed { 'Completed' } .cancelled { 'Cancelled' } } -} \ No newline at end of file +} diff --git a/lib/threefold/models/core/comment.v b/lib/threefold/models/core/comment.v index a52321e4..a0618777 100644 --- a/lib/threefold/models/core/comment.v +++ b/lib/threefold/models/core/comment.v @@ -16,12 +16,12 @@ pub mut: // new creates a new Comment with default values pub fn Comment.new() Comment { return Comment{ - id: 0 - user_id: 0 - content: '' + id: 0 + user_id: 0 + content: '' parent_comment_id: none - created_at: 0 - updated_at: 0 + created_at: 0 + updated_at: 0 } } @@ -51,4 +51,4 @@ pub fn (c Comment) is_top_level() bool { // is_reply returns true if this is a reply to another comment pub fn (c Comment) is_reply() bool { return c.parent_comment_id != none -} \ No newline at end of file +} diff --git a/lib/threefold/models/finance/account.v b/lib/threefold/models/finance/account.v index 7cbda12e..ff35381c 100644 --- a/lib/threefold/models/finance/account.v +++ b/lib/threefold/models/finance/account.v @@ -4,31 +4,31 @@ module finance @[heap] pub struct Account { pub mut: - id u32 // Unique account ID - name string // Internal name of the account for the user - user_id u32 // User ID of the owner of the account - description string // Optional description of the account - ledger string // Describes the ledger/blockchain where the account is located - address string // Address of the account on the blockchain - pubkey string // Public key - assets []u32 // List of asset IDs in this account - created_at u64 // Creation timestamp - updated_at u64 // Last update timestamp + id u32 // Unique account ID + name string // Internal name of the account for the user + user_id u32 // User ID of the owner of the account + description string // Optional description of the account + ledger string // Describes the ledger/blockchain where the account is located + address string // Address of the account on the blockchain + pubkey string // Public key + assets []u32 // List of asset IDs in this account + created_at u64 // Creation timestamp + updated_at u64 // Last update timestamp } // new creates a new Account with default values pub fn Account.new() Account { return Account{ - id: 0 - name: '' - user_id: 0 + id: 0 + name: '' + user_id: 0 description: '' - ledger: '' - address: '' - pubkey: '' - assets: [] - created_at: 0 - updated_at: 0 + ledger: '' + address: '' + pubkey: '' + assets: [] + created_at: 0 + updated_at: 0 } } @@ -94,4 +94,4 @@ pub fn (a Account) has_asset(asset_id u32) bool { // remove_asset removes an asset from the account pub fn (mut a Account) remove_asset(asset_id u32) { a.assets = a.assets.filter(it != asset_id) -} \ No newline at end of file +} diff --git a/lib/threefold/models/finance/asset.v b/lib/threefold/models/finance/asset.v index 05c7e700..d3cb0eee 100644 --- a/lib/threefold/models/finance/asset.v +++ b/lib/threefold/models/finance/asset.v @@ -26,15 +26,15 @@ pub mut: // new creates a new Asset with default values pub fn Asset.new() Asset { return Asset{ - id: 0 - name: '' + id: 0 + name: '' description: '' - amount: 0.0 - address: '' - asset_type: .native - decimals: 18 - created_at: 0 - updated_at: 0 + amount: 0.0 + address: '' + asset_type: .native + decimals: 18 + created_at: 0 + updated_at: 0 } } @@ -81,7 +81,31 @@ pub fn (a Asset) formatted_amount() string { factor *= 10 } formatted_amount := (a.amount * factor).round() / factor - return '${formatted_amount:.${a.decimals}f}' + // Format with the specified number of decimal places + if a.decimals == 0 { + return '${formatted_amount:.0f}' + } else if a.decimals == 1 { + return '${formatted_amount:.1f}' + } else if a.decimals == 2 { + return '${formatted_amount:.2f}' + } else if a.decimals == 3 { + return '${formatted_amount:.3f}' + } else if a.decimals == 4 { + return '${formatted_amount:.4f}' + } else { + // For more than 4 decimals, use string manipulation + str_amount := formatted_amount.str() + if str_amount.contains('.') { + parts := str_amount.split('.') + if parts.len == 2 { + decimal_part := parts[1] + if decimal_part.len > a.decimals { + return '${parts[0]}.${decimal_part[..a.decimals]}' + } + } + } + return str_amount + } } // transfer_to transfers amount to another asset @@ -96,4 +120,4 @@ pub fn (mut a Asset) transfer_to(mut target Asset, amount f64) ! { a.amount -= amount target.amount += amount -} \ No newline at end of file +} diff --git a/lib/threefold/models/finance/marketplace.v b/lib/threefold/models/finance/marketplace.v index c1de5c8f..b8c2c0a7 100644 --- a/lib/threefold/models/finance/marketplace.v +++ b/lib/threefold/models/finance/marketplace.v @@ -40,10 +40,10 @@ pub mut: pub fn Bid.new() Bid { return Bid{ listing_id: '' - bidder_id: 0 - amount: 0.0 - currency: '' - status: .active + bidder_id: 0 + amount: 0.0 + currency: '' + status: .active created_at: u64(time.now().unix_time()) } } @@ -82,50 +82,50 @@ pub fn (mut b Bid) status(status BidStatus) Bid { @[heap] pub struct Listing { pub mut: - id u32 // Unique listing ID - title string // Title of the listing - description string // Description of the listing - asset_id string // ID of the asset being listed - asset_type AssetType // Type of the asset - seller_id string // ID of the user selling the asset - price f64 // Initial price for fixed price, or starting price for auction - currency string // Currency of the listing - listing_type ListingType // Type of listing (fixed_price, auction, exchange) - status ListingStatus // Status of the listing - expires_at ?u64 // Optional expiration date - sold_at ?u64 // Optional date when the item was sold - buyer_id ?string // Optional buyer ID - sale_price ?f64 // Optional final sale price - bids []Bid // List of bids for auction type listings - tags []string // Tags for the listing - image_url ?string // Optional image URL - created_at u64 // Creation timestamp - updated_at u64 // Last update timestamp + id u32 // Unique listing ID + title string // Title of the listing + description string // Description of the listing + asset_id string // ID of the asset being listed + asset_type AssetType // Type of the asset + seller_id string // ID of the user selling the asset + price f64 // Initial price for fixed price, or starting price for auction + currency string // Currency of the listing + listing_type ListingType // Type of listing (fixed_price, auction, exchange) + status ListingStatus // Status of the listing + expires_at ?u64 // Optional expiration date + sold_at ?u64 // Optional date when the item was sold + buyer_id ?string // Optional buyer ID + sale_price ?f64 // Optional final sale price + bids []Bid // List of bids for auction type listings + tags []string // Tags for the listing + image_url ?string // Optional image URL + created_at u64 // Creation timestamp + updated_at u64 // Last update timestamp } // new creates a new Listing with default values pub fn Listing.new() Listing { now := u64(time.now().unix_time()) return Listing{ - id: 0 - title: '' - description: '' - asset_id: '' - asset_type: .native - seller_id: '' - price: 0.0 - currency: '' + id: 0 + title: '' + description: '' + asset_id: '' + asset_type: .native + seller_id: '' + price: 0.0 + currency: '' listing_type: .fixed_price - status: .active - expires_at: none - sold_at: none - buyer_id: none - sale_price: none - bids: [] - tags: [] - image_url: none - created_at: now - updated_at: now + status: .active + expires_at: none + sold_at: none + buyer_id: none + sale_price: none + bids: [] + tags: [] + image_url: none + created_at: now + updated_at: now } } @@ -336,4 +336,4 @@ pub fn (mut l Listing) check_expiration() { pub fn (mut l Listing) add_tag(tag string) Listing { l.tags << tag return l -} \ No newline at end of file +} diff --git a/lib/threefold/models/flow/flow.v b/lib/threefold/models/flow/flow.v index 84c75bf0..8b9ea88a 100644 --- a/lib/threefold/models/flow/flow.v +++ b/lib/threefold/models/flow/flow.v @@ -4,13 +4,13 @@ module flow @[heap] pub struct Flow { pub mut: - id u32 // Unique flow ID - flow_uuid string // A unique UUID for the flow, for external reference - name string // Name of the flow - status string // Current status of the flow (e.g., "Pending", "InProgress", "Completed", "Failed") - steps []FlowStep // Steps involved in this flow - created_at u64 // Creation timestamp - updated_at u64 // Last update timestamp + id u32 // Unique flow ID + flow_uuid string // A unique UUID for the flow, for external reference + name string // Name of the flow + status string // Current status of the flow (e.g., "Pending", "InProgress", "Completed", "Failed") + steps []FlowStep // Steps involved in this flow + created_at u64 // Creation timestamp + updated_at u64 // Last update timestamp } // new creates a new Flow @@ -18,11 +18,11 @@ pub mut: // The ID is managed by the database pub fn Flow.new(flow_uuid string) Flow { return Flow{ - id: 0 - flow_uuid: flow_uuid - name: '' - status: 'Pending' - steps: [] + id: 0 + flow_uuid: flow_uuid + name: '' + status: 'Pending' + steps: [] created_at: 0 updated_at: 0 } @@ -71,7 +71,7 @@ pub fn (f Flow) is_completed() bool { if f.steps.len == 0 { return false } - + for step in f.steps { if step.status != 'Completed' { return false @@ -84,11 +84,11 @@ pub fn (f Flow) is_completed() bool { pub fn (f Flow) get_next_step() ?FlowStep { mut sorted_steps := f.steps.clone() sorted_steps.sort(a.step_order < b.step_order) - + for step in sorted_steps { if step.status == 'Pending' { return step } } return none -} \ No newline at end of file +} diff --git a/lib/threefold/models/flow/flow_step.v b/lib/threefold/models/flow/flow_step.v index f52d6045..31466dad 100644 --- a/lib/threefold/models/flow/flow_step.v +++ b/lib/threefold/models/flow/flow_step.v @@ -15,12 +15,12 @@ pub mut: // new creates a new flow step pub fn FlowStep.new(step_order u32) FlowStep { return FlowStep{ - id: 0 + id: 0 description: none - step_order: step_order - status: 'Pending' - created_at: 0 - updated_at: 0 + step_order: step_order + status: 'Pending' + created_at: 0 + updated_at: 0 } } @@ -74,4 +74,4 @@ pub fn (mut fs FlowStep) fail() { // reset resets the step to pending status pub fn (mut fs FlowStep) reset() { fs.status = 'Pending' -} \ No newline at end of file +} diff --git a/lib/threefold/models/flow/signature_requirement.v b/lib/threefold/models/flow/signature_requirement.v index c9b90a28..8ab6e654 100644 --- a/lib/threefold/models/flow/signature_requirement.v +++ b/lib/threefold/models/flow/signature_requirement.v @@ -18,15 +18,15 @@ pub mut: // new creates a new signature requirement pub fn SignatureRequirement.new(flow_step_id u32, public_key string, message string) SignatureRequirement { return SignatureRequirement{ - id: 0 + id: 0 flow_step_id: flow_step_id - public_key: public_key - message: message - signed_by: none - signature: none - status: 'Pending' - created_at: 0 - updated_at: 0 + public_key: public_key + message: message + signed_by: none + signature: none + status: 'Pending' + created_at: 0 + updated_at: 0 } } @@ -112,4 +112,4 @@ pub fn (sr SignatureRequirement) validate_signature() bool { } } return false -} \ No newline at end of file +} diff --git a/lib/threefold/models/identity/kyc.v b/lib/threefold/models/identity/kyc.v index 7789b96e..66b1b26b 100644 --- a/lib/threefold/models/identity/kyc.v +++ b/lib/threefold/models/identity/kyc.v @@ -3,45 +3,45 @@ module identity // IdenfyWebhookEvent represents an iDenfy webhook event structure pub struct IdenfyWebhookEvent { pub mut: - client_id string // Client ID - scan_ref string // Scan reference - status string // Verification status - platform string // Platform used - started_at string // When verification started - finished_at ?string // When verification finished (optional) - client_ip ?string // Client IP address (optional) - client_location ?string // Client location (optional) - data ?IdenfyVerificationData // Verification data (optional) + client_id string // Client ID + scan_ref string // Scan reference + status string // Verification status + platform string // Platform used + started_at string // When verification started + finished_at ?string // When verification finished (optional) + client_ip ?string // Client IP address (optional) + client_location ?string // Client location (optional) + data ?IdenfyVerificationData // Verification data (optional) } // IdenfyVerificationData represents the verification data from iDenfy pub struct IdenfyVerificationData { pub mut: - doc_first_name ?string // First name from document - doc_last_name ?string // Last name from document - doc_number ?string // Document number - doc_personal_code ?string // Personal code from document - doc_expiry ?string // Document expiry date - doc_dob ?string // Date of birth from document - doc_type ?string // Document type - doc_sex ?string // Sex from document - doc_nationality ?string // Nationality from document - doc_issuing_country ?string // Document issuing country - manually_data_changed ?bool // Whether data was manually changed + doc_first_name ?string // First name from document + doc_last_name ?string // Last name from document + doc_number ?string // Document number + doc_personal_code ?string // Personal code from document + doc_expiry ?string // Document expiry date + doc_dob ?string // Date of birth from document + doc_type ?string // Document type + doc_sex ?string // Sex from document + doc_nationality ?string // Nationality from document + doc_issuing_country ?string // Document issuing country + manually_data_changed ?bool // Whether data was manually changed } // new creates a new IdenfyWebhookEvent pub fn IdenfyWebhookEvent.new() IdenfyWebhookEvent { return IdenfyWebhookEvent{ - client_id: '' - scan_ref: '' - status: '' - platform: '' - started_at: '' - finished_at: none - client_ip: none + client_id: '' + scan_ref: '' + status: '' + platform: '' + started_at: '' + finished_at: none + client_ip: none client_location: none - data: none + data: none } } @@ -102,16 +102,16 @@ pub fn (mut event IdenfyWebhookEvent) data(data ?IdenfyVerificationData) IdenfyW // new creates a new IdenfyVerificationData pub fn IdenfyVerificationData.new() IdenfyVerificationData { return IdenfyVerificationData{ - doc_first_name: none - doc_last_name: none - doc_number: none - doc_personal_code: none - doc_expiry: none - doc_dob: none - doc_type: none - doc_sex: none - doc_nationality: none - doc_issuing_country: none + doc_first_name: none + doc_last_name: none + doc_number: none + doc_personal_code: none + doc_expiry: none + doc_dob: none + doc_type: none + doc_sex: none + doc_nationality: none + doc_issuing_country: none manually_data_changed: none } } @@ -220,4 +220,4 @@ pub fn (event IdenfyWebhookEvent) get_document_info() string { return '${doc_type}: ${doc_number}' } return 'No document information' -} \ No newline at end of file +} diff --git a/lib/threefold/models/legal/contract.v b/lib/threefold/models/legal/contract.v index 047428fb..4fb881cb 100644 --- a/lib/threefold/models/legal/contract.v +++ b/lib/threefold/models/legal/contract.v @@ -32,11 +32,11 @@ pub mut: // new creates a new ContractRevision pub fn ContractRevision.new(version u32, content string, created_by string) ContractRevision { return ContractRevision{ - version: version - content: content + version: version + content: content created_at: u64(time.now().unix_time()) created_by: created_by - comments: none + comments: none } } @@ -49,27 +49,27 @@ pub fn (mut cr ContractRevision) comments(comments string) ContractRevision { // ContractSigner represents a party involved in signing a contract pub struct ContractSigner { pub mut: - id string // Unique ID for the signer (UUID string) - name string // Signer's name - email string // Signer's email - status SignerStatus // Current status - signed_at ?u64 // When they signed (optional) - comments ?string // Optional comments from signer - last_reminder_mail_sent_at ?u64 // Last reminder timestamp - signature_data ?string // Base64 encoded signature image data + id string // Unique ID for the signer (UUID string) + name string // Signer's name + email string // Signer's email + status SignerStatus // Current status + signed_at ?u64 // When they signed (optional) + comments ?string // Optional comments from signer + last_reminder_mail_sent_at ?u64 // Last reminder timestamp + signature_data ?string // Base64 encoded signature image data } // new creates a new ContractSigner pub fn ContractSigner.new(id string, name string, email string) ContractSigner { return ContractSigner{ - id: id - name: name - email: email - status: .pending - signed_at: none - comments: none + id: id + name: name + email: email + status: .pending + signed_at: none + comments: none last_reminder_mail_sent_at: none - signature_data: none + signature_data: none } } @@ -139,48 +139,48 @@ pub fn (mut cs ContractSigner) sign(signature_data ?string, comments ?string) { @[heap] pub struct Contract { pub mut: - id u32 // Unique contract ID - contract_id string // Unique UUID for the contract - title string // Contract title - description string // Contract description - contract_type string // Type of contract - status ContractStatus // Current status - created_by string // Who created the contract - terms_and_conditions string // Terms and conditions text - start_date ?u64 // Optional start date - end_date ?u64 // Optional end date - renewal_period_days ?i32 // Optional renewal period in days - next_renewal_date ?u64 // Optional next renewal date - signers []ContractSigner // List of signers - revisions []ContractRevision // Contract revisions - current_version u32 // Current version number - last_signed_date ?u64 // Last signing date - created_at u64 // Creation timestamp - updated_at u64 // Last update timestamp + id u32 // Unique contract ID + contract_id string // Unique UUID for the contract + title string // Contract title + description string // Contract description + contract_type string // Type of contract + status ContractStatus // Current status + created_by string // Who created the contract + terms_and_conditions string // Terms and conditions text + start_date ?u64 // Optional start date + end_date ?u64 // Optional end date + renewal_period_days ?i32 // Optional renewal period in days + next_renewal_date ?u64 // Optional next renewal date + signers []ContractSigner // List of signers + revisions []ContractRevision // Contract revisions + current_version u32 // Current version number + last_signed_date ?u64 // Last signing date + created_at u64 // Creation timestamp + updated_at u64 // Last update timestamp } // new creates a new Contract pub fn Contract.new(contract_id string) Contract { now := u64(time.now().unix_time()) return Contract{ - id: 0 - contract_id: contract_id - title: '' - description: '' - contract_type: '' - status: .draft - created_by: '' + id: 0 + contract_id: contract_id + title: '' + description: '' + contract_type: '' + status: .draft + created_by: '' terms_and_conditions: '' - start_date: none - end_date: none - renewal_period_days: none - next_renewal_date: none - signers: [] - revisions: [] - current_version: 0 - last_signed_date: none - created_at: now - updated_at: now + start_date: none + end_date: none + renewal_period_days: none + next_renewal_date: none + signers: [] + revisions: [] + current_version: 0 + last_signed_date: none + created_at: now + updated_at: now } } @@ -331,7 +331,7 @@ pub fn (c Contract) all_signed() bool { if c.signers.len == 0 { return false } - + for signer in c.signers { if signer.status != .signed { return false @@ -370,4 +370,4 @@ pub fn (c Contract) status_string() string { .expired { 'Expired' } .cancelled { 'Cancelled' } } -} \ No newline at end of file +} diff --git a/lib/threefold/models/library/collection.v b/lib/threefold/models/library/collection.v index 5fe81dd2..8db135a9 100644 --- a/lib/threefold/models/library/collection.v +++ b/lib/threefold/models/library/collection.v @@ -4,31 +4,31 @@ module library @[heap] pub struct Collection { pub mut: - id u32 // Unique collection ID - title string // Title of the collection - description ?string // Optional description of the collection - images []u32 // List of image item IDs belonging to this collection - pdfs []u32 // List of PDF item IDs belonging to this collection - markdowns []u32 // List of Markdown item IDs belonging to this collection - books []u32 // List of Book item IDs belonging to this collection - slides []u32 // List of Slides item IDs belonging to this collection - created_at u64 // Creation timestamp - updated_at u64 // Last update timestamp + id u32 // Unique collection ID + title string // Title of the collection + description ?string // Optional description of the collection + images []u32 // List of image item IDs belonging to this collection + pdfs []u32 // List of PDF item IDs belonging to this collection + markdowns []u32 // List of Markdown item IDs belonging to this collection + books []u32 // List of Book item IDs belonging to this collection + slides []u32 // List of Slides item IDs belonging to this collection + created_at u64 // Creation timestamp + updated_at u64 // Last update timestamp } // new creates a new Collection with default values pub fn Collection.new() Collection { return Collection{ - id: 0 - title: '' + id: 0 + title: '' description: none - images: [] - pdfs: [] - markdowns: [] - books: [] - slides: [] - created_at: 0 - updated_at: 0 + images: [] + pdfs: [] + markdowns: [] + books: [] + slides: [] + created_at: 0 + updated_at: 0 } } @@ -162,4 +162,4 @@ pub fn (c Collection) contains_slides(slides_id u32) bool { // get_description_string returns the description as a string (empty if none) pub fn (c Collection) get_description_string() string { return c.description or { '' } -} \ No newline at end of file +} diff --git a/lib/threefold/models/library/items.v b/lib/threefold/models/library/items.v index d24b5d5e..228bd1ea 100644 --- a/lib/threefold/models/library/items.v +++ b/lib/threefold/models/library/items.v @@ -17,14 +17,14 @@ pub mut: // new creates a new Image with default values pub fn Image.new() Image { return Image{ - id: 0 - title: '' + id: 0 + title: '' description: none - url: '' - width: 0 - height: 0 - created_at: 0 - updated_at: 0 + url: '' + width: 0 + height: 0 + created_at: 0 + updated_at: 0 } } @@ -97,13 +97,13 @@ pub mut: // new creates a new Pdf with default values pub fn Pdf.new() Pdf { return Pdf{ - id: 0 - title: '' + id: 0 + title: '' description: none - url: '' - page_count: 0 - created_at: 0 - updated_at: 0 + url: '' + page_count: 0 + created_at: 0 + updated_at: 0 } } @@ -151,12 +151,12 @@ pub mut: // new creates a new Markdown document with default values pub fn Markdown.new() Markdown { return Markdown{ - id: 0 - title: '' + id: 0 + title: '' description: none - content: '' - created_at: 0 - updated_at: 0 + content: '' + created_at: 0 + updated_at: 0 } } @@ -200,8 +200,8 @@ pub mut: // new creates a new TocEntry with default values pub fn TocEntry.new() TocEntry { return TocEntry{ - title: '' - page: 0 + title: '' + page: 0 subsections: [] } } @@ -245,13 +245,13 @@ pub mut: // new creates a new Book with default values pub fn Book.new() Book { return Book{ - id: 0 - title: '' - description: none + id: 0 + title: '' + description: none table_of_contents: [] - pages: [] - created_at: 0 - updated_at: 0 + pages: [] + created_at: 0 + updated_at: 0 } } @@ -325,8 +325,8 @@ pub mut: // new creates a new Slide pub fn Slide.new() Slide { return Slide{ - image_url: '' - title: none + image_url: '' + title: none description: none } } @@ -374,12 +374,12 @@ pub mut: // new creates a new Slideshow with default values pub fn Slideshow.new() Slideshow { return Slideshow{ - id: 0 - title: '' + id: 0 + title: '' description: none - slides: [] - created_at: 0 - updated_at: 0 + slides: [] + created_at: 0 + updated_at: 0 } } @@ -424,4 +424,4 @@ pub fn (mut s Slideshow) remove_slide(index u32) { if index < u32(s.slides.len) { s.slides.delete(int(index)) } -} \ No newline at end of file +} diff --git a/lib/threefold/models/location/address.v b/lib/threefold/models/location/address.v index c157eb85..15e72850 100644 --- a/lib/threefold/models/location/address.v +++ b/lib/threefold/models/location/address.v @@ -14,12 +14,12 @@ pub mut: // new creates a new Address with default values pub fn Address.new() Address { return Address{ - street: '' - city: '' - state: none + street: '' + city: '' + state: none postal_code: '' - country: '' - company: none + country: '' + company: none } } @@ -77,57 +77,57 @@ pub fn (a Address) has_company() bool { // format_single_line returns the address formatted as a single line pub fn (a Address) format_single_line() string { mut parts := []string{} - + if company := a.company { if company.len > 0 { parts << company } } - + if a.street.len > 0 { parts << a.street } - + if a.city.len > 0 { parts << a.city } - + if state := a.state { if state.len > 0 { parts << state } } - + if a.postal_code.len > 0 { parts << a.postal_code } - + if a.country.len > 0 { parts << a.country } - + return parts.join(', ') } // format_multiline returns the address formatted as multiple lines pub fn (a Address) format_multiline() string { mut lines := []string{} - + if company := a.company { if company.len > 0 { lines << company } } - + if a.street.len > 0 { lines << a.street } - + mut city_line := '' if a.city.len > 0 { city_line = a.city } - + if state := a.state { if state.len > 0 { if city_line.len > 0 { @@ -137,7 +137,7 @@ pub fn (a Address) format_multiline() string { } } } - + if a.postal_code.len > 0 { if city_line.len > 0 { city_line += ' ${a.postal_code}' @@ -145,15 +145,15 @@ pub fn (a Address) format_multiline() string { city_line = a.postal_code } } - + if city_line.len > 0 { lines << city_line } - + if a.country.len > 0 { lines << a.country } - + return lines.join('\n') } @@ -169,22 +169,15 @@ pub fn (a Address) get_company_string() string { // equals compares two addresses for equality pub fn (a Address) equals(other Address) bool { - return a.street == other.street && - a.city == other.city && - a.state == other.state && - a.postal_code == other.postal_code && - a.country == other.country && - a.company == other.company + return a.street == other.street && a.city == other.city && a.state == other.state + && a.postal_code == other.postal_code && a.country == other.country + && a.company == other.company } // is_empty checks if the address is completely empty pub fn (a Address) is_empty() bool { - return a.street.len == 0 && - a.city.len == 0 && - a.postal_code.len == 0 && - a.country.len == 0 && - a.state == none && - a.company == none + return a.street.len == 0 && a.city.len == 0 && a.postal_code.len == 0 && a.country.len == 0 + && a.state == none && a.company == none } // validate performs basic validation on the address @@ -192,22 +185,22 @@ pub fn (a Address) validate() !bool { if a.is_empty() { return error('Address cannot be empty') } - + if a.street.len == 0 { return error('Street address is required') } - + if a.city.len == 0 { return error('City is required') } - + if a.postal_code.len == 0 { return error('Postal code is required') } - + if a.country.len == 0 { return error('Country is required') } - + return true -} \ No newline at end of file +} diff --git a/lib/threefold/models/models.v b/lib/threefold/models/models.v index edef8172..d6a1054b 100644 --- a/lib/threefold/models/models.v +++ b/lib/threefold/models/models.v @@ -9,11 +9,12 @@ module models // - Payment models (Stripe webhooks) // - Location models (addresses) -// Re-export all model modules for easy access -pub use core -pub use finance -pub use flow -pub use business -pub use identity -pub use payment -pub use location \ No newline at end of file +// Import all model modules for easy access + +import freeflowuniverse.herolib.threefold.models.core +import freeflowuniverse.herolib.threefold.models.finance +import freeflowuniverse.herolib.threefold.models.flow +import freeflowuniverse.herolib.threefold.models.business +import freeflowuniverse.herolib.threefold.models.identity +import freeflowuniverse.herolib.threefold.models.payment +import freeflowuniverse.herolib.threefold.models.location diff --git a/lib/threefold/models/payment/stripe.v b/lib/threefold/models/payment/stripe.v index 3210640e..4d191369 100644 --- a/lib/threefold/models/payment/stripe.v +++ b/lib/threefold/models/payment/stripe.v @@ -17,8 +17,8 @@ pub mut: // StripeEventData represents the data portion of a Stripe event pub struct StripeEventData { pub mut: - object string // The main object data (JSON as string for flexibility) - previous_attributes ?string // Previous attributes if this is an update (JSON as string) + object string // The main object data (JSON as string for flexibility) + previous_attributes ?string // Previous attributes if this is an update (JSON as string) } // StripeEventRequest represents request information for a Stripe event @@ -31,15 +31,15 @@ pub mut: // new creates a new StripeWebhookEvent pub fn StripeWebhookEvent.new() StripeWebhookEvent { return StripeWebhookEvent{ - id: '' - object: 'event' - api_version: none - created: 0 - data: StripeEventData.new() - livemode: false + id: '' + object: 'event' + api_version: none + created: 0 + data: StripeEventData.new() + livemode: false pending_webhooks: 0 - request: none - event_type: '' + request: none + event_type: '' } } @@ -100,7 +100,7 @@ pub fn (mut event StripeWebhookEvent) event_type(event_type string) StripeWebhoo // new creates a new StripeEventData pub fn StripeEventData.new() StripeEventData { return StripeEventData{ - object: '' + object: '' previous_attributes: none } } @@ -120,7 +120,7 @@ pub fn (mut data StripeEventData) previous_attributes(previous_attributes ?strin // new creates a new StripeEventRequest pub fn StripeEventRequest.new() StripeEventRequest { return StripeEventRequest{ - id: none + id: none idempotency_key: none } } @@ -219,4 +219,4 @@ pub fn (event StripeWebhookEvent) get_event_action() string { return parts[parts.len - 1] } return '' -} \ No newline at end of file +} diff --git a/lib/web/docusaurus/dsite_generate_docs.v b/lib/web/docusaurus/dsite_generate_docs.v index 9a9e6359..7ebb49ff 100644 --- a/lib/web/docusaurus/dsite_generate_docs.v +++ b/lib/web/docusaurus/dsite_generate_docs.v @@ -41,8 +41,8 @@ pub fn (mut docsite DocSite) generate_docs() ! { } if gen.errors.len > 0 { - println("Page List: is header collection and page name per collection.\nAvailable pages:\n${gen.client.list_markdown()!}") - return error('Errors occurred during site generation:\n${gen.errors.join('\n\n')}\n') + println('Page List: is header collection and page name per collection.\nAvailable pages:\n${gen.client.list_markdown()!}') + return error('Errors occurred during site generation:\n${gen.errors.join('\n\n')}\n') } }