Coverage Summary for Class: GoalContributionEntity (com.georgeci.moneysurfer.data.db.entity)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| GoalContributionEntity |
100%
(1/1)
|
100%
(2/2)
|
|
100%
(11/11)
|
100%
(53/53)
|
package com.georgeci.moneysurfer.data.db.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
/**
* One signed movement against a [GoalEntity] — negative is a withdrawal.
*
* The goal FK cascades: deleting a goal drops its contributions locally. That
* happens silently, so the repository enqueues the matching outbox deletes
* itself; Firestore has no cascade.
*/
@Entity(
tableName = "goal_contributions",
foreignKeys = [
ForeignKey(
entity = WorkspaceEntity::class,
parentColumns = ["id"],
childColumns = ["workspaceId"],
),
ForeignKey(
entity = GoalEntity::class,
parentColumns = ["id"],
childColumns = ["goalId"],
onDelete = ForeignKey.CASCADE,
),
],
indices = [Index("workspaceId"), Index("goalId")],
)
data class GoalContributionEntity(
@PrimaryKey
@ColumnInfo(name = "id") val id: String,
@ColumnInfo(name = "workspaceId") val workspaceId: String,
@ColumnInfo(name = "goalId") val goalId: String,
/** Signed minor units — negative is a withdrawal. */
@ColumnInfo(name = "amount") val amount: Long,
/** ISO-8601 date. */
@ColumnInfo(name = "occurredOn") val occurredOn: String,
@ColumnInfo(name = "note") val note: String,
/** Always null in v1 — reserved for the money-backed model. */
@ColumnInfo(name = "transferId") val transferId: String? = null,
@ColumnInfo(name = "createdAt", defaultValue = "0") val createdAt: Long = 0L,
@ColumnInfo(name = "updatedAt", defaultValue = "0") val updatedAt: Long = 0L,
)