package store import ( "database/sql" "errors" "time" core "agent-system-core" ) var ErrNotFound = errors.New("store: not found") // ---- 项目与会话 ---- func (s *Store) CreateProject(name string) (core.Project, error) { p := core.Project{ID: newID("prj"), Name: name, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), Settings: map[string]any{}} _, err := s.db.Exec(`INSERT INTO projects(id,name,settings,created_at,updated_at) VALUES(?,?,?,?,?)`, p.ID, p.Name, "{}", nowISO(), nowISO()) return p, err } func (s *Store) ListProjects() ([]core.Project, error) { rows, err := s.db.Query(`SELECT id,name,settings,created_at,updated_at FROM projects ORDER BY updated_at DESC`) if err != nil { return nil, err } defer rows.Close() var out []core.Project for rows.Next() { var p core.Project var settings string var ca, ua string if err := rows.Scan(&p.ID, &p.Name, &settings, &ca, &ua); err != nil { return nil, err } p.CreatedAt, _ = time.Parse(time.RFC3339Nano, ca) p.UpdatedAt, _ = time.Parse(time.RFC3339Nano, ua) if settings != "" && settings != "{}" { p.Settings, _ = unmarshalJSON[map[string]any](settings) } out = append(out, p) } return out, rows.Err() } func (s *Store) GetProject(id string) (core.Project, error) { var p core.Project var settings, ca, ua string err := s.db.QueryRow(`SELECT id,name,settings,created_at,updated_at FROM projects WHERE id=?`, id). Scan(&p.ID, &p.Name, &settings, &ca, &ua) if errors.Is(err, sql.ErrNoRows) { return p, ErrNotFound } if err != nil { return p, err } p.CreatedAt, _ = time.Parse(time.RFC3339Nano, ca) p.UpdatedAt, _ = time.Parse(time.RFC3339Nano, ua) if settings != "" && settings != "{}" { p.Settings, _ = unmarshalJSON[map[string]any](settings) } return p, nil } func (s *Store) UpdateProjectSettings(id string, values map[string]any) error { cur, err := s.GetProject(id) if err != nil { return err } merged := core.MergeSettings(cur.Settings, values) _, err = s.db.Exec(`UPDATE projects SET settings=?, updated_at=? WHERE id=?`, marshalJSON(merged), nowISO(), id) return err } func (s *Store) RenameProject(id, name string) error { _, err := s.db.Exec(`UPDATE projects SET name=?, updated_at=? WHERE id=?`, name, nowISO(), id) return err } func (s *Store) DeleteProject(id string) error { _, err := s.db.Exec(`DELETE FROM projects WHERE id=?`, id) return err } func (s *Store) CreateConversation(projectID, title, profileID string) (core.Conversation, error) { c := core.Conversation{ID: newID("cnv"), ProjectID: projectID, Title: title, ProfileID: profileID, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC()} _, err := s.db.Exec(`INSERT INTO conversations(id,project_id,title,profile_id,created_at,updated_at) VALUES(?,?,?,?,?,?)`, c.ID, c.ProjectID, c.Title, c.ProfileID, nowISO(), nowISO()) return c, err } func (s *Store) ListConversations(projectID string) ([]core.Conversation, error) { rows, err := s.db.Query(`SELECT id,project_id,title,profile_id,created_at,updated_at FROM conversations WHERE project_id=? ORDER BY updated_at DESC`, projectID) if err != nil { return nil, err } defer rows.Close() var out []core.Conversation for rows.Next() { var c core.Conversation var ca, ua string if err := rows.Scan(&c.ID, &c.ProjectID, &c.Title, &c.ProfileID, &ca, &ua); err != nil { return nil, err } c.CreatedAt, _ = time.Parse(time.RFC3339Nano, ca) c.UpdatedAt, _ = time.Parse(time.RFC3339Nano, ua) out = append(out, c) } return out, rows.Err() } func (s *Store) GetConversation(id string) (core.Conversation, error) { var c core.Conversation var ca, ua string err := s.db.QueryRow(`SELECT id,project_id,title,profile_id,created_at,updated_at FROM conversations WHERE id=?`, id). Scan(&c.ID, &c.ProjectID, &c.Title, &c.ProfileID, &ca, &ua) if errors.Is(err, sql.ErrNoRows) { return c, ErrNotFound } if err != nil { return c, err } c.CreatedAt, _ = time.Parse(time.RFC3339Nano, ca) c.UpdatedAt, _ = time.Parse(time.RFC3339Nano, ua) return c, nil } func (s *Store) TouchConversation(id string) { s.db.Exec(`UPDATE conversations SET updated_at=? WHERE id=?`, nowISO(), id) } func (s *Store) UpdateConversation(id, title, profileID string) error { if title == "" { _, err := s.db.Exec(`UPDATE conversations SET profile_id=?, updated_at=? WHERE id=?`, profileID, nowISO(), id) return err } _, err := s.db.Exec(`UPDATE conversations SET title=?, profile_id=?, updated_at=? WHERE id=?`, title, profileID, nowISO(), id) return err } func (s *Store) DeleteConversation(id string) error { _, err := s.db.Exec(`DELETE FROM conversations WHERE id=?`, id) return err }