Claude-skill-registry architecture-philosophy
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.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/architecture-philosophy" ~/.claude/skills/majiayu000-claude-skill-registry-architecture-philosophy && rm -rf "$T"
skills/data/architecture-philosophy/SKILL.mdArchitecture 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:
- Think systems, not solutions - Will this pattern be needed elsewhere?
- Check existing patterns - Is this already solved in the codebase?
- Consider maintenance - How many places need updating when requirements change?
- 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 component |
| Inline error handling | Centralized system in |
Magic numbers () | Settings from table |
| Duplicate validation logic | Shared Zod schemas in |
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
or/lib//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
table for configurable valuesapp_settings - Feature flags: Gate new features with
useFeatureFlag() - Extensible schemas: Add columns that allow future use cases
// ❌ 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
skillerror-handling - Graceful degradation - If a feature fails, don't crash the page
- Fallback values - Always have sensible defaults
// ✅ 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 | for all badge colors |
| Registry patterns | for cache tags |
| Convention over configuration | File-based routing |
Mandatory Patterns
A. Use shadcn/ui Components
ALWAYS prefer shadcn over custom implementations.
// ✅ 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
,inputlabel
,textarea
,select
,checkboxtooltip
(custom wrapper)confirm-dialog
Reference:
src/components/ui/
B. Use Reusable Form Components
Reference the
skill.form-components
// ✅ Use form fields import { FormInput, FormSelect, FormCheckbox } from "@/components/ui/form-fields"; // ❌ Don't use raw <input>, <select> elements
C. Use the API Handler Pattern
Reference the
skill.api-handler
// ✅ Use withApiHandler export const POST = withApiHandler({ auth: 'required', schema: mySchema, }, async ({ user, body, adminClient }) => { return { success: true }; }); // ❌ Don't write boilerplate auth checks in every route
D. Use the Error System
Reference the
skill.error-handling
// ✅ Use AppError throw new AppError({ code: ErrorCode.VALIDATION_FAILED, message: 'Invalid input', context: { field: 'email' }, recoverable: true, }); // ❌ Don't throw generic Error objects
E. Use CSS Variables for Theming
Reference the
skill.design-system
// ✅ Semantic variables <div className="bg-card text-foreground border-border"> // ❌ Hardcoded Tailwind colors <div className="bg-slate-900 text-slate-300 border-slate-700">
Decision Framework
When implementing any feature, follow this checklist:
Before Writing Code
- Check existing patterns in AGENTS.md
- Search for similar implementations in the codebase
- Review relevant skills in
.agent/skills/ - Consider: Is this a one-off or a pattern?
While Writing Code
- Extract reusable pieces into utilities/components
- Use centralized configuration (settings, registries)
- Add proper error handling with AppError
- Follow the design system for all UI
After Writing Code
- Update documentation if adding new patterns
- Add to design system page if creating UI components
- Reference in AGENTS.md if it's a key pattern
- Create a skill if it's complex enough
Cross-Skill References
| When Working On | Reference Skill |
|---|---|
| New features | |
| API routes | |
| Database queries | |
| Error handling | |
| UI/Styling | |
| Forms | |
| After completion | |
Anti-Patterns to Avoid
1. The "Quick Fix"
"I'll just add this inline, it's faster"
Why it's bad: Creates tech debt, makes code harder to maintain.
Instead: Take 5 extra minutes to do it properly.
2. The "Special Case"
"This component is unique, it needs custom styling"
Why it's bad: Breaks consistency, harder to theme.
Instead: Use existing components, extend if needed.
3. The "Magic Number"
if (count > 50) { ... }
Why it's bad: Unexplained, not configurable.
Instead: Use settings or named constants.
4. The "Silenced Error"
try { ... } catch { /* ignore */ }
Why it's bad: Hides bugs, makes debugging impossible.
Instead: Use
normalizeError() and reportErrorClient().
5. The "Copy-Paste Component"
Creating a new component that's 90% the same as existing one.
Why it's bad: Duplicated code, inconsistent behavior.
Instead: Extract shared logic, use props for variations.
The 3-Time Rule
If you do something 3 times, extract it.
| Count | Action |
|---|---|
| 1st time | Implement inline |
| 2nd time | Note the pattern |
| 3rd time | Extract to utility/component/skill |
Key Reference Files
| Area | File |
|---|---|
| Error handling | |
| API handler | |
| Form components | |
| Badge config | |
| Cache registry | |
| Menu config | |
| Theme variables | |
| Settings hook | |
Summary
Build systems, not solutions.
Every feature you implement should make the next feature easier to build.