package org.terst.feedreader.data import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey @Entity(tableName = "feeds") data class FeedEntity( @PrimaryKey val id: String, // the feed URL itself -- naturally unique, no need for a separate id scheme val title: String, val siteUrl: String? = null, // the human-facing site link, if the feed provides one (distinct from the feed XML URL) val lastFetchedAt: Long? = null, val etag: String? = null, // conditional-GET caching (If-None-Match) to avoid re-downloading unchanged feeds val lastModified: String? = null, // conditional-GET caching (If-Modified-Since) val lastError: String? = null, // set when a fetch fails; cleared on the next successful fetch val folder: String? = null, // OPML category/outline this feed was imported under, if any -- null for ungrouped feeds val readerModeEnabled: Boolean = false // per-feed opt-IN, set only by explicitly tapping the reader-mode // toggle (never automatic/heuristic) -- once on, articles from this feed default to the // extracted view and auto-extract on open instead of requiring a per-article tap each time. ) @Entity(tableName = "articles") data class ArticleEntity( @PrimaryKey val id: String, // guid if the feed provides one, else a hash of the link @ColumnInfo(index = true) override val feedId: String?, // null for a standalone article saved via the share-sheet target, not tied to any feed override val title: String, val link: String, val author: String? = null, val publishedAt: Long? = null, val feedContentHtml: String? = null, // whatever content the feed itself provided (may be a summary, may be full text) val extractedContent: String? = null, // Readability-extracted full text, filled in on first read if feedContentHtml was thin val imageUrl: String? = null, // thumbnail, from media:thumbnail/enclosure or the first in the feed content -- see FeedParser val isRead: Boolean = false, val readAt: Long? = null, // when isRead flipped true; null while unread or after an explicit "mark unread". Lets a just-read article linger in the Unread view until the next fetch instead of vanishing the instant it's read -- see observeUnread/observeOlderUnread. val isSaved: Boolean = false, // explicitly kept (independent of read state) -- triggers a Stash save val stashArtifactId: String? = null, // set once successfully archived to Stash; null means not yet saved or save failed val createdAt: Long ) : Titled enum class FilterAction { MUTE, HIGHLIGHT } @Entity(tableName = "filter_rules") data class FilterRuleEntity( @PrimaryKey(autoGenerate = true) val id: Long = 0, val pattern: String, // plain substring match, case-insensitive -- see FilterRuleEngine val action: FilterAction, val feedId: String? = null, // null applies globally across all feeds val createdAt: Long )