From a164669cf2d3c68ad0a78e4afa9826b4104a95a4 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 8 Jan 2026 18:25:12 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- README.md | 20 ++++++--- ai_implmentation.md | 102 ++++++++++++++++++++++++++++++++------------ 2 files changed, 87 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index c978f7d..248ae2a 100644 --- a/README.md +++ b/README.md @@ -71,12 +71,15 @@ The iPhone app syncs card data to the paired Apple Watch via App Groups. When yo ## Architecture -- SwiftUI views are presentation only -- Shared app state uses `@Observable` classes on `@MainActor` -- SwiftData for persistence with CloudKit sync -- Protocol-oriented design for card data, sharing, and contact tracking -- String Catalogs (`.xcstrings`) for localization (en, es-MX, fr-CA) -- **Bedrock package** for shared design constants and utilities +- **Clean Architecture**: Clear separation between Views, State, Services, and Models +- **Views are dumb**: Presentation only, no business logic +- **State is smart**: `@Observable` classes with all business logic +- **Protocol-oriented**: Interfaces for services and stores +- **SwiftData + CloudKit**: Persistent storage with iCloud sync +- **One type per file**: Lean, maintainable files under 300 lines +- **Reusable components**: Shared UI in `Views/Components/` +- **Bedrock package**: Shared design system and utilities +- **String Catalogs**: Localization for en, es-MX, fr-CA ## Dependencies @@ -101,7 +104,10 @@ BusinessCard/ ├── Resources/ # String Catalogs (.xcstrings) ├── Services/ # Share link service, watch sync ├── State/ # Observable stores (CardStore, ContactsStore) -└── Views/ # SwiftUI screens and components +└── Views/ + ├── Components/ # Reusable UI components (AvatarBadgeView, etc.) + ├── Sheets/ # Modal sheets (RecordContactSheet, etc.) + └── [Feature].swift # Feature screens BusinessCardWatch/ # watchOS app target BusinessCardTests/ # Unit tests diff --git a/ai_implmentation.md b/ai_implmentation.md index 8f730c4..7215953 100644 --- a/ai_implmentation.md +++ b/ai_implmentation.md @@ -11,6 +11,8 @@ BusinessCard is a SwiftUI app for building and sharing digital business cards wi - iOS 26+, watchOS 12+, Swift 6.2. - SwiftUI with `@Observable` classes and `@MainActor`. - Protocol‑oriented architecture is prioritized. +- Clean Architecture with separation of concerns. +- One public type per file, keep files under 300 lines. - No UIKit unless explicitly requested. - String Catalogs only (`.xcstrings`). - No magic numbers in views; use Bedrock's `Design` constants. @@ -45,68 +47,109 @@ App-specific extensions are in `Design/DesignConstants.swift`: ### Models -- `BusinessCard/Models/BusinessCard.swift` — SwiftData model with: +- `Models/BusinessCard.swift` — SwiftData model with: - Basic fields: name, role, company, email, phone, website, location - Rich fields: pronouns, bio, social links (LinkedIn, Twitter, Instagram, etc.) - Custom links: 2 slots for custom URLs - Photo: `photoData` stored with `@Attribute(.externalStorage)` - Computed: `theme`, `layoutStyle`, `vCardPayload`, `hasSocialLinks` -- `BusinessCard/Models/Contact.swift` — SwiftData model with: +- `Models/Contact.swift` — SwiftData model with: - Basic fields: name, role, company - - Annotations: notes, tags (comma-separated), followUpDate, metAt - - Received cards: isReceivedCard, receivedCardData (vCard) + - Annotations: notes, tags (comma-separated), followUpDate, whereYouMet + - Received cards: isReceivedCard, email, phone - Photo: `photoData` - Computed: `tagList`, `hasFollowUp`, `isFollowUpOverdue` - Static: `fromVCard(_:)` parser -- `BusinessCard/Models/CardTheme.swift` — card theme palette -- `BusinessCard/Models/CardLayoutStyle.swift` — stacked/split/photo +- `Models/CardTheme.swift` — card theme palette +- `Models/CardLayoutStyle.swift` — stacked/split/photo +- `Models/AppTab.swift` — tab bar enum ### Protocols (POP) -- `BusinessCard/Protocols/BusinessCardProviding.swift` -- `BusinessCard/Protocols/ContactTracking.swift` -- `BusinessCard/Protocols/ShareLinkProviding.swift` +- `Protocols/BusinessCardProviding.swift` — card selection interface +- `Protocols/ContactTracking.swift` — contact management interface +- `Protocols/ShareLinkProviding.swift` — share URL generation interface ### State -- `BusinessCard/State/AppState.swift` — central state container -- `BusinessCard/State/CardStore.swift` — card CRUD, selection, watch sync -- `BusinessCard/State/ContactsStore.swift` — contacts, search, received cards +- `State/AppState.swift` — central state container +- `State/CardStore.swift` — card CRUD, selection, watch sync +- `State/ContactsStore.swift` — contacts, search, received cards ### Services -- `BusinessCard/Services/ShareLinkService.swift` — share URL helpers -- `BusinessCard/Services/WatchSyncService.swift` — App Group sync to watch +- `Services/ShareLinkService.swift` — share URL helpers +- `Services/WatchSyncService.swift` — App Group sync to watch ### Views -- `RootTabView.swift` — tabbed shell -- `CardsHomeView.swift` — hero + card carousel -- `CardEditorView.swift` — create/edit cards with PhotosPicker -- `BusinessCardView.swift` — card display with photo and social icons -- `ShareCardView.swift` — QR + share actions + track share -- `CustomizeCardView.swift` — theme/layout controls -- `ContactsView.swift` — tracking list with sections -- `ContactDetailView.swift` — full contact view with annotations -- `QRScannerView.swift` — camera-based QR scanner -- `QRCodeView.swift` — wrapper for Bedrock's QRCodeImageView -- `WidgetsView.swift` — preview mockups +Main screens: +- `Views/RootTabView.swift` — tabbed shell +- `Views/CardsHomeView.swift` — hero + card carousel +- `Views/ShareCardView.swift` — QR + share actions + track share +- `Views/CustomizeCardView.swift` — theme/layout controls +- `Views/ContactsView.swift` — contact list with sections +- `Views/WidgetsView.swift` — widget preview mockups + +Feature views: +- `Views/BusinessCardView.swift` — card display with layouts +- `Views/CardEditorView.swift` — create/edit cards with PhotosPicker +- `Views/ContactDetailView.swift` — full contact view with annotations +- `Views/QRScannerView.swift` — camera-based QR scanner +- `Views/QRCodeView.swift` — QR code image generator + +Reusable components (in `Views/Components/`): +- `AvatarBadgeView.swift` — circular avatar with photo or icon +- `IconRowView.swift` — icon + text row for details +- `LabelBadgeView.swift` — small badge labels +- `ActionRowView.swift` — generic action row with chevron + +Sheets (in `Views/Sheets/`): +- `RecordContactSheet.swift` — track share recipient + +Small utilities: +- `Views/EmptyStateView.swift` — empty state placeholder +- `Views/PrimaryActionButton.swift` — styled action button +- `Views/HeroBannerView.swift` — home page banner +- `Views/CardCarouselView.swift` — card scroll carousel +- `Views/WidgetsCalloutView.swift` — widget promotion callout ### Design + Localization -- `BusinessCard/Design/DesignConstants.swift` — extends Bedrock -- `BusinessCard/Resources/Localizable.xcstrings` -- `BusinessCard/Localization/String+Localization.swift` +- `Design/DesignConstants.swift` — extends Bedrock +- `Resources/Localizable.xcstrings` — string catalog +- `Localization/String+Localization.swift` — string helpers ### watchOS - `BusinessCardWatch/BusinessCardWatchApp.swift` - `BusinessCardWatch/Views/WatchContentView.swift` - `BusinessCardWatch/State/WatchCardStore.swift` +- `BusinessCardWatch/Models/WatchCard.swift` - `BusinessCardWatch/Resources/Localizable.xcstrings` +## File Guidelines + +### Size Limits +- Main views: aim for under 300 lines +- Extract reusable sub-views to `Components/` +- Extract sheets/modals to `Sheets/` +- Private structs in same file OK if under 50 lines + +### Current File Sizes +| File | Lines | Status | +|------|-------|--------| +| CardEditorView | ~420 | Complex form, acceptable | +| QRScannerView | ~310 | Camera + parsing, acceptable | +| BusinessCardView | ~245 | Multiple layouts, acceptable | +| ShareCardView | ~235 | Good | +| ContactDetailView | ~235 | Good | +| ContactsView | ~220 | Good | +| CustomizeCardView | ~170 | Good | +| All others | <110 | Good | + ## Localization - All user-facing strings are in `.xcstrings`. @@ -140,3 +183,6 @@ App-specific extensions are in `Design/DesignConstants.swift`: 5. Prefer protocols for new capabilities. 6. Add unit tests for new model logic. 7. Update `ROADMAP.md` when adding features. +8. **Keep files under 300 lines** — extract components when needed. +9. **No duplicate code** — check for existing components first. +10. **One public type per file** — private helpers OK if small.