diff --git a/docs/audit-report.md b/docs/audit-report.md new file mode 100644 index 0000000..6acf232 --- /dev/null +++ b/docs/audit-report.md @@ -0,0 +1,238 @@ +# Mana-Loop Codebase Audit Report + +**Date:** 2025-01-24 +**Auditor:** Automated sub-agent analysis + +## Executive Summary + +The Mana-Loop codebase is a Next.js game application with a mixed architecture - partially refactored from a monolithic store (`store.ts`) to a modular store architecture (`stores/`). The codebase has significant technical debt in the form of dead code, unimplemented features, and files that have grown too large. + +--- + +## Phase 1: Files Over 300 Lines + +### Critical (Needs Immediate Refactoring) + +| File | Lines | Purpose | Issue | +|------|-------|---------|-------| +| `src/lib/game/store.ts` | 2464 | Legacy monolithic game store | Monolith doing virtually all game logic | +| `src/lib/game/skill-evolution.ts` | 2312 | Skill talent trees | Single file with all skill trees; could split by category | +| `src/lib/game/constants.ts` | 1436 | Game constants & definitions | Mixes constants with content data (spells, skills, etc.) | +| `src/lib/game/types.ts` | 516 | TypeScript type definitions | Type definitions should be split by domain | +| `src/components/game/tabs/CraftingTab.tsx` | 965 | Crafting UI | Single component handling all crafting phases | +| `src/lib/game/crafting-slice.ts` | 847 | Old crafting store | Legacy file; newer version exists at `stores/craftingSlice.ts` | +| `src/lib/game/data/enchantment-effects.ts` | 846 | Enchantment effect definitions | Large but focused; acceptable as data file | +| `src/components/game/tabs/DebugTab.tsx` | 700 | Debug tools UI | Catch-all debug panel; could split by feature | +| `src/lib/game/store/craftingSlice.ts` | 644 | New crafting store | Cleaner but still combines state with business logic | + +### Moderate (Should Refactor) + +| File | Lines | Purpose | Issue | +|------|-------|---------|-------| +| `src/lib/game/attunements.ts` | 567 | Attunement system (OLD) | **DEAD CODE** - new version at `data/attunements.ts` | +| `src/components/game/tabs/GrimoireTab.tsx` | 567 | Pact system UI | Combines memory, pacts, boons | +| `src/components/game/StatsTab.tsx` | 551 | Stats display (OLD) | Too many unrelated stat categories | +| `src/components/game/tabs/StatsTab.tsx` | 545 | Stats display (NEW) | Same issues as above | +| `src/lib/game/stores/gameStore.ts` | 509 | Game coordinator store | Still coordinates too many systems | +| `src/lib/game/computed-stats.ts` | 492 | Computed statistics | Mixes utilities with stat calculations | +| `src/lib/game/data/golems.ts` | 471 | Golem definitions | Focused, acceptable size | +| `src/lib/game/data/equipment.ts` | 468 | Equipment definitions | Data file, acceptable size | +| `src/app/page.tsx` | 465 | Main game page | Should be thin shell; currently imports everything | +| `src/components/game/LootInventory.tsx` | 460 | Loot inventory UI | Handles multiple inventory types | +| `src/components/game/SkillsTab.tsx` | 418 | Skills UI (OLD) | Combines display with upgrade dialog | +| `src/components/game/GameContext.tsx` | 405 | Game context provider | Monolithic context combining all stores | +| `src/lib/game/upgrade-effects.ts` | 402 | Upgrade effect computation | Focused, acceptable | +| `src/components/game/tabs/EquipmentTab.tsx` | 393 | Equipment UI | Acceptable size | +| `src/lib/game/utils.ts` | 372 | Game utilities | Grown to include significant game logic | +| `src/components/game/tabs/SkillsTab.tsx` | 369 | Skills UI (NEW) | Same as old version | +| `src/lib/game/store/skillSlice.ts` | 346 | Skill store slice (OLD) | Legacy; newer version exists | +| `src/components/game/tabs/SpireTab.tsx` | 345 | Spire progression UI | Acceptable size | +| `src/components/game/tabs/GolemancyTab.tsx` | 338 | Golem management UI | Acceptable size | +| `src/lib/game/stores/skillStore.ts` | 332 | Skill store (NEW) | Acceptable size | +| `src/lib/game/store/computed.ts` | 322 | Computed values (OLD) | Legacy computed values | +| `src/components/game/SpireTab.tsx` | 320 | Spire UI (OLD) | Duplicate of tabs/ version | + +### Test Files Over 300 Lines (Acceptable) + +- `src/lib/game/store.test.ts` - 1042 lines +- `src/lib/game/__tests__/skills.test.ts` - 588 lines +- `src/lib/game/stores/__tests__/store-methods.test.ts` - 583 lines +- `src/lib/game/stores/index.test.ts` - 571 lines +- `src/lib/game/skills.test.ts` - 542 lines +- `src/lib/game/stores.test.ts` - 494 lines +- `src/lib/game/stores/__tests__/stores.test.ts` - 458 lines +- `src/lib/game/__tests__/skill-system.test.ts` - 347 lines + +--- + +## Phase 1: TODO/FIXME and Unimplemented Features + +### TODO/FIXME Comments + +**No TODO or FIXME comments found in the codebase.** + +### Unimplemented Special Effects + +The following special effects are **registered but never applied** in game logic: + +#### 1. `spellEcho10` (Enchantment Effect) +- **Location:** `src/lib/game/data/enchantment-effects.ts:530` +- **Definition:** 10% chance to cast a spell twice +- **Issue:** `hasSpecial(effects, 'spellEcho10')` is never checked in combat logic +- **Severity:** Medium - Equipment enchantment doesn't work + +#### 2. `worldThread` and `worldWeb` (Skill Upgrades) +- **Location:** `src/lib/game/skill-evolution.ts:1662,1670` +- **Definitions:** + - `worldThread`: "Enchantments also apply 5% as world effects" + - `worldWeb`: "Enchantments also apply 10% as world effects" +- **Issue:** These specialIds are never checked with `hasSpecial()` +- **Severity:** High - Major feature gap ("world effects" mechanic unimplemented) + +#### 3. Weapon Enchantment Specials +All defined but never checked: + +| Special ID | Location | Purpose | +|------------|----------|---------| +| `fireBlade` | `constants.ts:864`, `enchantment-effects.ts:781` | Burn enemies | +| `frostBlade` | `constants.ts:877`, `enchantment-effects.ts:791` | Prevent enemy dodge | +| `lightningBlade` | `constants.ts:890`, `enchantment-effects.ts:801` | Pierce 30% armor | +| `voidBlade` | `constants.ts:903`, `enchantment-effects.ts:811` | +20% damage | + +- **Severity:** High - Weapon enchantment system broken + +#### 4. `comboMaster` (Special Effect) +- **Location:** `src/lib/game/upgrade-effects.ts:97,396` +- **Definition:** Every 5th attack deals 3x damage +- **Issue:** Hit counter tracking status unclear; combat handler may not check this +- **Severity:** Low - Implementation status unclear + +### Effects Applied but Never Read + +#### 1. `weaponManaMax` and `weaponManaRegen` +- **Location:** `src/lib/game/data/enchantment-effects.ts:566-616` +- **Issue:** Bonuses stored in `equipmentEffects.bonuses` but never read in `computeAllEffects()` +- **Severity:** Medium - Weapon mana system incomplete + +#### 2. `insightGainMultiplier` from Equipment +- **Location:** `src/lib/game/effects.ts:127-129` +- **Issue:** Stored via type assertion but never read in `calcInsight()` +- **Severity:** Medium - Insight bonus from equipment doesn't work + +#### 3. `guardianDamageMultiplier` from Equipment +- **Location:** `src/lib/game/effects.ts:131-132` +- **Issue:** Stored but unclear if ever read +- **Severity:** Low - Needs investigation + +--- + +## Phase 1: Dead Code Analysis + +### Confirmed Dead Code (Safe to Remove) + +| File | Reason | Evidence | +|------|--------|----------| +| `src/lib/game/attunements.ts` | Old attunement system | No imports; new version at `data/attunements.ts` | +| `src/lib/game/navigation-slice.ts` | Old navigation system | No imports anywhere | +| `src/lib/db.ts` | Prisma client | No imports; possibly planned backend feature | +| `src/components/game/ComboMeter.tsx` | Unused component | No imports; references non-existent `ComboState` type | +| `src/components/game/layout/GameFooter.tsx` | Unused component | No imports | +| `src/components/game/shared/GameOverScreen.tsx` | Unused component | No imports | +| `src/components/game/shared/MemorySlotPicker.tsx` | Unused component | Only used by GameOverScreen | + +### Duplicate Code to Clean + +| Location | Issue | Action | +|----------|-------|--------| +| `src/components/game/types.ts` | Duplicate formatting functions | Remove; use `src/lib/game/formatting.ts` instead | +| `src/lib/game/store.ts` | Functions duplicated in `utils.ts` and `computed-stats.ts` | Consolidate during refactoring | + +### Flagged for Review (String References/Dynamic Imports) + +#### UI Components (Possibly Unused) +Many shadcn/ui components in `src/components/ui/` have no direct imports: +- `aspect-ratio.tsx`, `avatar.tsx`, `breadcrumb.tsx`, `calendar.tsx`, `carousel.tsx`, `chart.tsx`, `checkbox.tsx`, `collapsible.tsx`, `command.tsx`, `context-menu.tsx`, `drawer.tsx`, `dropdown-menu.tsx`, `form.tsx`, `hover-card.tsx`, `input-otp.tsx`, `label.tsx`, `menubar.tsx`, `navigation-menu.tsx`, `pagination.tsx`, `popover.tsx`, `radio-group.tsx`, `resizable.tsx`, `scroll-area.tsx` (USED), `select.tsx` (USED), `separator.tsx` (USED), `sheet.tsx`, `skeleton.tsx`, `slider.tsx`, `sonner.tsx`, `switch.tsx` (USED), `table.tsx`, `textarea.tsx`, `toggle.tsx`, `toggle-group.tsx` + +**Note:** These might be used dynamically or via string references. Review before removing. + +#### Test File Duplication +- `src/lib/game/skills.test.ts` (tests old store) +- `src/lib/game/store.test.ts` (tests old store) +- `src/lib/game/__tests__/skills.test.ts` (newer) +- `src/lib/game/stores/__tests__/store-methods.test.ts` (newer) +- `src/lib/game/stores/__tests__/stores.test.ts` (newer) + +**Recommendation:** Old test files may be redundant if new tests provide adequate coverage. + +--- + +## Architecture Notes + +### Store Migration In Progress +The codebase shows an active migration from: +- **Old:** Monolithic `src/lib/game/store.ts` (2464 lines) +- **New:** Modular stores in `src/lib/game/stores/` (gameStore.ts, combatStore.ts, etc.) + +Current status: Mixed usage - some components still import from old store. + +### Data vs Logic Separation +Good separation in `src/lib/game/data/` for: +- `attunements.ts` +- `crafting-recipes.ts` +- `enchantment-effects.ts` +- `equipment.ts` +- `golems.ts` +- `loot-drops.ts` +- `achievements.ts` + +--- + +## Recommended Action Plan + +### Phase 2: Safe Deletions (High Priority) +1. Delete `src/lib/game/attunements.ts` +2. Delete `src/lib/game/navigation-slice.ts` +3. Delete `src/lib/db.ts` +4. Delete `src/components/game/ComboMeter.tsx` +5. Delete `src/components/game/layout/GameFooter.tsx` +6. Delete `src/components/game/shared/GameOverScreen.tsx` +7. Delete `src/components/game/shared/MemorySlotPicker.tsx` +8. Clean duplicate formatting functions from `src/components/game/types.ts` + +### Phase 3: Refactor Large Files (Medium Priority) +1. **store.ts (2464 lines):** Complete migration to modular stores +2. **skill-evolution.ts (2312 lines):** Split by skill category +3. **constants.ts (1436 lines):** Split into domain-specific data files +4. **types.ts (516 lines):** Split by domain +5. **CraftingTab.tsx (965 lines):** Split by crafting phase +6. **page.tsx (465 lines):** Make thin shell +7. **GameContext.tsx (405 lines):** Simplify or remove need for monolithic context + +### Phase 4: Implement Missing Effects (High Priority) +1. Implement weapon enchantment specials (`fireBlade`, `frostBlade`, `lightningBlade`, `voidBlade`) +2. Implement `worldThread`/`worldWeb` ("world effects" mechanic) +3. Wire up `spellEcho10` in combat logic +4. Apply `weaponManaMax`/`weaponManaRegen` or remove +5. Use `insightGainMultiplier` in `calcInsight()` +6. Verify `comboMaster` implementation + +### Phase 5: Cleanup (Low Priority) +1. Review and remove unused UI components +2. Consolidate test files +3. Review relationship between `effects.ts` and `upgrade-effects.ts` + +--- + +## Verification Checklist + +After each phase: +- [ ] Game builds without errors +- [ ] Game runs correctly in browser +- [ ] All tabs functional +- [ ] No console errors +- [ ] Tests pass (if any) +- [ ] Commit and push changes + +--- + +**Next Steps:** Begin Phase 2 - Safe Deletions diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx deleted file mode 100755 index 4a8cca4..0000000 --- a/src/components/ui/accordion.tsx +++ /dev/null @@ -1,66 +0,0 @@ -"use client" - -import * as React from "react" -import * as AccordionPrimitive from "@radix-ui/react-accordion" -import { ChevronDownIcon } from "lucide-react" - -import { cn } from "@/lib/utils" - -function Accordion({ - ...props -}: React.ComponentProps) { - return -} - -function AccordionItem({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -function AccordionTrigger({ - className, - children, - ...props -}: React.ComponentProps) { - return ( - - svg]:rotate-180", - className - )} - {...props} - > - {children} - - - - ) -} - -function AccordionContent({ - className, - children, - ...props -}: React.ComponentProps) { - return ( - -
{children}
-
- ) -} - -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx deleted file mode 100755 index 1421354..0000000 --- a/src/components/ui/alert.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const alertVariants = cva( - "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", - { - variants: { - variant: { - default: "bg-card text-card-foreground", - destructive: - "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -function Alert({ - className, - variant, - ...props -}: React.ComponentProps<"div"> & VariantProps) { - return ( -
- ) -} - -function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { - return ( -
- ) -} - -function AlertDescription({ - className, - ...props -}: React.ComponentProps<"div">) { - return ( -
- ) -} - -export { Alert, AlertTitle, AlertDescription } diff --git a/src/components/ui/aspect-ratio.tsx b/src/components/ui/aspect-ratio.tsx deleted file mode 100755 index 3df3fd0..0000000 --- a/src/components/ui/aspect-ratio.tsx +++ /dev/null @@ -1,11 +0,0 @@ -"use client" - -import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" - -function AspectRatio({ - ...props -}: React.ComponentProps) { - return -} - -export { AspectRatio } diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx deleted file mode 100755 index 71e428b..0000000 --- a/src/components/ui/avatar.tsx +++ /dev/null @@ -1,53 +0,0 @@ -"use client" - -import * as React from "react" -import * as AvatarPrimitive from "@radix-ui/react-avatar" - -import { cn } from "@/lib/utils" - -function Avatar({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -function AvatarImage({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -function AvatarFallback({ - className, - ...props -}: React.ComponentProps) { - return ( - - ) -} - -export { Avatar, AvatarImage, AvatarFallback } diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx deleted file mode 100755 index eb88f32..0000000 --- a/src/components/ui/breadcrumb.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { ChevronRight, MoreHorizontal } from "lucide-react" - -import { cn } from "@/lib/utils" - -function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { - return