feat: Add tags model and handler

- Add DBTags struct and methods
- Add tags_handle function for RPC calls
- Integrate tags into ModelsFactory and handler dispatch
This commit is contained in:
Mahmoud-Emad
2025-10-07 13:25:25 +03:00
parent 479068587d
commit c29678b303
2 changed files with 157 additions and 32 deletions

View File

@@ -17,20 +17,21 @@ __global (
@[heap]
pub struct ModelsFactory {
pub mut:
calendar DBCalendar
calendar_event DBCalendarEvent
group DBGroup
user DBUser
project DBProject
project_issue DBProjectIssue
chat_group DBChatGroup
chat_message DBChatMessage
contact DBContact
profile DBProfile
planning DBPlanning
calendar DBCalendar
calendar_event DBCalendarEvent
group DBGroup
user DBUser
project DBProject
project_issue DBProjectIssue
chat_group DBChatGroup
chat_message DBChatMessage
contact DBContact
profile DBProfile
planning DBPlanning
registration_desk DBRegistrationDesk
messages DBMessages
rpc_handler &Handler
messages DBMessages
tags DBTags
rpc_handler &Handler
}
@[params]
@@ -48,46 +49,49 @@ pub fn new(args NewArgs) !&ModelsFactory {
}
mut h := new_handler(openrpc_path)!
mut f := ModelsFactory{
calendar: DBCalendar{
calendar: DBCalendar{
db: &mydb
}
calendar_event: DBCalendarEvent{
calendar_event: DBCalendarEvent{
db: &mydb
}
group: DBGroup{
group: DBGroup{
db: &mydb
}
user: DBUser{
user: DBUser{
db: &mydb
}
project: DBProject{
project: DBProject{
db: &mydb
}
project_issue: DBProjectIssue{
project_issue: DBProjectIssue{
db: &mydb
}
chat_group: DBChatGroup{
chat_group: DBChatGroup{
db: &mydb
}
chat_message: DBChatMessage{
chat_message: DBChatMessage{
db: &mydb
}
contact: DBContact{
contact: DBContact{
db: &mydb
}
profile: DBProfile{
profile: DBProfile{
db: &mydb
}
planning: DBPlanning{
planning: DBPlanning{
db: &mydb
}
registration_desk: DBRegistrationDesk{
db: &mydb
}
messages: DBMessages{
messages: DBMessages{
db: &mydb
}
rpc_handler: &h
tags: DBTags{
db: &mydb
}
rpc_handler: &h
}
// openrpc handler can be used by any server, has even embedded unix sockets and simple http server
@@ -123,13 +127,16 @@ pub fn group_api_handler(rpcid int, servercontext map[string]string, actorname s
return calendar_handle(mut f, rpcid, servercontext, userref, methodname, params)!
}
'calendar_event' {
return calendar_event_handle(mut f, rpcid, servercontext, userref, methodname, params)!
return calendar_event_handle(mut f, rpcid, servercontext, userref, methodname,
params)!
}
'chat_group' {
return chat_group_handle(mut f, rpcid, servercontext, userref, methodname, params)!
return chat_group_handle(mut f, rpcid, servercontext, userref, methodname,
params)!
}
'chat_message' {
return chat_message_handle(mut f, rpcid, servercontext, userref, methodname, params)!
return chat_message_handle(mut f, rpcid, servercontext, userref, methodname,
params)!
}
'group' {
return group_handle(mut f, rpcid, servercontext, userref, methodname, params)!
@@ -138,7 +145,8 @@ pub fn group_api_handler(rpcid int, servercontext map[string]string, actorname s
return project_handle(mut f, rpcid, servercontext, userref, methodname, params)!
}
'project_issue' {
return project_issue_handle(mut f, rpcid, servercontext, userref, methodname, params)!
return project_issue_handle(mut f, rpcid, servercontext, userref, methodname,
params)!
}
'user' {
return user_handle(mut f, rpcid, servercontext, userref, methodname, params)!
@@ -153,11 +161,15 @@ pub fn group_api_handler(rpcid int, servercontext map[string]string, actorname s
return planning_handle(mut f, rpcid, servercontext, userref, methodname, params)!
}
'registration_desk' {
return registration_desk_handle(mut f, rpcid, servercontext, userref, methodname, params)!
return registration_desk_handle(mut f, rpcid, servercontext, userref, methodname,
params)!
}
'message' {
return message_handle(mut f, rpcid, servercontext, userref, methodname, params)!
}
'tags' {
return tags_handle(mut f, rpcid, servercontext, userref, methodname, params)!
}
else {
return jsonrpc.new_error(rpcid,
code: 32111
@@ -166,4 +178,4 @@ pub fn group_api_handler(rpcid int, servercontext map[string]string, actorname s
)
}
}
}
}

113
lib/hero/heromodels/tags.v Normal file
View File

@@ -0,0 +1,113 @@
module heromodels
import freeflowuniverse.herolib.hero.db
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_true }
import freeflowuniverse.herolib.hero.user { UserRef }
import json
// Tags represents a collection of tag names with a unique ID
// This is the same as db.Tags but in the heromodels context
pub type Tags = db.Tags
pub fn (self Tags) type_name() string {
return 'tags'
}
// return example rpc call and result for each methodname
pub fn (self Tags) example(methodname string) (string, string) {
match methodname {
'get' {
return '{"id": 1}', '{"id": 1, "names": ["development", "urgent", "team"], "md5": "abc123def456"}'
}
else {
return '{}', '{}'
}
}
}
pub struct DBTags {
pub mut:
db &db.DB @[skip; str: skip]
}
pub fn (mut self DBTags) get(id u32) !Tags {
if id == 0 {
return error('Tags ID cannot be 0')
}
// Get the full Tags entity to include md5
tags_json := self.db.redis.hget('db:tags', id.str())!
if tags_json == '' {
return error('Tags entity not found for ID: ${id}')
}
// Decode Tags entity
tags_entity := json.decode(Tags, tags_json)!
return tags_entity
}
pub fn (mut self DBTags) exist(id u32) !bool {
if id == 0 {
return false
}
tags_json := self.db.redis.hget('db:tags', id.str()) or { '' }
return tags_json != ''
}
pub fn (mut self DBTags) delete(id u32) !bool {
if id == 0 {
return false
}
// Get the Tags entity first to get the md5 hash
tags_json := self.db.redis.hget('db:tags', id.str()) or { '' }
if tags_json == '' {
return false // Already doesn't exist
}
tags_entity := json.decode(Tags, tags_json)!
// Delete from both hash tables
self.db.redis.hdel('db:tags', id.str())!
self.db.redis.hdel('db:tags_hash', tags_entity.md5)!
return true
}
pub fn tags_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
match method {
'get' {
id := db.decode_u32(params)!
res := f.tags.get(id)!
return new_response(rpcid, json.encode(res))
}
'exist' {
id := db.decode_u32(params)!
exists := f.tags.exist(id)!
if exists {
return new_response_true(rpcid)
} else {
return new_response_false(rpcid)
}
}
'delete' {
id := db.decode_u32(params)!
deleted := f.tags.delete(id)!
if deleted {
return new_response_true(rpcid)
} else {
return new_error(rpcid,
code: 404
message: 'Tags with ID ${id} not found'
)
}
}
else {
return new_error(rpcid,
code: -32601
message: 'Method not found: ${method}'
)
}
}
}