@Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertAll(components: List<ComponentEntity>)

@Entity(tableName = "components") data class ComponentEntity( @PrimaryKey val id: String, // e.g. "rune_ember" val name: String, val type: ComponentType, val rarity: Int, // 1..5 val iconRes: Int // @DrawableRes )

7.1 Repository Skeleton @Singleton class SpellRepository @Inject constructor( private val spellDao: SpellDao, private val componentDao: ComponentDao, private val api: SpellApi, @ApplicationContext private val ctx: Context ) { // Local flow val allSpells: Flow<List<SpellEntity>> = spellDao.observeAll()

| Rule | Explanation | |------|-------------| | Rarity Sum ≤ 10 | Prevent “over‑powered” spells. | | At least one RUNE | Guarantees a magical core. | | No duplicate component IDs | Each slot must be unique. | | Mana Cost = (Rarity × 10) + (type‑bonus) | Runes × 5, Reagents × 3, Gestures × 2. | | Name Generation | <Rune.name> + “ of ” + <Gesture.name> (fallback to generic). | | Description | Auto‑generated from component lore strings. |

private fun synthesizeSpell(): SpellEntity require(canSynthesize()) val rune = currentComponents.first it?.type == ComponentType.RUNE !! val gesture = currentComponents.first it?.type == ComponentType.GESTURE !!

@Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(spell: SpellEntity)