Primary sync: replace PersistenceActor JSON file with SwiftData + CloudKit - Add SavedCardModel (@Model class) and PersistenceController (ModelContainer with .automatic CloudKit, fallback to local). BackgroundPersistenceActor (@ModelActor) handles all DB I/O off the main thread. - One-time migration imports user_collection.json into SwiftData and renames the original file to prevent re-import. - Inject modelContainer into SwiftUI environment in IYmtgApp. Image storage: Documents/UserContent/ subfolder (blueprint requirement) - ImageManager.dir now targets iCloud Documents/UserContent/ (or local equiv). - migrateImagesToUserContent() moves existing JPGs to the new subfolder on first launch; called during the SwiftData migration. Firebase: demoted to optional manual backup (metadata only, no images) - Remove all automatic CloudEngine.save/delete/batchUpdatePrices calls from CollectionViewModel mutations. - Add backupAllToFirebase() for user-triggered metadata sync. - Add isFirebaseBackupEnabled to AppConfig (default false). - Add Cloud Backup section in Library settings with iCloud vs Firebase explanation and "Backup Metadata to Firebase Now" button. Also: full modular refactor (Data/, Features/, Services/ directories) and README updated with CloudKit setup steps and revised release checklist. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
322 lines
18 KiB
Markdown
322 lines
18 KiB
Markdown
# IYmtg Platinum Prime (Version 1.0.0)
|
|
**SYSTEM CONTEXT FOR AI (STRICT PRESERVATION)**
|
|
CRITICAL INSTRUCTION: This document is the single, authoritative Source of Truth for "IYmtg," an iOS application designed to identify, grade, and insure Magic: The Gathering cards.
|
|
|
|
* **Version Authority:** This Version 1.0.0 supersedes all previous iterations.
|
|
* **Architecture Mandate:** Any future updates must strictly adhere to the defined pipeline: Vector Fingerprinting (Identity) -> OCR (Validation) -> ML Analysis (Condition/Foil).
|
|
* **Preservation Protocol:** Do not summarize, truncate, or remove sections of this manual during review.
|
|
|
|
## Part 1: App Store Listing
|
|
|
|
### 1. Metadata
|
|
* **App Name:** IYmtg: Card Scanner & Insurance
|
|
* **Subtitle:** Identify, Grade & Insure Magic
|
|
* **Category:** Reference / Utilities
|
|
* **Keywords:** magic,gathering,scanner,tcg,card,price,insurance,manager,grade,foil,mtg,free,offline
|
|
* **Device Orientation:** Strictly lock to Portrait in Xcode.
|
|
|
|
### 2. Description
|
|
**Headline:** The Easiest Way to Insure Your Magic Collection.
|
|
|
|
**Body:**
|
|
Your Magic: The Gathering collection represents years of history and passion. Losing it to theft, fire, or disaster is a nightmare scenario. IYmtg is the first app built specifically to make **insuring your collection** simple, fast, and accurate.
|
|
|
|
Forget complex spreadsheets and manual entry. Just point your camera, and IYmtg handles the rest. It identifies the card, grades the condition, detects foiling, and fetches the market price instantly. When you're done, one tap generates a professional **Insurance Schedule PDF** ready for your agent.
|
|
|
|
**Why IYmtg?**
|
|
* 📄 **Insurance Ready:** Generate a timestamped, itemized PDF Schedule in seconds.
|
|
* ⚡ **Effortless Scanning:** Auto-detects Set, Condition, and Foil type (including Etched, Galaxy, and more).
|
|
* 🔒 **Private & Secure:** Your data is backed up, but your images stay private in iCloud.
|
|
* ✅ **Simple & Clean:** No ads, no subscriptions, just a powerful tool for collectors.
|
|
|
|
**Development Transparency:**
|
|
This application's code and visual assets were developed with the assistance of Artificial Intelligence. This modern approach allows us to deliver a sophisticated, high-performance tool dedicated to a single goal: helping collectors manage, grade, and insure their valuable history with precision and ease.
|
|
|
|
**Community Data Initiative:**
|
|
Help us make IYmtg smarter! If you find a card that scans incorrectly, you can correct it in the app. When you do, you'll have the option to securely send that image to our training database. Your contributions directly improve the AI models for the entire community.
|
|
|
|
**Features:**
|
|
* **Insurance Reports:** Export your entire collection to a PDF ready for your insurance agent.
|
|
* **Collection Valuation:** Monitor the total value of your collection with real-time market data.
|
|
* **Smart Scanning:** Identify cards, foils, and condition automatically.
|
|
* **Cloud Sync:** Keep your collection safe and accessible across your devices.
|
|
* **Offline Access:** Scan and manage your cards even without an internet connection.
|
|
* **Market Data:** Switch between major pricing sources (TCGPlayer & Cardmarket).
|
|
* **Export Options:** Also supports CSV and digital deck formats for other uses.
|
|
|
|
## Part 2: Workspace & Assets
|
|
|
|
### Step 1: Workspace Setup
|
|
1. Create the master folder on your Desktop.
|
|
2. Right-click -> Sync with Google Drive (Critical for backups).
|
|
3. Organize your sub-folders exactly as shown below:
|
|
|
|
```text
|
|
IYmtg_Master/
|
|
├── IYmtg_App_iOS/ (The Xcode Project)
|
|
├── IYmtg_Builder_Mac/ (The Database Builder)
|
|
├── IYmtg_Training/ (ML Image Data)
|
|
└── IYmtg_Automation/ (Python/Shell Scripts)
|
|
```
|
|
|
|
## 2. Visual Assets
|
|
|
|
Place the following assets in `Assets.xcassets` in the Xcode project.
|
|
|
|
**Important:** AI tools often generate large files (e.g., 2048x2048). You **must resize and crop** the results to the dimensions listed below. For the AppIcon, exact 1024x1024 dimensions are mandatory.
|
|
|
|
| Asset Name | Dimensions | Description | Gemini Generation Prompt |
|
|
| :--- | :--- | :--- | :--- |
|
|
| **AppIcon** | 1024x1024 | App Icon. | "A high-quality iOS app icon. A stylized neon green cybernetic eye scanning a dark, mystical trading card silhouette. Dark purple and black background. Minimalist, sleek, modern technology meets fantasy magic. No text. Square aspect ratio." |
|
|
| **logo_header** | 300x80 | Header Logo. | "A typographic logo for an app named 'IYmtg'. Horizontal layout. Neon green text, futuristic sans-serif font. Dark background. The text should be glowing. High contrast. Aspect ratio 4:1." |
|
|
| **scanner_frame** | 600x800 | Viewfinder. | "A HUD viewfinder overlay for a camera app. Glowing white bracket corners. Thin, high-tech lines connecting corners. Center is empty. Sci-fi interface style. Pure white lines on a solid black background. Aspect ratio 3:4." |
|
|
| **empty_library** | 800x800 | Empty State. | "Isometric 3D render of a clean, empty wooden desk. A single Magic: The Gathering style card sits in the center. Soft warm lighting. Minimalist design. High resolution. No text. Square aspect ratio." |
|
|
| **share_watermark** | 400x100 | Watermark. | "A watermark logo text 'Verified by IYmtg'. White text with a checkmark icon. Clean, bold font. Solid black background. Professional verification seal style. Aspect ratio 4:1." |
|
|
| **card_placeholder**| 600x840 | Loading State. | "A generic trading card back design. Grey and silver swirl pattern. Mystical and abstract. No text. Aspect ratio 2.5:3.5." |
|
|
|
|
### Automated Resizing
|
|
We have provided a Python script to automatically crop and resize your AI-generated images to the exact dimensions required above.
|
|
|
|
1. **Setup:** Ensure you have Python installed and run `pip install Pillow`.
|
|
2. **Folders:** Run the script once to generate the `Raw_Assets` and `Ready_Assets` folders in `IYmtg_Master`.
|
|
3. **Generate Placeholders (Optional):** If you don't have AI images yet, run this script to create dummy files in `Raw_Assets` to test the pipeline.
|
|
```bash
|
|
python3 IYmtg_Automation/generate_placeholders.py
|
|
```
|
|
4. **Place Images:** Save your real AI results into `Raw_Assets` (overwrite the placeholders), naming them exactly as listed above (e.g., `AppIcon.png`).
|
|
5. **Run:** Execute the resize script:
|
|
```bash
|
|
python3 IYmtg_Automation/resize_assets.py
|
|
```
|
|
6. **Result:** Your Xcode-ready images will be in `Ready_Assets`. Drag them into `Assets.xcassets`.
|
|
|
|
## 3. Machine Learning Training
|
|
|
|
### **General Data Collection Protocol (CRITICAL)**
|
|
The app sends **cropped** images (just the card, no background) to the AI. Your training data must match this.
|
|
|
|
1. **Capture:** Take photos of the card on a contrasting background.
|
|
* **For Foils:** Take 3-5 photos of the *same card* at different tilt angles. The AI needs to see how the light moves across the surface (e.g., flat, tilted left, tilted back).
|
|
* **For Damage:** Ensure the lighting specifically highlights the defect (e.g., raking light for dents).
|
|
2. **Crop:** Crop the photo so **only the card** is visible (remove the table/background).
|
|
3. **Sort:** Place the cropped image into the corresponding folder in `IYmtg_Training`.
|
|
4. **Quantity:** Aim for 30-50 images per category for robust results.
|
|
|
|
### Step 1: The Master Foil Shopping List (Required for FoilEngine)
|
|
Acquire one of each (~$50 total) to train the Foil Classifier. This ensures the app can distinguish complex modern foil types.
|
|
|
|
| Foil Type | Recommended Card | Visual Key (For Substitutes) |
|
|
| :--- | :--- | :--- |
|
|
| **Traditional** | Any Common Foil | Standard rainbow reflection, smooth surface. |
|
|
| **Etched** | Harmonize (Strixhaven Archive) | Metallic, grainy texture, matte finish, no rainbow. |
|
|
| **Pre-Modern** | Opt (Dominaria Remastered - Retro) | Shooting star in text box, specific retro frame shine. |
|
|
| **Textured** | Rivaz of the Claw (Dominaria United) | Raised 3D pattern on surface, fingerprint-like feel. |
|
|
| **Gilded** | Riveteers Charm (New Capenna) | Embossed gold frame elements, glossy raised texture. |
|
|
| **Galaxy** | Command Performance (Unfinity) | Embedded "stars" or sparkles in the foil pattern. |
|
|
| **Surge** | Explore (Warhammer 40k) | Rippling "wave" pattern across the entire card. |
|
|
| **Silver Screen** | Otherworldly Gaze (Double Feature) | Grayscale art with silver metallic highlights. |
|
|
| **Oil Slick** | Basic Land (Phyrexia: ONE - Compleat) | Raised, slick black-on-black texture, high contrast. |
|
|
| **Confetti** | Negate (Wilds of Eldraine - Confetti) | Glittering "confetti" sparkles scattered on art. |
|
|
| **Halo** | Uncommon Legend (MOM: Multiverse) | Swirling circular pattern around the frame. |
|
|
| **Neon Ink** | Hidetsugu (Neon Yellow) | Bright, fluorescent ink layer on top of foil. |
|
|
| **Fracture** | Enduring Vitality (Duskmourn Japan) | Shattered glass pattern, highly reflective. |
|
|
|
|
### Step 2: The Stamp Classifier Shopping List
|
|
Acquire pairs of cards to train the `StampDetector` (Promo/Date Stamped vs. Regular). This is a **Binary Classifier**, meaning the AI learns by comparing "Yes" vs "No".
|
|
|
|
* **Prerelease Promos:** Any card with a Gold Date Stamp (e.g., "29 September 2018").
|
|
* **Promo Pack Cards:** Cards with the Planeswalker Symbol stamp in the bottom right of the art.
|
|
* **Purchase List:** Buy 50-100 cheap bulk promos (often <$0.25 each) and their non-promo counterparts.
|
|
* **Action:** Place cropped images of promos in `Stamp_Data/Stamped` and regular versions in `Stamp_Data/Clean`.
|
|
|
|
### Step 3: The "Damage Simulation Lab"
|
|
Techniques to ethically create training data using "Draft Chaff" (worthless cards).
|
|
|
|
| Category | Damage Type | Simulation Technique | Capture Tip (Crucial for ML) |
|
|
| :--- | :--- | :--- | :--- |
|
|
| **Surface** | Light Scratches | Rub foil surface gently with 0000 Steel Wool. | Use flash or moving light source to catch glint. |
|
|
| **Surface** | Clouding | Rub white eraser vigorously over foil surface. | Compare side-by-side with a clean card. |
|
|
| **Surface** | Dirt | Smudge lightly with potting soil or cocoa powder. | Ensure contrast against card art. |
|
|
| **Surface** | Dents | Press a ballpoint pen cap firmly into the surface. | **Raking Light:** Light from side to cast shadows. |
|
|
| **Edges** | Whitening | Rub card edges rapidly against denim jeans. | Photograph against a **Black Background**. |
|
|
| **Edges** | Chipping | Flake off small bits of black border. | Photograph against a **White Background**. |
|
|
| **Edges** | Corner Wear | Rub corners against a rough mousepad. | Macro focus on the corner radius. |
|
|
| **Structure** | Creases | Fold a corner until a hard line forms. | Catch the light reflection off the crease ridge. |
|
|
| **Structure** | Shuffle Bend | Riffle shuffle aggressively to create an arch. | Profile view (side view) to show curvature. |
|
|
| **Structure** | Water Damage | Mist with spray bottle, wait 60s, dry. | Catch the rippled surface texture with side light. |
|
|
| **Critical** | Inking | Use a Black Sharpie to "fix" whitened edges. | Use UV/Blacklight if possible, or bright white light. |
|
|
| **Critical** | Rips | Tear the edge slightly (approx. 5mm). | High contrast background. |
|
|
| **Critical** | Binders Dents | Press a 3-ring binder ring into the card. | Raking light to show the circular crimp. |
|
|
|
|
### Step 4: The "Edge Case" Validation List
|
|
Acquire these specific cheap cards to verify the logic-based detectors. **Note:** These are for **Manual Verification** (testing the app), not for Create ML training folders.
|
|
|
|
| Detector | Target Card Type | Recommended Purchase |
|
|
| :--- | :--- | :--- |
|
|
| **ListSymbol** | "The List" Reprint | Any common from "The List" (look for planeswalker symbol). |
|
|
| **Border** | World Champ Deck | Any 1996-2004 World Champ card (Gold Border). |
|
|
| **Border** | Chronicles Reprint | *City of Brass* (Chronicles) vs *City of Brass* (Modern Reprint). |
|
|
| **Corner** | Alpha/Beta Sim | *4th Edition* (Standard) vs *Alpha* (Proxy/Counterfeit for testing). |
|
|
| **Saturation** | Unl/Revised Sim | *Revised* Basic Land (Washed out) vs *4th Edition* (Saturated). |
|
|
|
|
### Step 5: Training Folder Structure
|
|
Create the following directory tree inside `IYmtg_Training` to organize your image data for Create ML.
|
|
|
|
```text
|
|
IYmtg_Training/
|
|
├── Foil_Data/ (Image Classification)
|
|
│ ├── NonFoil/
|
|
│ ├── Traditional/
|
|
│ ├── Etched/
|
|
│ ├── PreModern/
|
|
│ ├── Textured/
|
|
│ ├── Galaxy/
|
|
│ ├── Surge/
|
|
│ ├── OilSlick/
|
|
│ ├── StepAndCompleat/
|
|
│ ├── Halo/
|
|
│ ├── Confetti/
|
|
│ ├── NeonInk/
|
|
│ └── Fracture/
|
|
├── Stamp_Data/ (Image Classification)
|
|
│ ├── Stamped/
|
|
│ └── Clean/
|
|
└── Condition_Data/ (Object Detection)
|
|
├── Surface/
|
|
│ ├── LightScratches/
|
|
│ ├── Clouding/
|
|
│ ├── Dirt/
|
|
│ └── Dents/
|
|
├── Edges/
|
|
│ ├── Whitening/
|
|
│ ├── Chipping/
|
|
│ └── CornerWear/
|
|
├── Structure/
|
|
│ ├── Creases/
|
|
│ ├── ShuffleBend/
|
|
│ └── WaterDamage/
|
|
└── Critical/
|
|
├── Inking/
|
|
├── Rips/
|
|
└── BindersDents/
|
|
```
|
|
|
|
### Step 4: Create ML
|
|
1. **Foil Classifier:** Train an Image Classification model using `Foil_Data`. Export as `IYmtgFoilClassifier.mlmodel`.
|
|
2. **Condition Classifier:** Train an Object Detection model using `Condition_Data`. Export as `IYmtgConditionClassifier.mlmodel`.
|
|
3. **Import:** Drag both `.mlmodel` files into the Xcode Project Navigator.
|
|
|
|
## 4. Backend & Security
|
|
|
|
### Cloud Storage Architecture
|
|
The app uses a two-tier cloud strategy:
|
|
|
|
| Tier | Technology | What it stores | Cost |
|
|
| :--- | :--- | :--- | :--- |
|
|
| **Primary** | iCloud + CloudKit (SwiftData) | All card metadata, synced automatically across devices | Free (user's iCloud) |
|
|
| **Secondary** | Firebase Firestore | Metadata only — no images — optional manual backup | Free (Firestore free tier) |
|
|
|
|
Card images are stored in the user's iCloud Drive under `Documents/UserContent/` and are **never** uploaded to Firebase.
|
|
|
|
### iCloud / CloudKit Setup (Required for Primary Sync)
|
|
1. In Xcode, open **Signing & Capabilities**.
|
|
2. Add the **iCloud** capability. Enable **CloudKit**.
|
|
3. Add a CloudKit container named `iCloud.<your-bundle-id>`.
|
|
4. Add the **Background Modes** capability. Enable **Remote notifications**.
|
|
5. Set the minimum deployment target to **iOS 17** (required by SwiftData).
|
|
|
|
Without this setup the app falls back to local-only storage automatically.
|
|
|
|
### Firebase Configuration (Optional Secondary Backup)
|
|
Firebase is no longer the primary sync mechanism. It serves as a user-triggered metadata backup.
|
|
1. **Create Project:** Go to the Firebase Console and create a new project.
|
|
2. **Authentication:** Enable "Anonymous" sign-in in the Authentication tab.
|
|
3. **Firestore Database:** Create a database and apply the rules from `IYmtg_App_iOS/Firebase/firestore.rules`.
|
|
4. **Setup:** Download `GoogleService-Info.plist` from Project Settings and drag it into the `IYmtg_App_iOS` folder in Xcode (ensure "Copy items if needed" is checked).
|
|
5. Users trigger backup manually via **Library → Cloud Backup → Backup Metadata to Firebase Now**.
|
|
|
|
The app runs fully without `GoogleService-Info.plist` (Local Mode — iCloud sync still works).
|
|
|
|
### Over-the-Air (OTA) Model Updates
|
|
To update ML models without an App Store release:
|
|
1. Train your new model (e.g., `IYmtgFoilClassifier.mlmodel`).
|
|
2. Upload the `.mlmodel` file to Firebase Storage in the `models/` folder.
|
|
3. The app will automatically detect the newer file, download, compile, and hot-swap it on the next launch.
|
|
|
|
### Privacy Manifest
|
|
Ensure `PrivacyInfo.xcprivacy` is included in the app target to satisfy Apple's privacy requirements regarding file timestamps and user defaults.
|
|
|
|
## 5. Automation
|
|
|
|
Scripts are located in `IYmtg_Automation/`.
|
|
|
|
### Set Symbol Harvester
|
|
Fetches training data for set symbols from Scryfall.
|
|
|
|
```bash
|
|
pip install requests pillow
|
|
python3 IYmtg_Automation/fetch_set_symbols.py
|
|
```
|
|
|
|
### Weekly Update Script
|
|
Automates the build-and-deploy process for the database builder.
|
|
|
|
```bash
|
|
chmod +x IYmtg_Automation/weekly_update.sh
|
|
./IYmtg_Automation/weekly_update.sh
|
|
```
|
|
|
|
## 6. App Configuration
|
|
|
|
**CRITICAL:** Edit `IYmtg_App_iOS/AppConfig.swift` before building to ensure payments and support work correctly:
|
|
1. Set `contactEmail` to your real email address.
|
|
2. Set `tipJarProductIDs` to your actual In-App Purchase IDs.
|
|
3. `isFirebaseBackupEnabled` defaults to `false`. Users opt-in from Library settings.
|
|
|
|
## 7. Development Mode
|
|
|
|
To enable saving raw training images during scanning:
|
|
1. Add the compilation flag `ENABLE_DEV_MODE` in Xcode Build Settings.
|
|
2. Tap the "IYmtg" logo header 5 times in the app to activate.
|
|
|
|
## 8. Testing
|
|
|
|
The project includes a comprehensive unit test suite located in `IYmtgTests.swift`.
|
|
|
|
**How to Run:**
|
|
* Press `Cmd+U` in Xcode to execute the test suite.
|
|
|
|
**Scope:**
|
|
* **Models:** Verifies `SavedCard` initialization and data mapping.
|
|
* **Engines:** Tests logic for `ConditionEngine` (grading rules) and `ExportEngine` (CSV/Arena/MTGO formatting).
|
|
* **ViewModel:** Validates `ScannerViewModel` state management, including search filtering and portfolio value calculations.
|
|
|
|
**Note:** CoreML models are not loaded during unit tests to ensure speed and stability. The tests verify the *logic* surrounding the models (e.g., "If 3 scratches are detected, grade is Played") rather than the ML inference itself.
|
|
|
|
## 9. Release Checklist
|
|
|
|
Perform these steps before submitting to the App Store.
|
|
|
|
1. **Configuration Check:**
|
|
* [ ] Open `AppConfig.swift`.
|
|
* [ ] Verify `contactEmail` is valid.
|
|
* [ ] Verify `tipJarProductIDs` match App Store Connect.
|
|
* [ ] Ensure `enableFoilDetection` and other flags are `true`.
|
|
2. **iCloud / CloudKit:**
|
|
* [ ] Signing & Capabilities → iCloud → CloudKit enabled.
|
|
* [ ] CloudKit container added: `iCloud.<bundle-id>`.
|
|
* [ ] Background Modes → Remote notifications enabled.
|
|
* [ ] Minimum deployment target set to **iOS 17**.
|
|
3. **Assets:**
|
|
* [ ] Ensure `Assets.xcassets` has the AppIcon filled for all sizes.
|
|
4. **Testing:**
|
|
* [ ] Run Unit Tests (`Cmd+U`) - All must pass.
|
|
* [ ] Run on Physical Device - Verify Camera permissions prompt appears.
|
|
5. **Build:**
|
|
* [ ] Select "Any iOS Device (arm64)".
|
|
* [ ] Product -> Archive.
|
|
* [ ] Validate App in Organizer.
|
|
* [ ] Distribute App -> App Store Connect.
|
|
|
|
---
|
|
**Version Authority:** 1.0.0 |