turash/bugulma/backend/internal/graph/node_converter.go
Damir Mukimov 000eab4740
Major repository reorganization and missing backend endpoints implementation
Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools

Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
  * GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
  * GET /api/v1/users/me/organizations - User organizations
  * POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue

API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules

Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
2025-11-25 06:01:16 +01:00

118 lines
2.5 KiB
Go

package graph
import (
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
)
// NodeConverter converts Neo4j nodes and relationships to domain types
type NodeConverter struct{}
// NewNodeConverter creates a new node converter
func NewNodeConverter() *NodeConverter {
return &NodeConverter{}
}
// ConvertNode converts a Neo4j node to PathNode
func (nc *NodeConverter) ConvertNode(node neo4j.Node) PathNode {
return PathNode{
ID: getStringProp(node.Props, "id"),
Labels: node.Labels,
Properties: node.Props,
}
}
// ConvertRelationship converts a Neo4j relationship to PathRelationship
func (nc *NodeConverter) ConvertRelationship(rel neo4j.Relationship) PathRelationship {
return PathRelationship{
ID: rel.ElementId,
Type: rel.Type,
Properties: rel.Props,
}
}
// ConvertNodes converts a slice of Neo4j nodes to PathNodes
func (nc *NodeConverter) ConvertNodes(nodes []interface{}) []PathNode {
result := make([]PathNode, 0, len(nodes))
for _, node := range nodes {
if n, ok := node.(neo4j.Node); ok {
result = append(result, nc.ConvertNode(n))
}
}
return result
}
// ConvertRelationships converts a slice of Neo4j relationships to PathRelationships
func (nc *NodeConverter) ConvertRelationships(rels []interface{}) []PathRelationship {
result := make([]PathRelationship, 0, len(rels))
for _, rel := range rels {
if r, ok := rel.(neo4j.Relationship); ok {
result = append(result, nc.ConvertRelationship(r))
}
}
return result
}
// Helper functions for property extraction
func getStringProp(props map[string]interface{}, key string) string {
if val, ok := props[key]; ok && val != nil {
if str, ok := val.(string); ok {
return str
}
}
return ""
}
func getFloat64Prop(props map[string]interface{}, key string) float64 {
if val, ok := props[key]; ok && val != nil {
switch v := val.(type) {
case float64:
return v
case int64:
return float64(v)
case int:
return float64(v)
}
}
return 0.0
}
func getStringValue(val interface{}) string {
if val == nil {
return ""
}
if str, ok := val.(string); ok {
return str
}
return ""
}
func getFloat64Value(val interface{}) float64 {
if val == nil {
return 0.0
}
switch v := val.(type) {
case float64:
return v
case int64:
return float64(v)
case int:
return float64(v)
}
return 0.0
}
func getIntValue(val interface{}) int {
if val == nil {
return 0
}
switch v := val.(type) {
case int64:
return int(v)
case int:
return v
case float64:
return int(v)
}
return 0
}