#pragma once #include #include // Sistema de proyectos: cada proyecto es una subcarpeta junto al exe que // contiene sus propios `operations.db`, `types.yaml` y `graph_explorer.db` // (layouts). El usuario crea proyectos, los nombra y conmuta entre ellos. // // Layout en disco (issue: convencion local_files): // // / // graph_explorer.exe // enrichers/, runtime/, *.ttf, ... (read-only, distribuibles) // local_files/ (escribibles, per-PC) // imgui.ini, app_settings.ini (gestionados por fn_framework) // graph_explorer.ini # last_active + recent // projects/ // default/ // operations.db // types.yaml // graph_explorer.db # layouts del proyecto // caso_X/ // ... namespace ge { // Helpers que resuelven a /local_files/... via fn::local_path. // Las constantes solo guardan el basename relativo a local_files/. constexpr const char* k_projects_subdir = "projects"; constexpr const char* k_default_project = "default"; constexpr const char* k_settings_basename = "graph_explorer.ini"; // Devuelven paths absolutos resueltos contra local_files/ (creando la // carpeta si no existe). Sustituyen el uso directo de los constexpr. const char* projects_root(); // /local_files/projects const char* settings_path(); // /local_files/graph_explorer.ini struct ProjectPaths { std::string root_dir; // /projects// std::string operations_db; // /operations.db std::string types_yaml; // /types.yaml std::string layout_db; // /graph_explorer.db }; // Valida slug (a-z, 0-9, _ y -). Devuelve true si es valido. error_msg // describe el motivo del fallo. bool project_validate_slug(const char* name, std::string* error_msg); // Devuelve los paths del proyecto `slug`. NO comprueba existencia en disco. ProjectPaths project_paths(const char* slug); // Asegura que `/projects/` existe. Idempotente. bool projects_root_ensure(); // Lista proyectos detectados (subdirs de `/projects/`). Ordenado alfa. // Cada string es el slug (basename de la subcarpeta). bool project_list(std::vector* out); // Devuelve true si la carpeta del proyecto existe y contiene operations.db. bool project_exists(const char* slug); // Crea el proyecto `slug`: // - mkdir /projects// // - bootstrap operations.db con el DDL completo (entities, relations, fts, ...) // - escribe types.yaml semilla (basado en examples/types.yaml o embed) // Devuelve false y rellena `error_msg` si falla. bool project_create(const char* slug, std::string* error_msg); // Migracion: si `/projects/` no existe pero hay operations.db en el cwd, // crea projects/default/ y mueve operations.db + graph_explorer.db ahi. // Idempotente: no-op si projects/ ya existe. bool projects_migrate_legacy_layout(); // Migracion idempotente del schema de una operations.db existente. // Detecta columnas/tablas ausentes via PRAGMA y aplica los ALTER TABLE // minimos. Llamar al abrir un proyecto antes de cargar el grafo. // // Migraciones aplicadas: // - 0035a: ALTER TABLE entities ADD COLUMN group_id TEXT (si falta) // // Devuelve true si la BD esta al dia (o ya lo estaba). Si falla, rellena // `error_msg` y devuelve false. bool project_migrate_schema(const std::string& path, std::string* error_msg); // Lee/escribe `graph_explorer.ini` (junto al exe). Formato: // last_active = // recent = slug1,slug2,slug3 struct ProjectSettings { std::string last_active; // slug del ultimo proyecto abierto std::vector recent; // mas reciente primero, max 5 }; bool project_settings_load(ProjectSettings* out); bool project_settings_save(const ProjectSettings& s); // Marca `slug` como activo y lo empuja al frente de `recent`. Persiste en // disco. No-op si slug es vacio. void project_settings_touch(const char* slug); // Abre la carpeta del proyecto en el explorador del sistema. // (Windows: explorer.exe; Linux: xdg-open). void project_reveal_in_explorer(const char* slug); } // namespace ge