| 312 | } |
| 313 | |
| 314 | func generateSPAFallbacks(outputDir, patchedHTML string, tasks []*model.Task) error { |
| 315 | // Top-level SPA routes |
| 316 | routes := []string{"tasks", "board", "graph", "next", "stats", "validate", "tracks"} |
| 317 | for _, route := range routes { |
| 318 | dir := filepath.Join(outputDir, route) |
| 319 | if err := os.MkdirAll(dir, 0755); err != nil { |
| 320 | return fmt.Errorf("failed to create route directory %s: %w", route, err) |
| 321 | } |
| 322 | if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte(patchedHTML), 0644); err != nil { |
| 323 | return fmt.Errorf("failed to write fallback for %s: %w", route, err) |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | // Per-task detail routes: /tasks/{id}/index.html |
| 328 | for _, t := range tasks { |
| 329 | dir := filepath.Join(outputDir, "tasks", t.ID) |
| 330 | if err := os.MkdirAll(dir, 0755); err != nil { |
| 331 | return fmt.Errorf("failed to create task route directory %s: %w", t.ID, err) |
| 332 | } |
| 333 | if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte(patchedHTML), 0644); err != nil { |
| 334 | return fmt.Errorf("failed to write fallback for task %s: %w", t.ID, err) |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | // 404.html for GitHub Pages fallback |
| 339 | if err := os.WriteFile(filepath.Join(outputDir, "404.html"), []byte(patchedHTML), 0644); err != nil { |
| 340 | return fmt.Errorf("failed to write 404.html: %w", err) |
| 341 | } |
| 342 | |
| 343 | return nil |
| 344 | } |