ZDDC/zddc/internal/archive/resolver.go
ZDDC ea385b5366 Initial commit
ZDDC — Zero Day Document Control. A file-naming convention plus five
single-file HTML tools (archive, transmittal, classifier, mdedit,
landing) and an optional Go HTTP server (zddc-server) with ACL and a
virtual archive index. Self-contained, offline-capable, dependency-free.

See README.md for an overview, AGENTS.md and ARCHITECTURE.md for the
build/release/architecture detail, bootstrap/README.md for the
two-level deployment install pattern, and zddc/README.md for the
HTTP server.
2026-04-27 11:05:47 -05:00

80 lines
1.9 KiB
Go

package archive
import (
"strings"
)
// Resolve parses the .archive request filename and returns the server-relative
// redirect target URL (no leading slash).
//
// Supported URL filename patterns (after stripping .html suffix):
// - trackingNumber → highest base revision of trackingNumber
// - trackingNumber_rev → base revision file for rev
// - trackingNumber_rev+C1 → modifier file (C1, B1, N1, Q1)
//
// Returns ("", false) if the filename cannot be parsed or no match exists.
func Resolve(idx *Index, filename string) (string, bool) {
// Strip .html suffix
stem := strings.TrimSuffix(filename, ".html")
if stem == filename {
// No .html suffix — not a valid archive request
return "", false
}
idx.mu.RLock()
defer idx.mu.RUnlock()
// Try to split off revision part (last _ segment)
lastUnderscore := strings.LastIndex(stem, "_")
if lastUnderscore < 0 {
// No underscore — treat entire stem as tracking number
tracking := stem
te, ok := idx.ByTracking[tracking]
if !ok || te.HighestBaseRev == "" {
return "", false
}
re, ok := te.ByRevision[te.HighestBaseRev]
if !ok || re.BasePath == "" {
return "", false
}
return re.BasePath, true
}
tracking := stem[:lastUnderscore]
revPart := stem[lastUnderscore+1:]
// Split revPart on "+" to separate baseRev from modifier
plusIdx := strings.Index(revPart, "+")
var baseRev, modifier string
if plusIdx < 0 {
baseRev = revPart
modifier = ""
} else {
baseRev = revPart[:plusIdx]
modifier = revPart[plusIdx+1:]
}
te, ok := idx.ByTracking[tracking]
if !ok {
return "", false
}
re, ok := te.ByRevision[baseRev]
if !ok {
return "", false
}
if modifier == "" {
if re.BasePath == "" {
return "", false
}
return re.BasePath, true
}
// Modifier lookup
path, ok := re.Modifiers[modifier]
if !ok {
return "", false
}
return path, true
}