feat(tools): add maintenance and meal planning tools with CRUD operations

- Implement maintenance tool for adding, logging, and retrieving tasks
- Create meals tool for managing recipes, meal plans, and shopping lists
- Introduce reparse metadata tool for updating thought metadata
- Add household knowledge, home maintenance, family calendar, meal planning, and professional CRM database migrations
- Grant necessary permissions for new database tables
This commit is contained in:
2026-03-26 23:29:03 +02:00
parent b74d63c543
commit 0eb6ac7ee5
25 changed files with 2910 additions and 10 deletions

View File

@@ -428,6 +428,57 @@ func (db *DB) ListThoughtsMissingEmbedding(ctx context.Context, model string, li
return thoughts, nil
}
func (db *DB) ListThoughtsForMetadataReparse(ctx context.Context, limit int, projectID *uuid.UUID, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
args := make([]any, 0, 3)
conditions := make([]string, 0, 4)
if !includeArchived {
conditions = append(conditions, "archived_at is null")
}
if projectID != nil {
args = append(args, *projectID)
conditions = append(conditions, fmt.Sprintf("project_id = $%d", len(args)))
}
if olderThanDays > 0 {
args = append(args, time.Now().Add(-time.Duration(olderThanDays)*24*time.Hour))
conditions = append(conditions, fmt.Sprintf("created_at < $%d", len(args)))
}
args = append(args, limit)
query := `
select guid, content, metadata, project_id, archived_at, created_at, updated_at
from thoughts
`
if len(conditions) > 0 {
query += " where " + strings.Join(conditions, " and ")
}
query += " order by created_at asc limit $" + fmt.Sprintf("%d", len(args))
rows, err := db.pool.Query(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("list thoughts for metadata reparse: %w", err)
}
defer rows.Close()
thoughts := make([]thoughttypes.Thought, 0, limit)
for rows.Next() {
var thought thoughttypes.Thought
var metadataBytes []byte
if err := rows.Scan(&thought.ID, &thought.Content, &metadataBytes, &thought.ProjectID, &thought.ArchivedAt, &thought.CreatedAt, &thought.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan metadata-reparse thought: %w", err)
}
if err := json.Unmarshal(metadataBytes, &thought.Metadata); err != nil {
return nil, fmt.Errorf("decode metadata-reparse thought metadata: %w", err)
}
thoughts = append(thoughts, thought)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate metadata-reparse thoughts: %w", err)
}
return thoughts, nil
}
func (db *DB) UpsertEmbedding(ctx context.Context, thoughtID uuid.UUID, model string, embedding []float32) error {
_, err := db.pool.Exec(ctx, `
insert into embeddings (thought_id, model, dim, embedding)