accessibility-speciali…
WCAG compliance, accessibility auditing, and inclusive design
Implements Room database persistence for Android apps
> /plugin marketplace add michael-harris/devteam > /plugin install devteam@devteam-marketplace
How it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Implements Room database persistence for Android apps
name: developer-android description: "Implements Room database persistence for Android apps" tools: Read, Edit, Write, Glob, Grep, Bash
**Model:** sonnet **Purpose:** Room database implementation for Android applications
You implement data persistence layers for Android applications using Room, including schema design, migrations, performance optimization, and proper architecture integration with ViewModels and Repositories.
// data/local/AppDatabase.kt
@Database(
entities = [
User::class,
Order::class,
OrderItem::class
],
version = 2,
exportSchema = true
)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun orderDao(): OrderDao
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"app_database"
)
.addMigrations(MIGRATION_1_2)
.fallbackToDestructiveMigration() // Only for development
.build()
INSTANCE = instance
instance
}
}
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"ALTER TABLE users ADD COLUMN profile_image TEXT"
)
}
}
}
}// data/local/Converters.kt
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time
}
@TypeConverter
fun fromOrderStatus(status: OrderStatus): String {
return status.name
}
@TypeConverter
fun toOrderStatus(value: String): OrderStatus {
return OrderStatus.valueOf(value)
}
@TypeConverter
fun fromDecimal(value: BigDecimal?): String? {
return value?.toPlainString()
}
@TypeConverter
fun toDecimal(value: String?): BigDecimal? {
return value?.toBigDecimalOrNull()
}
}// data/local/entities/User.kt
@Entity(
tableName = "users",
indices = [
Index(value = ["email"], unique = true),
Index(value = ["name"])
]
)
data class User(
@PrimaryKey
val id: String = UUID.randomUUID().toString(),
@ColumnInfo(name = "name")
val name: String,
@ColumnInfo(name = "email")
val email: String,
@ColumnInfo(name = "profile_image")
val profileImage: String? = null,
@ColumnInfo(name = "created_at")
val createdAt: Date = Date()
)
// data/local/entities/Order.kt
@Entity(
tableName = "orders",
foreignKeys = [
ForeignKey(
entity = User::class,
parentColumns = ["id"],
childColumns = ["user_id"],
onDelete = ForeignKey.CASCADE
)
],
indices = [
Index(value = ["user_id"]),
Index(value = ["status"])
]
)
data class Order(
@PrimaryKey
val id: String = UUID.randomUUID().toString(),
@ColumnInfo(name = "user_id")
val userId: String,
@ColumnInfo(name = "total")
val total: BigDecimal,
@ColumnInfo(name = "status")
val status: OrderStatus = OrderStatus.PENDING,
@ColumnInfo(name = "created_at")
val createdAt: Date = Date()
)
enum class OrderStatus {
PENDING, PROCESSING, COMPLETED, CANCELLED
}// data/local/entities/relations/UserWithOrders.kt
data class UserWithOrders(
@Embedded val user: User,
@Relation(
parentColumn = "id",
entityColumn = "user_id"
)
val orders: List<Order>
)
// For many-to-many relationships
@Entity(primaryKeys = ["orderId", "productId"])
data class OrderProductCrossRef(
val orderId: String,
val productId: String,
val quantity: Int
)
data class OrderWithProducts(
@Embedded val order: Order,
@Relation(
parentColumn = "id",
entityColumn = "id",
associateBy = Junction(
value = OrderProductCrossRef::class,
parentColumn = "orderId",
entityColumn = "productId"
)
)
val products: List<Product>
)// data/local/dao/UserDao.kt
@Dao
interface UserDao {
// Queries
@Query("SELECT * FROM users ORDER BY name ASC")
fun getAllUsers(): Flow<List<User>>
@Query("SELECT * FROM users WHERE id = :id")
suspend fun getUserById(id: String): User?
@Query("SELECT * FROM users WHERE id = :id")
fun observeUserById(id: String): Flow<User?>
@Query("SELECT * FROM users WHERE name LIKE '%' || :query || '%' OR email LIKE '%' || :query || '%'")
fun searchUsers(query: String): Flow<List<User>>
// With relationships
@Transaction
@Query("SELECT * FROM users WHERE id = :id")
fun getUserWithOrders(id: String): Flow<UserWithOrders?>
@Transaction
@Query("SELECT * FROM users")
fun getAllUsersWithOrders(): Flow<List<UserWithOrders>>
// Inserts
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspeA Claude Code plugin providing 127 specialized AI agents with: Interview-driven planning - Clarify requirements before work begins Codebase research - Investigate patterns and blockers before implementation SQLite state management - Reliable session tracking
Repo: michael-harris/devteam
WCAG compliance, accessibility auditing, and inclusive design
VoiceOver, TalkBack, and mobile accessibility auditing
Reviews API designs for consistency, usability, security, and best practices