Add first launch event, share tracking for overview PDF and diagram exports. Add SystemOverviewPDFExporter for A4 PDF generation. Update charger model with new configuration fields and localization for all 5 languages. Refresh app icon assets and CLAUDE.md build instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build & Test Commands
Use the Xcode MCP server tools instead of xcodebuild CLI:
- List windows first: Always run
mcp__xcode__XcodeListWindowsto find the correcttabIdentifier— it changes depending on which Xcode windows are open. - Build:
mcp__xcode__BuildProject - Run all tests:
mcp__xcode__RunAllTests - Check errors:
mcp__xcode__GetBuildLog(severity:error) ormcp__xcode__XcodeListNavigatorIssues
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. Translation files are in *.lproj/Localizable.strings and Localizable.stringsdict.
- Use
String(localized:defaultValue:)— notNSLocalizedString. ThedefaultValueserves as English fallback and avoids showing raw keys when a Localizable.strings entry is missing. - When adding new user-facing strings, add translations to all 5 Localizable.strings files immediately.
PDF Export Pattern
PDF exports use UIGraphicsPDFRenderer with A4 portrait format. The pattern is:
- Exporter struct (e.g.
SystemOverviewPDFExporter,SystemBillOfMaterialsPDFExporter) with snapshot data types — keeps Core Graphics rendering isolated from SwiftUI/SwiftData. - ShareSheet triggered via
@Stateitem binding in the parent view. - Toolbar button (not inline content) for the export action.
StoreKit
Subscription product IDs: app.voltplan.cable.weekly, app.voltplan.cable.yearly. Pro features are gated via StoreKitManager.isPro.