--- name: architecture-philosophy description: Core architectural principles for StepLeague - modular design, system thinking, future-proofing, and maintenance reduction. Use when designing new features, refactoring code, considering implementation approaches, or making any architectural decisions. Keywords: architecture, design, modular, refactoring, reusable, shadcn, maintenance, future-proof, system. compatibility: Antigravity, Claude Code, Cursor metadata: version: "1.1" project: "stepleague" --- # Architecture Philosophy Skill > **THE MOST IMPORTANT SKILL:** This skill defines HOW we build everything. > Every other skill references these principles. --- ## ⚠️ Critical: Read This First Before implementing ANY solution: 1. **Think systems, not solutions** - Will this pattern be needed elsewhere? 2. **Check existing patterns** - Is this already solved in the codebase? 3. **Consider maintenance** - How many places need updating when requirements change? 4. **Reference other skills** - They encode project-specific implementations of these principles --- ## Core Principles Every solution in StepLeague must follow these principles: ### 1. 🧩 Modular Over Monolithic (MOST CRITICAL) **Build systems, not one-off solutions.** > If you're writing code that solves just ONE specific case, you're probably doing it wrong. > Take 5 extra minutes to think: "How can I make this reusable?" | ❌ One-Off (BAD) | ✅ Modular System (GOOD) | |------------------|--------------------------| | Hardcoded notification for leagues | Generic notification system with event types | | Custom dropdown for one form | Reusable `FormSelect` component | | Inline error handling | Centralized `AppError` system in `src/lib/errors.ts` | | Magic numbers (`if (count > 50)`) | Settings from `app_settings` table | | Duplicate validation logic | Shared Zod schemas in `/lib/schemas/` | **Questions to ask BEFORE writing code:** - Will this pattern be needed elsewhere? → Extract it - Can I extend an existing utility/hook/component? → Extend, don't duplicate - Does this belong in a shared location? → Move it to `/lib/` or `/components/ui/` - Am I hardcoding a value that might change? → Use settings ### 2. 🔮 Future-Thinking **Design for tomorrow, implement for today.** - **Settings over hardcoding**: Use `app_settings` table for configurable values - **Feature flags**: Gate new features with `useFeatureFlag()` - **Extensible schemas**: Add columns that allow future use cases ```typescript // ❌ WRONG: Hardcoded limit const MAX_PROXIES = 10; // ✅ CORRECT: Configurable const maxProxies = useAppSettings('proxy_max_per_user', 10); ``` ### 3. 🛡️ Defensive Programming **Assume things will fail. Plan for it.** - **Use the error handling system** - Reference `error-handling` skill - **Graceful degradation** - If a feature fails, don't crash the page - **Fallback values** - Always have sensible defaults ```typescript // ✅ Defensive pattern with fallback const branding = await getCachedBranding().catch(() => DEFAULT_BRANDING); ``` ### 4. 📉 Maintenance Reduction **Less code = less bugs = less maintenance.** | Principle | Example | |-----------|---------| | Use existing libraries | shadcn/ui over custom components | | Central configuration | `badges.ts` for all badge colors | | Registry patterns | `CacheRegistry` for cache tags | | Convention over configuration | File-based routing | --- ## Mandatory Patterns ### A. Use shadcn/ui Components **ALWAYS prefer shadcn over custom implementations.** ```typescript // ✅ Use shadcn import { Dialog } from "@/components/ui/dialog"; import { DropdownMenu } from "@/components/ui/dropdown-menu"; import { toast } from "@/hooks/use-toast"; // ❌ Don't create custom modals, dropdowns, or alerts ``` **Installed shadcn components:** - `toast`, `dialog`, `dropdown-menu`, `input`, `label` - `textarea`, `select`, `checkbox`, `tooltip` - `confirm-dialog` (custom wrapper) Reference: `src/components/ui/` ### B. Use Reusable Form Components **Reference the `form-components` skill.** ```typescript // ✅ Use form fields import { FormInput, FormSelect, FormCheckbox } from "@/components/ui/form-fields"; // ❌ Don't use raw ,