diff --git a/docs/todo/TODO_SCAN_REPORT.md b/docs/todo/TODO_SCAN_REPORT.md new file mode 100644 index 000000000..fc3803d15 --- /dev/null +++ b/docs/todo/TODO_SCAN_REPORT.md @@ -0,0 +1,177 @@ +# TODO Scan Report + +- Generated: `2025-12-25 20:56:07Z` (UTC) +- Repo root: `/Users/rmac/Documents/GitHub/metabuilder` +- Pattern: `\b(TODO|FIXME|HACK|XXX)\b` +- Excludes: `docs/todo/`, `**/node_modules/`, `**/.next/`, `**/coverage/`, `**/dist/`, `**/build/`, `**/.git/` + +## Summary +- Total matches: **152** +- By marker: `TODO`=152 +- By top-level directory: + - `dbal`: 6 + - `docs`: 95 + - `frontends`: 36 + - `tools`: 15 + +## Matches + +### `dbal` (6) +- `dbal/cpp/README.Linting.md:306` — - TODO/FIXME comments count +- `dbal/cpp/lint.sh:137` — echo "Checking for TODO/FIXME comments..." +- `dbal/cpp/lint.sh:138` — TODO_COUNT=$(grep -r "TODO\|FIXME" src/ include/ || true | wc -l) +- `dbal/cpp/lint.sh:140` — echo -e "${YELLOW}⚠ Found $TODO_COUNT TODO/FIXME comments${NC}" +- `dbal/cpp/lint.sh:141` — grep -rn "TODO\|FIXME" src/ include/ || true +- `dbal/cpp/lint.sh:143` — echo -e "${GREEN}✓ No TODO/FIXME comments${NC}" + +### `docs` (95) +- `docs/CONTRIBUTING.md:23` — - Leave TODO comments for missing functionality. +- `docs/CONTRIBUTING.md:185` — 5. **TODOs** - Leave TODO comments for missing functionality +- `docs/CONTRIBUTING.md:275` — TODO: Links below use ../docs/... from docs/CONTRIBUTING.md and resolve to docs/docs; update to correct relative paths (including security and copilot). +- `docs/CONTRIBUTING.md:279` — TODO: E2E tests guide lives under frontends/nextjs/e2e; update this link. +- `docs/DOCS_ORGANIZATION_COMPLETE.md:8` — TODO: This file is in docs/ so ./docs/ links are broken; root-level file list is outdated (README/CONTRIBUTING are not at repo root). +- `docs/DOCS_ORGANIZATION_GUIDE.md:5` — TODO: This file is already in docs/; links that start with ./docs/ are broken and should be updated to correct relative paths. +- `docs/DOCS_ORGANIZATION_GUIDE.md:139` — - Search for "ERROR:", "TODO:", "FIXME:" to find action items +- `docs/NAVIGATION.md:144` — TODO: docs/src/ is missing; add the folder or update/remove the src links below. +- `docs/README.md:5` — TODO: This file lives under docs/; links that start with ./docs/ are broken and PRD/SECURITY paths are outdated. +- `docs/README.md:230` — TODO: src/README.md does not exist under docs/; confirm correct location or add missing docs/src. +- `docs/README.md:261` — TODO: Manual deployment docs are not under docs/deployment; update this link to the correct location. +- `docs/START_HERE.md:5` — TODO: This file is in docs/ so ./docs/ links are broken; the root-level file list below is outdated (README/CONTRIBUTING live elsewhere or do not exist). +- `docs/START_HERE.md:16` — - Leave TODO comments for missing functionality. +- `docs/architecture/css-as-abstract-system.md:275` — ## TODO +- `docs/architecture/deployment.md:298` — TODO: Security guide lives at ../security/SECURITY.md; update this link. +- `docs/architecture/packages.md:496` — TODO: Development guide link should point to docs/guides/getting-started.md (current file does not exist). +- `docs/architecture/packages.md:498` — TODO: Component guidelines link points to a non-existent docs/components/README.md; update to correct location. +- `docs/architecture/security.md:260` — TODO: Security guidelines live at ../security/SECURITY.md; update this link. +- `docs/architecture/testing.md:243` — TODO: E2E tests live under frontends/nextjs/e2e; update this link. +- `docs/archive/src/lib/CODE_TO_DOCS_MAPPING.md:9` — TODO: Audit component/hook documentation coverage, replace TBD values, and update `/src/` path references to match the current `frontends/nextjs/src` layout. +- `docs/database/PRISMA_SETUP.md:140` — TODO: The migration guide link should be relative to docs/database (remove ./docs/). +- `docs/deployments/CI_CD_REPAIRS.md:129` — 2. **quality-check**: Scans for console.log, TODO comments +- `docs/deployments/CI_CD_SUMMARY.md:38` — 4. **Quality Check** - Console.log and TODO detection +- `docs/deployments/CI_CD_SUMMARY.md:327` — TODO: Links below are repo-relative but this file is in docs/deployments; update paths for workflow README and E2E guide. +- `docs/deployments/CI_FIX_SUMMARY.md:226` — # src/client.cpp # TODO: Implement +- `docs/deployments/CI_FIX_SUMMARY.md:227` — # src/errors.cpp # TODO: Implement +- `docs/deployments/GITHUB_WORKFLOWS_AUDIT.md:25` — - ✅ Code quality checks (console.log, TODO detection) +- `docs/guides/SASS_QUICK_REFERENCE.md:287` — TODO: The design tokens link should not use ../docs/ from docs/guides; update to the correct relative path. +- `docs/guides/getting-started.md:313` — TODO: Links in this section use ./ from docs/guides; update to correct relative paths (architecture/reference/troubleshooting) and fix README/SECURITY/COMPONENT_MAP locations be... +- `docs/implementation/DBAL_INTEGRATION.md:285` — # TODO: deployment docs live under docs/deployments/; update this reference. +- `docs/implementation/DBAL_INTEGRATION.md:391` — TODO: Fix related doc links (deployments path and local implementation docs). +- `docs/implementation/DBAL_INTEGRATION.md:408` — TODO: No LICENSE file exists at repo root; update to correct location (e.g., docs/LICENSE) or add one. +- `docs/migrations/FILE_RELOCATION_GUIDE.md:83` — TODO: This repo does not have root README/PRD/SECURITY/LIMITED files as listed; update for current structure (docs/* locations). +- `docs/migrations/FILE_RELOCATION_GUIDE.md:92` — TODO: Example path uses /workspaces/spark-template and root file list no longer matches this repo. +- `docs/migrations/MIGRATION_STATUS.md:159` — 3. Audit log storage using console.log - TODO: database implementation +- `docs/migrations/MIGRATION_STATUS.md:160` — 4. Modular package storage stubbed - TODO: database implementation +- `docs/migrations/RELOCATION_SUMMARY.md:79` — TODO: This repo does not have root README/PRD/SECURITY as listed; update to current docs locations. +- `docs/refactoring/REFACTORING_INDEX.md:360` — TODO: Paths below are wrong from docs/refactoring; update copilot/PRD and schema/src references to valid locations. +- `docs/refactoring/REFACTORING_SUMMARY.md:450` — TODO: Update copilot instructions and PRD links to correct relative paths from docs/refactoring. +- `docs/reference/DOCUMENTATION_FINDINGS.md:605` — TODO: Core doc links below point to docs/reference; update to correct paths under docs/ (README, PRD, SECURITY). +- `docs/reference/IMPROVEMENT_ROADMAP_INDEX.md:8` — TODO: This file uses ./docs/... links which are broken from docs/reference/; update to correct relative paths. +- `docs/reference/PRIORITY_ACTION_PLAN.md:9` — TODO: This file uses ./docs/... links which are broken from docs/reference/; update to correct relative paths. +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:25` — - TODO/FIXME comments +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:152` — - `
TODO
` in components +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:161` — 6. **TODO Comments** (🟡 Medium) +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:162` — - TODO/FIXME indicating incomplete work +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:225` — - Replace TODO with GitHub issues +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:254` — # Find TODO comments +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:255` — grep -r "// TODO:" src/ +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:262` — grep -r "
TODO" src/ +- `docs/reference/STUB_DETECTION_IMPLEMENTATION.md:377` — TODO: Update reference links to correct repo-relative paths from docs/reference (stub-detection docs, workflows, scripts). +- `docs/reference/STUB_DETECTION_QUICK_START.md:28` — - **10 medium** severity (marked as TODO/mock) +- `docs/reference/STUB_DETECTION_QUICK_START.md:29` — - **179 low** severity (mostly TODO comments) +- `docs/reference/STUB_DETECTION_QUICK_START.md:39` — | Returns null | `return null // TODO` | 🟡 Medium | +- `docs/reference/STUB_DETECTION_QUICK_START.md:40` — | TODO comment | `// TODO: implement this` | 🟡 Medium | +- `docs/reference/STUB_DETECTION_QUICK_START.md:41` — | Placeholder UI | `
TODO: build UI
` | 🟠 High | +- `docs/reference/STUB_DETECTION_QUICK_START.md:57` — ### Find All TODO Comments +- `docs/reference/STUB_DETECTION_QUICK_START.md:59` — grep -r "TODO:" src/ | grep -v test +- `docs/reference/STUB_DETECTION_QUICK_START.md:149` — TODO: doc links below should be relative to docs/reference (use ../stub-detection/...). +- `docs/reference/STUB_DETECTION_QUICK_START.md:173` — ### Tip 2: Create Issues Instead of TODO +- `docs/reference/STUB_DETECTION_QUICK_START.md:176` — // TODO: add caching +- `docs/reference/STUB_DETECTION_QUICK_START.md:238` — "code": "{ // TODO: Replace with proper database query" +- `docs/reference/STUB_DETECTION_SUMMARY.md:44` — 4. **🟡 TODO Comments** - `// TODO:` or `// FIXME:` markers +- `docs/reference/STUB_DETECTION_SUMMARY.md:45` — 5. **🟠 Placeholder Text** - `
TODO: build UI
` +- `docs/reference/STUB_DETECTION_SUMMARY.md:86` — - ✅ **10 medium severity** - Some marked as TODO/mock +- `docs/reference/STUB_DETECTION_SUMMARY.md:87` — - ✅ **179 low severity** - Mostly TODO comments +- `docs/reference/STUB_DETECTION_SUMMARY.md:144` — ### Example 3: TODO Comment +- `docs/reference/STUB_DETECTION_SUMMARY.md:147` — // TODO: implement processing // ← Detected: 🟡 Medium +- `docs/reference/STUB_DETECTION_SUMMARY.md:230` — TODO: Stub-detection doc references below should be relative to docs/reference (use ../stub-detection/...). +- `docs/reference/TESTING_IMPLEMENTATION_SUMMARY.md:7` — TODO: This file uses ../docs/... links that resolve to docs/docs; update to correct relative paths. +- `docs/stub-detection/OVERVIEW.md:19` — - **Low**: 179 (TODO comments) +- `docs/stub-detection/OVERVIEW.md:22` — - TODO/FIXME comments: 167 +- `docs/stub-detection/OVERVIEW.md:77` — TODO: Links below should be relative to docs/stub-detection (drop docs/ prefix). +- `docs/stub-detection/OVERVIEW.md:108` — ### 4. TODO Comments (🟡 Medium) +- `docs/stub-detection/OVERVIEW.md:111` — // TODO: implement this ← Detected +- `docs/stub-detection/OVERVIEW.md:119` — return
TODO: Build dashboard
// ← Detected +- `docs/stub-detection/OVERVIEW.md:208` — ### Fix TODO Comment +- `docs/stub-detection/OVERVIEW.md:211` — // TODO: implement feature +- `docs/stub-detection/QUICK_REFERENCE.md:10` — | `
TODO
` | 🟠 High | See Pattern 4 | Implement component | +- `docs/stub-detection/QUICK_REFERENCE.md:12` — | `// TODO:` comment | 🟡 Medium | See Pattern 6 | Create issue, implement | +- `docs/stub-detection/QUICK_REFERENCE.md:71` — ### Replace TODO Comments +- `docs/stub-detection/QUICK_REFERENCE.md:74` — // TODO: implement feature +- `docs/stub-detection/QUICK_REFERENCE.md:92` — # TODO comments +- `docs/stub-detection/QUICK_REFERENCE.md:93` — grep -r "TODO\|FIXME" src/ +- `docs/stub-detection/QUICK_REFERENCE.md:154` — // TODO: implement +- `docs/stub-detection/README.md:12` — - Contains TODO/FIXME comments indicating incomplete work +- `docs/stub-detection/README.md:51` — return
TODO: Build dashboard
+- `docs/stub-detection/README.md:88` — | `// TODO:` or `// FIXME:` | Medium | Known issue, incomplete | +- `docs/stub-detection/README.md:260` — return null // TODO: load config +- `docs/stub-detection/README.md:278` — return
TODO: Build dashboard
+- `docs/stub-detection/README.md:315` — ### Pattern 6: TODO Comments +- `docs/stub-detection/README.md:317` — **Problem**: Code has TODO/FIXME comments indicating incomplete work +- `docs/stub-detection/README.md:319` — **Fix**: Create GitHub issue and remove TODO from code +- `docs/stub-detection/README.md:324` — // TODO: Add real email validation +- `docs/stub-detection/README.md:389` — // TODO: add caching (#TBD) + +### `frontends` (36) +- `frontends/nextjs/src/components/GitHubActionsFetcher.tsx:66` — // TODO: Replace with proper GitHub OAuth authentication in Next.js +- `frontends/nextjs/src/components/GitHubActionsFetcher.tsx:140` — // TODO: Replace with Next.js API route that calls an LLM service +- `frontends/nextjs/src/components/GitHubActionsFetcher.tsx:291` — // TODO: Replace with Next.js API route that calls an LLM service +- `frontends/nextjs/src/components/ScreenshotAnalyzer.tsx:64` — // TODO: Replace with Next.js API route that calls an LLM service +- `frontends/nextjs/src/components/ui/accordion.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/alert-dialog.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/alert.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/avatar.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/badge.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/button.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/card.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/checkbox.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/dialog.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/dropdown-menu.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/input.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/label.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/progress.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/radio-group.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/scroll-area.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/select.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/separator.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/sheet.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/skeleton.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/slider.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/sonner.tsx:94` — // TODO: Implement dismiss by ID +- `frontends/nextjs/src/components/ui/switch.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/table.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/tabs.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/components/ui/textarea.ts:2` — // TODO: Update imports to use @/components/ui directly +- `frontends/nextjs/src/hooks/useAuth.ts:28` — // TODO: Implement proper auth with backend/Prisma +- `frontends/nextjs/src/hooks/useKV.ts:9` — // TODO: Implement proper persistent KV storage with Database/Prisma +- `frontends/nextjs/src/lib/lua/sandboxed-lua-engine.ts:19` — // TODO: Enforce maxMemory limit in sandbox execution. +- `frontends/nextjs/src/lib/security/secure-db/log-operation.ts:28` — // TODO: Replace with proper audit log storage +- `frontends/nextjs/src/lib/security/secure-db/operations/get-audit-logs.ts:14` — // TODO: Replace with proper audit log storage query using the requested limit. +- `frontends/nextjs/src/lib/security/secure-db/operations/verify-credentials.ts:16` — // TODO: Track failed login attempts and enforce account lockout/backoff. +- `frontends/nextjs/src/lib/security/secure-db/rate-limit-store.ts:1` — // TODO: Load rate limit settings from config/DB instead of hardcoding. + +### `tools` (15) +- `tools/analyze-implementation-completeness.ts:104` — if (body.includes('TODO') || body.includes('FIXME')) { +- `tools/analyze-test-coverage.ts:292` — // Generate TODO items +- `tools/analyze-test-coverage.ts:294` — console.log("TODO - CREATE TESTS FOR:"); +- `tools/autobot.sh:9` — codex exec --full-auto --sandbox="danger-full-access" --cd="/Users/rmac/Documents/GitHub/metabuilder/docs/todo/" "Please resolve my TODO list, Scan project for TODO items." || e... +- `tools/check-function-coverage.js:184` — console.log(`🎯 TODO - CREATE TESTS FOR:`); +- `tools/detect-stub-implementations.ts:24` — name: 'TODO comment in function', +- `tools/detect-stub-implementations.ts:25` — pattern: /\/\/\s*TODO|\/\/\s*FIXME|\/\/\s*XXX|\/\/\s*HACK/i, +- `tools/detect-stub-implementations.ts:28` — description: 'Function has TODO/FIXME comment' +- `tools/detect-stub-implementations.ts:53` — pattern: /<[A-Z]\w*[^>]*>\s*(placeholder|TODO|FIXME|stub|mock|example|not implemented)/i, +- `tools/detect-stub-implementations.ts:130` — if (line.match(/stub|placeholder|mock|not implemented|TODO.*implementation/i)) { +- `tools/generate-stub-report.ts:138` — report += ' return null // TODO: implement API call\n' +- `tools/generate-stub-report.ts:151` — report += ' return
TODO: Build dashboard
\n' +- `tools/generate-stub-report.ts:185` — report += '- [ ] All TODO/FIXME comments reference GitHub issues\n' +- `tools/generate-stub-report.ts:194` — report += '3. **Convert stubs to issues** - Don\'t use TODO in code, create GitHub issues\n' +- `tools/generate-stub-report.ts:196` — report += '5. **Use linting rules** - Configure ESLint to catch console.log and TODO\n\n' diff --git a/docs/todo/TODO_STATUS.md b/docs/todo/TODO_STATUS.md new file mode 100644 index 000000000..50be354df --- /dev/null +++ b/docs/todo/TODO_STATUS.md @@ -0,0 +1,31 @@ +# TODO List Status + +- Generated: `2025-12-25 20:56:07Z` (UTC) +- Directory: `/Users/rmac/Documents/GitHub/metabuilder/docs/todo` +- Total items: **852** (`open`=829, `done`=23) + +| File | Open | Done | Total | +|------|-----:|-----:|------:| +| `0-kickstart.md` | 8 | 0 | 8 | +| `1-TODO.md` | 4 | 0 | 4 | +| `10-SECURITY-TODO.md` | 40 | 2 | 42 | +| `11-DEPLOYMENT-TODO.md` | 40 | 0 | 40 | +| `12-DOCUMENTATION-TODO.md` | 45 | 0 | 45 | +| `13-DECLARATIVE-UI-TODO.md` | 45 | 1 | 46 | +| `14-MULTI-TENANT-TODO.md` | 35 | 0 | 35 | +| `15-BUILD-FIXES-TODO.md` | 34 | 6 | 40 | +| `16-SCRIPTS-TOOLING-TODO.md` | 37 | 3 | 40 | +| `17-GITHUB-COPILOT-TODO.md` | 35 | 0 | 35 | +| `18-ACCESSIBILITY-TODO.md` | 40 | 0 | 40 | +| `19-PERFORMANCE-TODO.md` | 40 | 0 | 40 | +| `2-TODO.md` | 27 | 0 | 27 | +| `20-FUTURE-FEATURES-TODO.md` | 45 | 0 | 45 | +| `21-SDLC-TODO.md` | 127 | 2 | 129 | +| `3-TODO.md` | 16 | 0 | 16 | +| `4-DBAL-TODO.md` | 30 | 2 | 32 | +| `5-FRONTEND-TODO.md` | 37 | 1 | 38 | +| `6-PACKAGES-TODO.md` | 49 | 1 | 50 | +| `7-DATABASE-TODO.md` | 30 | 0 | 30 | +| `8-TESTING-TODO.md` | 30 | 4 | 34 | +| `9-LUA-SCRIPTING-TODO.md` | 35 | 1 | 36 | +| `README.md` | 0 | 0 | 0 | diff --git a/docs/todo/scan-project-todos.py b/docs/todo/scan-project-todos.py new file mode 100644 index 000000000..d87d1013d --- /dev/null +++ b/docs/todo/scan-project-todos.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import re +import subprocess +from collections import Counter, defaultdict +from dataclasses import dataclass +from datetime import datetime, timezone +from pathlib import Path + + +@dataclass(frozen=True) +class TodoMatch: + path: str + line: int + text: str + + +PATTERN = r"\b(TODO|FIXME|HACK|XXX)\b" +RG_GLOBS = [ + "!docs/todo/**", + "!**/node_modules/**", + "!**/.next/**", + "!**/coverage/**", + "!**/dist/**", + "!**/build/**", + "!**/.git/**", +] + + +def _repo_root(script_dir: Path) -> Path: + # docs/todo -> docs -> repo root + return script_dir.parent.parent + + +def _run_rg(repo_root: Path) -> list[TodoMatch]: + cmd = ["rg", "-n", "-S", PATTERN] + for glob in RG_GLOBS: + cmd.extend(["--glob", glob]) + cmd.append(".") + + completed = subprocess.run( + cmd, + cwd=repo_root, + text=True, + capture_output=True, + check=False, + ) + + if completed.returncode not in (0, 1): + raise RuntimeError( + "ripgrep failed\n" + f"cmd: {' '.join(cmd)}\n" + f"exit: {completed.returncode}\n" + f"stderr:\n{completed.stderr}" + ) + + matches: list[TodoMatch] = [] + for raw_line in completed.stdout.splitlines(): + # Format: path:line:text (text itself may contain ':', so split max 2) + file_part, sep1, rest = raw_line.partition(":") + if not sep1: + continue + line_part, sep2, text_part = rest.partition(":") + if not sep2: + continue + try: + line_no = int(line_part) + except ValueError: + continue + matches.append( + TodoMatch( + path=file_part.removeprefix("./"), + line=line_no, + text=text_part.rstrip(), + ) + ) + return matches + + +def _top_level_dir(path: str) -> str: + if not path: + return "(root)" + if path.startswith(".github/"): + return ".github" + return path.split("/", 1)[0] + + +def _marker_counts(matches: list[TodoMatch]) -> Counter[str]: + counts: Counter[str] = Counter() + marker_re = re.compile(PATTERN, re.IGNORECASE) + for match in matches: + found = marker_re.search(match.text) + if not found: + continue + counts[found.group(1).upper()] += 1 + return counts + + +def _render_scan_report( + repo_root: Path, out_path: Path, matches: list[TodoMatch] +) -> None: + now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%SZ") + + by_dir: dict[str, list[TodoMatch]] = defaultdict(list) + for match in matches: + by_dir[_top_level_dir(match.path)].append(match) + + dir_counts = Counter({k: len(v) for k, v in by_dir.items()}) + marker_counts = _marker_counts(matches) + + lines: list[str] = [] + lines.append("# TODO Scan Report") + lines.append("") + lines.append(f"- Generated: `{now}` (UTC)") + lines.append(f"- Repo root: `{repo_root}`") + lines.append(f"- Pattern: `{PATTERN}`") + lines.append( + "- Excludes: `docs/todo/`, `**/node_modules/`, `**/.next/`, `**/coverage/`, `**/dist/`, `**/build/`, `**/.git/`" + ) + lines.append("") + lines.append("## Summary") + lines.append(f"- Total matches: **{len(matches)}**") + if marker_counts: + lines.append( + "- By marker: " + + ", ".join( + f"`{marker}`={marker_counts[marker]}" + for marker in sorted(marker_counts.keys()) + ) + ) + lines.append("- By top-level directory:") + for directory in sorted(dir_counts.keys()): + lines.append(f" - `{directory}`: {dir_counts[directory]}") + + lines.append("") + lines.append("## Matches") + for directory in sorted(by_dir.keys()): + lines.append("") + lines.append(f"### `{directory}` ({len(by_dir[directory])})") + for match in sorted(by_dir[directory], key=lambda m: (m.path, m.line)): + snippet = re.sub(r"\s+", " ", match.text).strip() + if len(snippet) > 180: + snippet = snippet[:177] + "..." + lines.append(f"- `{match.path}:{match.line}` — {snippet}") + + out_path.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8") + + +def _render_todo_status(todo_dir: Path, out_path: Path) -> None: + md_files = sorted( + p for p in todo_dir.glob("*.md") if p.name not in {"TODO_SCAN_REPORT.md", "TODO_STATUS.md"} + ) + + checkbox_open_re = re.compile(r"^\s*-\s*\[\s*\]\s+") + checkbox_done_re = re.compile(r"^\s*-\s*\[\s*x\s*\]\s+", re.IGNORECASE) + + rows: list[tuple[str, int, int, int]] = [] + total_open = 0 + total_done = 0 + for path in md_files: + open_count = 0 + done_count = 0 + for line in path.read_text(encoding="utf-8").splitlines(): + if checkbox_done_re.match(line): + done_count += 1 + elif checkbox_open_re.match(line): + open_count += 1 + total_open += open_count + total_done += done_count + rows.append((path.name, open_count, done_count, open_count + done_count)) + + lines: list[str] = [] + now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%SZ") + lines.append("# TODO List Status") + lines.append("") + lines.append(f"- Generated: `{now}` (UTC)") + lines.append(f"- Directory: `{todo_dir}`") + lines.append(f"- Total items: **{total_open + total_done}** (`open`={total_open}, `done`={total_done})") + lines.append("") + lines.append("| File | Open | Done | Total |") + lines.append("|------|-----:|-----:|------:|") + for filename, open_count, done_count, total in rows: + lines.append(f"| `{filename}` | {open_count} | {done_count} | {total} |") + + out_path.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8") + + +def main() -> None: + script_path = Path(__file__).resolve() + todo_dir = script_path.parent + repo_root = _repo_root(todo_dir) + + matches = _run_rg(repo_root) + _render_scan_report(repo_root, todo_dir / "TODO_SCAN_REPORT.md", matches) + _render_todo_status(todo_dir, todo_dir / "TODO_STATUS.md") + + print(f"Wrote: {todo_dir / 'TODO_SCAN_REPORT.md'}") + print(f"Wrote: {todo_dir / 'TODO_STATUS.md'}") + + +if __name__ == "__main__": + main() + diff --git a/frontends/nextjs/src/lib/rendering/page-renderer.test.ts b/frontends/nextjs/src/lib/rendering/page-renderer.test.ts index fb7bce2ba..ae1d78d00 100644 --- a/frontends/nextjs/src/lib/rendering/page-renderer.test.ts +++ b/frontends/nextjs/src/lib/rendering/page-renderer.test.ts @@ -49,8 +49,7 @@ function createMockUser(role: string, id = 'user1'): User { return { id, username: `User ${id}`, - role: role as any, - level: role === 'public' ? 1 : role === 'user' ? 2 : role === 'admin' ? 3 : role === 'god' ? 4 : 5, + role: role as UserRole, email: `${id}@test.com`, createdAt: Date.now(), }