chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1 del flow 0008 (kanban_cpp + agent_runner_api + DoD schema). Incluye: - dev/flows/0008-kanban-cpp-and-agent-workflows.md - dev/issues/0112-0119*.md (7 sub-issues) - WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+105
-3
@@ -303,18 +303,70 @@ func (db *DB) InsertApp(a *App) error {
|
||||
a.ID = GenerateID(a.Name, a.Lang, a.Domain)
|
||||
}
|
||||
|
||||
var (
|
||||
svcPort int
|
||||
svcHealth string
|
||||
svcHealthTO int
|
||||
svcUnit string
|
||||
svcScope string
|
||||
svcRestart string
|
||||
svcRuntime string
|
||||
svcLocalOnly int
|
||||
)
|
||||
if a.Service != nil {
|
||||
svcPort = a.Service.Port
|
||||
svcHealth = a.Service.HealthEndpoint
|
||||
svcHealthTO = a.Service.HealthTimeoutS
|
||||
svcUnit = a.Service.SystemdUnit
|
||||
svcScope = a.Service.SystemdScope
|
||||
svcRestart = a.Service.RestartPolicy
|
||||
svcRuntime = a.Service.Runtime
|
||||
if a.Service.IsLocalOnly {
|
||||
svcLocalOnly = 1
|
||||
}
|
||||
}
|
||||
|
||||
if a.Version == "" {
|
||||
a.Version = "0.1.0"
|
||||
}
|
||||
|
||||
_, err := db.conn.Exec(`
|
||||
INSERT OR REPLACE INTO apps (
|
||||
id, name, lang, domain, description, tags,
|
||||
uses_functions, uses_types, framework, entry_point,
|
||||
documentation, notes, dir_path, content_hash, created_at, updated_at, repo_url, project_id, uses_modules
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
documentation, notes, dir_path, content_hash, created_at, updated_at, repo_url, project_id, uses_modules,
|
||||
service_port, service_health_endpoint, service_health_timeout_s,
|
||||
service_systemd_unit, service_systemd_scope, service_restart_policy,
|
||||
service_runtime, service_is_local_only, version
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
a.ID, a.Name, a.Lang, a.Domain, a.Description, marshalStrings(a.Tags),
|
||||
marshalStrings(a.UsesFunctions), marshalStrings(a.UsesTypes), a.Framework, a.EntryPoint,
|
||||
a.Documentation, a.Notes, a.DirPath, a.ContentHash, a.CreatedAt.Format(time.RFC3339), a.UpdatedAt.Format(time.RFC3339),
|
||||
a.RepoURL, a.ProjectID, marshalStrings(a.UsesModules),
|
||||
svcPort, svcHealth, svcHealthTO, svcUnit, svcScope, svcRestart, svcRuntime, svcLocalOnly, a.Version,
|
||||
)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Replace service_targets for this app (idempotent).
|
||||
if _, err := db.conn.Exec("DELETE FROM service_targets WHERE app_id = ?", a.ID); err != nil {
|
||||
return fmt.Errorf("clearing service_targets for %s: %w", a.ID, err)
|
||||
}
|
||||
if a.Service != nil {
|
||||
for _, pc := range a.Service.PCTargets {
|
||||
if pc == "" {
|
||||
continue
|
||||
}
|
||||
if _, err := db.conn.Exec(
|
||||
"INSERT OR REPLACE INTO service_targets (app_id, pc_id, role) VALUES (?, ?, 'primary')",
|
||||
a.ID, pc,
|
||||
); err != nil {
|
||||
return fmt.Errorf("inserting service_target %s/%s: %w", a.ID, pc, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetApp returns a single app by ID.
|
||||
@@ -374,12 +426,16 @@ func scanApps(rows interface{ Next() bool; Scan(...any) error }) ([]App, error)
|
||||
var a App
|
||||
var tagsJSON, usesFnJSON, usesTypJSON, usesModJSON string
|
||||
var createdAt, updatedAt string
|
||||
var svcPort, svcHealthTO, svcLocalOnly int
|
||||
var svcHealth, svcUnit, svcScope, svcRestart, svcRuntime string
|
||||
|
||||
err := rows.Scan(
|
||||
&a.ID, &a.Name, &a.Lang, &a.Domain, &a.Description, &tagsJSON,
|
||||
&usesFnJSON, &usesTypJSON, &a.Framework, &a.EntryPoint,
|
||||
&a.Documentation, &a.Notes, &a.DirPath, &createdAt, &updatedAt, &a.ContentHash,
|
||||
&a.RepoURL, &a.ProjectID, &usesModJSON,
|
||||
&svcPort, &svcHealth, &svcHealthTO, &svcUnit, &svcScope, &svcRestart, &svcRuntime, &svcLocalOnly,
|
||||
&a.Version,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("scanning app: %w", err)
|
||||
@@ -392,11 +448,47 @@ func scanApps(rows interface{ Next() bool; Scan(...any) error }) ([]App, error)
|
||||
a.CreatedAt, _ = time.Parse(time.RFC3339, createdAt)
|
||||
a.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt)
|
||||
|
||||
if svcPort != 0 || svcHealth != "" || svcUnit != "" || svcScope != "" || svcRestart != "" || svcRuntime != "" || svcLocalOnly != 0 {
|
||||
a.Service = &ServiceSpec{
|
||||
Port: svcPort,
|
||||
HealthEndpoint: svcHealth,
|
||||
HealthTimeoutS: svcHealthTO,
|
||||
SystemdUnit: svcUnit,
|
||||
SystemdScope: svcScope,
|
||||
RestartPolicy: svcRestart,
|
||||
Runtime: svcRuntime,
|
||||
IsLocalOnly: svcLocalOnly != 0,
|
||||
}
|
||||
}
|
||||
|
||||
result = append(result, a)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetServicePCTargets returns the pc_ids declared in service_targets for an app.
|
||||
// Empty slice when the app has no declared targets. Issue 0105.
|
||||
func (db *DB) GetServicePCTargets(appID string) ([]string, error) {
|
||||
rows, err := db.conn.Query(
|
||||
"SELECT pc_id FROM service_targets WHERE app_id = ? ORDER BY pc_id",
|
||||
appID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var out []string
|
||||
for rows.Next() {
|
||||
var pc string
|
||||
if err := rows.Scan(&pc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, pc)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Purge deletes all data from functions, types, apps, analysis, projects, vaults and modules. Used before re-indexing.
|
||||
func (db *DB) Purge() error {
|
||||
if _, err := db.conn.Exec("DELETE FROM functions"); err != nil {
|
||||
@@ -408,6 +500,9 @@ func (db *DB) Purge() error {
|
||||
if _, err := db.conn.Exec("DELETE FROM apps"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.conn.Exec("DELETE FROM service_targets"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.conn.Exec("DELETE FROM analysis"); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -435,11 +530,18 @@ func (db *DB) PurgeLocalOnly(localAppIDs, localAnalysisIDs, localProjectIDs map[
|
||||
if _, err := db.conn.Exec("DELETE FROM apps WHERE id = ?", id); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.conn.Exec("DELETE FROM service_targets WHERE app_id = ?", id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Delete apps without repo_url (legacy local-only apps not yet pushed)
|
||||
if _, err := db.conn.Exec("DELETE FROM apps WHERE repo_url = '' OR repo_url IS NULL"); err != nil {
|
||||
return err
|
||||
}
|
||||
// Orphan service_targets cleanup
|
||||
if _, err := db.conn.Exec("DELETE FROM service_targets WHERE app_id NOT IN (SELECT id FROM apps)"); err != nil {
|
||||
return err
|
||||
}
|
||||
// Same for analysis
|
||||
for id := range localAnalysisIDs {
|
||||
if _, err := db.conn.Exec("DELETE FROM analysis WHERE id = ?", id); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user