diff --git a/.cursor/rules/atlas-project-rules.mdc b/.cursor/rules/atlas-project-rules.mdc new file mode 100644 index 0000000..d76ca1f --- /dev/null +++ b/.cursor/rules/atlas-project-rules.mdc @@ -0,0 +1,58 @@ +--- +alwaysApply: true +--- +########################################## +# Atlas Project Standard Rules v1.0 +# ISO Ref: DevOps-Config-2025 +# Maintainer: Adastra - InfraOps Team +########################################## + +## Metadata +- Template Name : Atlas Project Standard Rules +- Version : 1.0 +- Maintainer : InfraOps Team +- Last Updated : 2025-12-14 + +--- + +## Rule Categories + +### 🔧 Indentation & Spacing +[ ] CURSOR-001: Gunakan 2 spasi untuk indentation +[ ] CURSOR-002: Hindari tab, gunakan spasi konsisten + +### 📂 Naming Convention +[ ] CURSOR-010: File harus pakai snake_case +[ ] CURSOR-011: Folder pakai kebab-case +[ ] CURSOR-012: Config file wajib ada suffix `.conf` +[ ] CURSOR-013: Script file wajib ada suffix `.sh` +[ ] CURSOR-014: Log file wajib ada suffix `.log` + +### 🗂 File Structure +[ ] CURSOR-020: Semua file harus ada header metadata +[ ] CURSOR-021: Pisahkan config, script, dan log folder +[ ] CURSOR-022: Tidak ada file kosong di repo + +### ✅ Audit & Compliance +[ ] CURSOR-030: Checklist harus lengkap sebelum commit +[ ] CURSOR-031: Semua config tervalidasi linting +[ ] CURSOR-032: Banner branding wajib ada di setiap template + +### ⚠️ Error Handling +[ ] CURSOR-040: Log error harus diarahkan ke folder `/logs` +[ ] CURSOR-041: Tidak ada hardcoded path di script +[ ] CURSOR-042: Semua service startup diverifikasi + +--- + +## Compliance Scoring +- [ ] 100% → Audit Passed +- [ ] 80–99% → Minor Findings +- [ ] <80% → Audit Failed + +--- + +## Notes +- Semua rule harus dipetakan ke ID unik (CURSOR-XXX). +- Versi baru wajib update metadata & banner. +- Checklist ini bisa dipakai lintas project untuk konsistensi. diff --git a/internal/httpapp/app.go b/internal/httpapp/app.go new file mode 100644 index 0000000..0c40643 --- /dev/null +++ b/internal/httpapp/app.go @@ -0,0 +1,80 @@ +package httpapp + +import ( + "fmt" + "html/template" + "net/http" + "path/filepath" + "time" +) + +type Config struct { + Addr string + TemplatesDir string + StaticDir string +} + +type App struct { + cfg Config + tmpl *template.Template + mux *http.ServeMux +} + +func New(cfg Config) (*App, error) { + if cfg.TemplatesDir == "" { + cfg.TemplatesDir = "web/templates" + } + if cfg.StaticDir == "" { + cfg.StaticDir = "web/static" + } + + tmpl, err := parseTemplates(cfg.TemplatesDir) + if err != nil { + return nil, err + } + + a := &App{ + cfg: cfg, + tmpl: tmpl, + mux: http.NewServeMux(), + } + + a.routes() + return a, nil +} + +func (a *App) Router() http.Handler { + // Wrap the mux with basic middleware chain + return requestID(logging(a.mux)) +} + +func (a *App) routes() { + // Static + fs := http.FileServer(http.Dir(a.cfg.StaticDir)) + a.mux.Handle("/static/", http.StripPrefix("/static/", fs)) + + // Core pages + a.mux.HandleFunc("/", a.handleDashboard) + + // Health & metrics + a.mux.HandleFunc("/healthz", a.handleHealthz) + a.mux.HandleFunc("/metrics", a.handleMetrics) +} + +func parseTemplates(dir string) (*template.Template, error) { + pattern := filepath.Join(dir, "*.html") + files, err := filepath.Glob(pattern) + if err != nil { + return nil, err + } + if len(files) == 0 { + return nil, fmt.Errorf("no templates found at %s", pattern) + } + + funcs := template.FuncMap{ + "nowRFC3339": func() string { return time.Now().Format(time.RFC3339) }, + } + + t := template.New("root").Funcs(funcs) + return t.ParseFiles(files...) +} diff --git a/pluto-api b/pluto-api new file mode 100755 index 0000000..4458013 Binary files /dev/null and b/pluto-api differ diff --git a/web/templates/base.html b/web/templates/base.html new file mode 100644 index 0000000..72b0a03 --- /dev/null +++ b/web/templates/base.html @@ -0,0 +1,47 @@ +{{define "base"}} + + + + + + {{.Title}} • PlutoOS + + + + + + + +
+
+
+
P
+
+
PlutoOS
+
Storage Controller v1
+
+
+ + +
+
+ +
+ {{template "content" .}} +
+ + + + +{{end}} diff --git a/web/templates/dashboard.html b/web/templates/dashboard.html new file mode 100644 index 0000000..e69de29