docs(flows): DoD obligatorio con user-facing surface + abrir issues 0100-0103 (taxonomia, frontmatter migration, dev_console, work dashboard)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+59
-2
@@ -16,6 +16,7 @@ type IndexResult struct {
|
||||
Analysis int
|
||||
Projects int
|
||||
Vaults int
|
||||
Modules int
|
||||
UnitTests int
|
||||
ValidationErrors []string
|
||||
Warnings []string
|
||||
@@ -31,7 +32,7 @@ type IndexResult struct {
|
||||
// directories (e.g. python/functions/, python/types/).
|
||||
func Index(db *DB, root string) (*IndexResult, error) {
|
||||
// Load existing timestamps before purging so we can preserve created_at
|
||||
oldFuncs, oldTypes, oldApps, oldAnalysis, oldProjects, oldVaults, err := db.LoadTimestamps()
|
||||
oldFuncs, oldTypes, oldApps, oldAnalysis, oldProjects, oldVaults, oldModules, err := db.LoadTimestamps()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading timestamps: %w", err)
|
||||
}
|
||||
@@ -62,6 +63,20 @@ func Index(db *DB, root string) (*IndexResult, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Discover module directories (modules/<name>/) — each may contain function .md
|
||||
// files alongside the module.md. Module entrypoint .md files (e.g. data_table.md)
|
||||
// live in their module dir; types still live in types/ to keep cross-module reuse.
|
||||
modRoot := filepath.Join(root, "modules")
|
||||
if fi, err := os.Stat(modRoot); err == nil && fi.IsDir() {
|
||||
modEntries, _ := os.ReadDir(modRoot)
|
||||
for _, me := range modEntries {
|
||||
if !me.IsDir() {
|
||||
continue
|
||||
}
|
||||
funcDirs = append(funcDirs, filepath.Join(modRoot, me.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
for _, dir := range funcDirs {
|
||||
walkMD(dir, func(path string) {
|
||||
f, err := ParseFunctionMD(path, root)
|
||||
@@ -146,6 +161,31 @@ func Index(db *DB, root string) (*IndexResult, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse modules from modules/*/module.md
|
||||
var modules []*Module
|
||||
modulesDir := filepath.Join(root, "modules")
|
||||
if fi, err := os.Stat(modulesDir); err == nil && fi.IsDir() {
|
||||
modEntries, _ := os.ReadDir(modulesDir)
|
||||
for _, me := range modEntries {
|
||||
if !me.IsDir() {
|
||||
continue
|
||||
}
|
||||
modMD := filepath.Join(modulesDir, me.Name(), "module.md")
|
||||
if _, err := os.Stat(modMD); err != nil {
|
||||
continue
|
||||
}
|
||||
m, err := ParseModuleMD(modMD, root)
|
||||
if err != nil {
|
||||
result.Errors = append(result.Errors, fmt.Sprintf("parse %s: %v", modMD, err))
|
||||
continue
|
||||
}
|
||||
if m.DirPath == "" {
|
||||
m.DirPath = filepath.Join("modules", me.Name())
|
||||
}
|
||||
modules = append(modules, m)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse projects from projects/*/project.md
|
||||
var projects []*Project
|
||||
var vaults []*Vault
|
||||
@@ -347,6 +387,19 @@ func Index(db *DB, root string) (*IndexResult, error) {
|
||||
result.Vaults++
|
||||
}
|
||||
|
||||
for _, m := range modules {
|
||||
m.ContentHash = ComputeModuleHash(m)
|
||||
applyTimestamps(&m.CreatedAt, &m.UpdatedAt, m.ContentHash, oldModules[m.ID], now)
|
||||
if err := db.InsertModule(m); err != nil {
|
||||
result.Errors = append(result.Errors, fmt.Sprintf("insert module %s: %v", m.ID, err))
|
||||
continue
|
||||
}
|
||||
if err := emitModuleVersionHeader(m, root); err != nil {
|
||||
result.Warnings = append(result.Warnings, fmt.Sprintf("module %s: codegen version header: %v", m.ID, err))
|
||||
}
|
||||
result.Modules++
|
||||
}
|
||||
|
||||
// Extract unit tests from test files of tested functions
|
||||
if err := db.PurgeUnitTests(); err != nil {
|
||||
result.Warnings = append(result.Warnings, fmt.Sprintf("purging unit_tests: %v", err))
|
||||
@@ -437,7 +490,8 @@ func applyTimestamps(createdAt, updatedAt *time.Time, newHash string, old timest
|
||||
}
|
||||
}
|
||||
|
||||
// walkMD walks a directory recursively and calls fn for each .md file found.
|
||||
// walkMD walks a directory recursively and calls fn for each .md file found,
|
||||
// skipping module.md (which is parsed separately as a Module entry).
|
||||
func walkMD(dir string, fn func(path string)) {
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return
|
||||
@@ -446,6 +500,9 @@ func walkMD(dir string, fn func(path string)) {
|
||||
if err != nil || info.IsDir() || !strings.HasSuffix(path, ".md") {
|
||||
return nil
|
||||
}
|
||||
if filepath.Base(path) == "module.md" {
|
||||
return nil
|
||||
}
|
||||
fn(path)
|
||||
return nil
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user