package main import ( "encoding/json" "fmt" "inou/lib" "os" "time" ) const dossierID = "63d5df76904b1ec5" // Anastasiia const eventTag = "events-2026-01-24" // Maps event type to category var typeToCategory = map[string]int{ "procedure": lib.CategorySurgery, "surgery": lib.CategorySurgery, "medication": lib.CategoryMedication, "hospitalization": lib.CategoryHospital, "lab": lib.CategoryLab, "vital": lib.CategoryVital, "symptom": lib.CategorySymptom, "therapy": lib.CategoryTherapy, "vaccination": lib.CategoryHistory, // no specific category "milestone": lib.CategoryHistory, // no specific category yet "device": lib.CategorySurgery, // device implant is surgical } type DocData struct { Events []map[string]interface{} `json:"events"` Assessments []map[string]interface{} `json:"assessments"` Attributes map[string]interface{} `json:"attributes"` Content string `json:"content"` } func main() { if err := lib.CryptoInit("/tank/inou/master.key"); err != nil { fmt.Fprintf(os.Stderr, "CryptoInit: %v\n", err) os.Exit(1) } if err := lib.DBInit("/tank/inou/data/inou.db"); err != nil { fmt.Fprintf(os.Stderr, "DBInit: %v\n", err) os.Exit(1) } // Check for --delete flag if len(os.Args) > 1 && os.Args[1] == "--delete" { deleteEvents() return } // Get all document entries for Anastasiia docs, err := lib.EntryQuery(dossierID, lib.CategoryDocument, "") if err != nil { fmt.Fprintf(os.Stderr, "Query: %v\n", err) os.Exit(1) } fmt.Printf("Found %d documents\n\n", len(docs)) totalEvents := 0 totalAssessments := 0 for _, doc := range docs { fmt.Printf("Processing: %s\n", doc.Value) var data DocData if err := json.Unmarshal([]byte(doc.Data), &data); err != nil { fmt.Fprintf(os.Stderr, " Parse error: %v\n", err) continue } // Create entries for events for _, event := range data.Events { if err := createEventEntry(doc.EntryID, event); err != nil { fmt.Fprintf(os.Stderr, " Event error: %v\n", err) continue } totalEvents++ } // Create entries for assessments for _, assessment := range data.Assessments { if err := createAssessmentEntry(doc.EntryID, assessment); err != nil { fmt.Fprintf(os.Stderr, " Assessment error: %v\n", err) continue } totalAssessments++ } fmt.Printf(" %d events, %d assessments\n", len(data.Events), len(data.Assessments)) } fmt.Printf("\nTotal: %d events, %d assessments created\n", totalEvents, totalAssessments) } func createEventEntry(sourceID string, event map[string]interface{}) error { eventType, _ := event["type"].(string) what, _ := event["what"].(string) when, _ := event["when"].(string) where, _ := event["where"].(string) details, _ := event["details"].(string) // Determine category category := lib.CategoryHistory // default if cat, ok := typeToCategory[eventType]; ok { category = cat } // Parse date var timestamp int64 if when != "" { if t, err := time.Parse("2006-01-02", when); err == nil { timestamp = t.Unix() } else if t, err := time.Parse("2006-01", when); err == nil { timestamp = t.Unix() } else if t, err := time.Parse("2006", when); err == nil { timestamp = t.Unix() } } // Build data - include source document as reference (not parent) data := map[string]interface{}{ "where": where, "details": details, "source_id": sourceID, // reference to source document } dataJSON, _ := json.Marshal(data) entry := lib.Entry{ EntryID: lib.NewID(), DossierID: dossierID, ParentID: "", // ROOT level - event is the primary entity Category: category, Type: eventType, Value: what, Timestamp: timestamp, Tags: eventTag, Data: string(dataJSON), } return lib.EntryWrite("", &entry) } func createAssessmentEntry(sourceID string, assessment map[string]interface{}) error { by, _ := assessment["by"].(string) states, _ := assessment["states"].(string) // Include source document as reference (not parent) data := map[string]interface{}{ "provider": by, "source_id": sourceID, // reference to source document } dataJSON, _ := json.Marshal(data) entry := lib.Entry{ EntryID: lib.NewID(), DossierID: dossierID, ParentID: "", // ROOT level - assessment is the primary entity Category: lib.CategoryAssessment, Type: "clinical_opinion", Value: states, Summary: fmt.Sprintf("По мнению %s", by), // "According to [provider]" Tags: eventTag, Data: string(dataJSON), } return lib.EntryWrite("", &entry) } func deleteEvents() { fmt.Println("Deleting entries with tag:", eventTag) entries, err := lib.EntryQuery(dossierID, -1, "") if err != nil { fmt.Fprintf(os.Stderr, "Query: %v\n", err) os.Exit(1) } var toDelete []lib.Entry for _, e := range entries { if e.Tags != "" && e.Tags == eventTag { toDelete = append(toDelete, *e) } } fmt.Printf("Found %d entries to delete\n", len(toDelete)) for _, e := range toDelete { if err := lib.EntryDelete("", dossierID, &lib.Filter{EntryID: e.EntryID}); err != nil { fmt.Fprintf(os.Stderr, "Delete %s: %v\n", e.EntryID, err) } } fmt.Println("Done") }