BusinessCard/ai_implmentation.md

228 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AI Implementation Context
This file summarizes project-specific context, architecture, and conventions to speed up future AI work.
## Project Summary
BusinessCard is a SwiftUI app for building and sharing digital business cards with QR codes. It includes iOS screens for cards, sharing, customization, contact tracking, and widget previews, plus a watchOS companion to show a default card QR code.
## Key Constraints
- iOS 26+, watchOS 12+, Swift 6.2.
- SwiftUI with `@Observable` classes and `@MainActor`.
- Protocoloriented 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.
- Uses **Bedrock** package for shared design system and utilities.
## Core Data Flow
- `AppState` owns:
- `CardStore` (cards and selection)
- `ContactsStore` (contact list + search)
- `ShareLinkService` (share URLs)
- **SwiftData** with CloudKit for persistence and sync.
- **App Groups** for iOS-Watch data sharing.
- Views read state via environment and render UI only.
## Dependencies
### Bedrock Package
Located at `/Frameworks/Bedrock` (local package). Provides:
- `Design.Spacing`, `Design.CornerRadius`, `Design.Opacity`, etc.
- `QRCodeGenerator` and `QRCodeImageView` for QR codes
- Reusable settings components
App-specific extensions are in `Design/DesignConstants.swift`:
- `Design.CardSize` - card dimensions, avatar, QR sizes
- `Design.Shadow.offsetNone` - zero offset extension
- `Color.AppBackground`, `Color.CardPalette`, `Color.AppAccent`, `Color.AppText`
## Important Files
### Models
- `Models/BusinessCard.swift` — SwiftData model with:
- Name fields: prefix, firstName, middleName, lastName, maidenName, suffix, preferredName
- Basic fields: role, company, email, phone, website, location
- Rich fields: pronouns, bio, headline, accreditations (comma-separated tags)
- **Dynamic contact fields**: `@Relationship` to array of `ContactField` objects
- Legacy fields: social links (LinkedIn, Twitter, etc.) for backward compatibility
- Photos: `photoData` (profile), `coverPhotoData` (banner background), `logoData` (company logo) stored with `@Attribute(.externalStorage)`
- Computed: `theme`, `layoutStyle`, `vCardPayload`, `orderedContactFields`
- Helper methods: `addContactField`, `removeContactField`, `reorderContactFields`
- `Models/ContactField.swift` — SwiftData model for dynamic contact fields:
- Properties: `typeId`, `value`, `title`, `orderIndex`
- Relationship: `card` (inverse to BusinessCard)
- Computed: `fieldType`, `displayName`, `iconImage()`, `iconColor`, `buildURL()`
- Supports multiple fields of same type, drag-to-reorder
- `Models/ContactFieldType.swift` — Struct defining 30+ field types:
- Categories: contact, social, developer, messaging, payment, creator, scheduling, other
- Properties: `id`, `displayName`, `systemImage`, `isCustomSymbol`, `iconColor`
- Properties: `valueLabel`, `valuePlaceholder`, `titleSuggestions`, `keyboardType`
- Method: `iconImage()` — returns correct Image (asset vs SF Symbol)
- Method: `urlBuilder` — closure to build deep link URLs
- Static instances: `.email`, `.phone`, `.linkedIn`, `.twitter`, `.instagram`, etc.
- Uses custom assets from `Assets.xcassets/SocialSymbols/`
- `Models/Contact.swift` — SwiftData model with:
- Basic fields: name, role, company
- Annotations: notes, tags (comma-separated), followUpDate, whereYouMet
- Received cards: isReceivedCard, email, phone
- Photo: `photoData` stored with `@Attribute(.externalStorage)` - editable via PhotosPicker in ContactDetailView and AddContactSheet
- Computed: `tagList`, `hasFollowUp`, `isFollowUpOverdue`
- Static: `fromVCard(_:)` parser
- `Models/CardTheme.swift` — card theme palette
- `Models/CardLayoutStyle.swift` — stacked/split/photo
- `Models/AppTab.swift` — tab bar enum
### Protocols (POP)
- `Protocols/BusinessCardProviding.swift` — card selection interface
- `Protocols/ContactTracking.swift` — contact management interface
- `Protocols/ShareLinkProviding.swift` — share URL generation interface
### State
- `State/AppState.swift` — central state container
- `State/CardStore.swift` — card CRUD, selection, watch sync
- `State/ContactsStore.swift` — contacts, search, received cards
### Services
- `Services/ShareLinkService.swift` — share URL helpers
- `Services/WatchSyncService.swift` — App Group sync to watch
### Views
Main screens:
- `Views/RootTabView.swift` — tabbed shell (3 tabs: My Cards, Contacts, Widgets) + floating share button
- `Views/CardsHomeView.swift` — full-screen swipeable card view with edit button
- `Views/ShareCardView.swift` — QR + share actions + track share (opened as sheet from floating button)
- `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 for 3 image types (profile, cover, logo)
- `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
- `ContactFieldPickerView.swift` — grid picker for selecting contact field types
- `ContactFieldsManagerView.swift` — orchestrates picker + added fields list
- `AddedContactFieldsView.swift` — displays added fields with drag-to-reorder
- `PhotoSourcePicker.swift` — generic photo source picker sheet (library, camera, remove)
- `CameraCaptureView.swift` — UIImagePickerController wrapper for camera capture
Sheets (in `Views/Sheets/`):
- `RecordContactSheet.swift` — track share recipient
- `ContactFieldEditorSheet.swift` — add/edit contact field with type-specific UI
- `AddContactSheet.swift` — manually add a new contact
- `PhotoCropperSheet.swift` — 2-step photo editor with pinch-to-zoom and square crop
Small utilities:
- `Views/EmptyStateView.swift` — empty state placeholder
- `Views/PrimaryActionButton.swift` — styled action button
### Assets
- `Assets.xcassets/SocialSymbols/` — custom brand icons as `.symbolset` files:
- Social: linkedin, x-twitter, instagram, facebook, tiktok, threads, bluesky, mastodon, reddit, twitch
- Developer: github.fill
- Messaging: telegram, discord.fill, slack, matrix
- Creator: patreon.fill, ko-fi
**Icon Rendering:**
- Custom symbols use `Image("symbolName")` (asset catalog)
- SF Symbols use `Image(systemName: "symbolName")`
- `ContactFieldType.isCustomSymbol` flag determines which to use
- `ContactFieldType.iconImage()` returns the correct Image type
### Design + Localization
- `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 |
|------|-------|--------|
| ContactFieldType | ~650 | 30+ field definitions, acceptable |
| CardEditorView | ~520 | Complex form + field manager, acceptable |
| BusinessCardView | ~320 | Clickable fields + legacy fallback, acceptable |
| QRScannerView | ~310 | Camera + parsing, acceptable |
| ShareCardView | ~235 | Good |
| ContactDetailView | ~235 | Good |
| ContactsView | ~220 | Good |
| CardsHomeView | ~150 | Full-screen swipeable cards, good |
| AddedContactFieldsView | ~135 | Drag-to-reorder, good |
| ContactFieldPickerView | ~100 | Grid picker, good |
| All others | <110 | Good |
## Localization
- All user-facing strings are in `.xcstrings`.
- Supported locales: en, esMX, frCA.
- Use `String.localized("Key")` for non-Text strings.
## Testing
- `BusinessCardTests/BusinessCardTests.swift` covers:
- vCard payload formatting
- Card CRUD operations
- Contact search and filtering
- Social links detection
- Contact notes/tags
- Follow-up status
- vCard parsing for received cards
## Known Stubs / TODOs
- Apple Wallet and NFC flows are alert-only placeholders.
- Share URLs are sample placeholders.
- Widget previews are not WidgetKit extensions.
- See `ROADMAP.md` for full feature status.
## If You Extend The App
1. Add new strings to the String Catalogs.
2. Use `Design.*` from Bedrock for spacing, opacity, etc.
3. Add app-specific constants to `DesignConstants.swift`.
4. Keep view logic UI-only; push business logic to state classes.
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.