- Show BOM button for unsaved loads (no longer requires save first) - Set US fallback affiliate tag for unknown countries - Localize Amazon search queries in all 5 languages (EN/DE/ES/FR/NL) - Add affiliate URL/country fields to SavedBattery model - Auto-detect unit system (imperial for US locale, metric otherwise) - Set charger input voltage based on locale (120V US, 230V EU) - Remove StoreKitManager and CableProPaywallView - Add CLAUDE.md project instructions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build & Test Commands
# Build
xcodebuild -scheme Cable -destination 'platform=iOS Simulator,name=iPhone 15' build
# Run all tests (unit + UI)
xcodebuild -scheme Cable -destination 'platform=iOS Simulator,name=iPhone 15' test
# Run only unit tests
xcodebuild -scheme Cable -destination 'platform=iOS Simulator,name=iPhone 15' -only-testing:CableTests test
# Open in Xcode (preferred for UI iteration with previews)
open Cable.xcodeproj
Requires Xcode 15+ and iOS 17 simulator. No external dependencies beyond the Xcode toolchain.
Architecture
SwiftUI + SwiftData app for sizing low-voltage electrical conductors (boats, RVs, off-grid).
Data Model Hierarchy
ElectricalSystem (top-level container) owns collections of:
SavedLoad— individual electrical loads with wire sizing parametersSavedBattery— battery banks with chemistry-specific capacity rulesSavedCharger— charging equipment specs
All are @Model classes persisted via SwiftData. The container is configured in CableApp.swift and injected into the SwiftUI environment.
Key Layers
- Calculation engine (
Loads/ElectricalCalculations.swift): Pure static functions for wire cross-section sizing, voltage drop, power loss, and fuse recommendations. Uses copper resistivity (0.017 Ω·mm²/m) with a 5% max voltage drop constraint. Supports both metric (mm²) and imperial (AWG) wire standards. - CableCalculator (
Loads/CableCalculator.swift): ObservableObject wrapper that bridges the calculation engine to SwiftUI views. - App-wide state:
UnitSystemSettings(metric/imperial, persisted to UserDefaults) andStoreKitManager(subscription status) are injected as@EnvironmentObject.
Navigation Flow
SystemsView (root list) → LoadsView (per-system TabView with 4 tabs: Overview, Components, Batteries, Chargers) → individual editor modals for each entity type.
Feature Organization
Each feature has its own directory under Cable/: Loads/, Systems/, Batteries/, Chargers/, Overview/, Paywall/. Models and views for each feature live together.
Code Style
- 4-space indentation, trailing commas on multiline collections, 120-char soft line limit
UpperCamelCasefor types,lowerCamelCasefor methods/properties- Test naming:
testScenario_expectedResult - Commit messages: short imperative subjects under 50 characters
Localization
5 languages: English (base), German, Spanish, French, Dutch. UI strings use String(localized:). Translation files are in *.lproj/Localizable.strings and Localizable.stringsdict.
StoreKit
Subscription product IDs: app.voltplan.cable.weekly, app.voltplan.cable.yearly. Pro features are gated via StoreKitManager.isPro.