fix: use sex column for Desire Sync question filtering instead of fragile ID pattern

This commit is contained in:
null 2026-06-18 00:32:39 -05:00
parent c0696cfb80
commit 2677e38514
9 changed files with 30 additions and 14 deletions

View File

@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "7d88101b5a057ac275bdc43a65fb2380", "identityHash": "7e7d78fcca52e788c28d1d1090c6d608",
"entities": [ "entities": [
{ {
"tableName": "question", "tableName": "question",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `text` TEXT NOT NULL, `category_id` TEXT NOT NULL, `depth_level` INTEGER NOT NULL, `is_premium` INTEGER NOT NULL, `type` TEXT NOT NULL, `tags` TEXT NOT NULL, `answer_config` TEXT NOT NULL, `pack_id` TEXT, `created_at` INTEGER NOT NULL, `status` TEXT NOT NULL, PRIMARY KEY(`id`))", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `text` TEXT NOT NULL, `category_id` TEXT NOT NULL, `depth_level` INTEGER NOT NULL, `is_premium` INTEGER NOT NULL, `type` TEXT NOT NULL, `tags` TEXT NOT NULL, `answer_config` TEXT NOT NULL, `pack_id` TEXT, `created_at` INTEGER NOT NULL, `status` TEXT NOT NULL, `sex` TEXT, PRIMARY KEY(`id`))",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -73,6 +73,12 @@
"columnName": "status", "columnName": "status",
"affinity": "TEXT", "affinity": "TEXT",
"notNull": true "notNull": true
},
{
"fieldPath": "sex",
"columnName": "sex",
"affinity": "TEXT",
"notNull": false
} }
], ],
"primaryKey": { "primaryKey": {
@ -298,7 +304,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7d88101b5a057ac275bdc43a65fb2380')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7e7d78fcca52e788c28d1d1090c6d608')"
] ]
} }
} }

Binary file not shown.

View File

@ -27,8 +27,8 @@ interface QuestionDao {
@Query("SELECT * FROM question WHERE type IN ('single_choice', 'this_or_that', 'scale') AND status = 'active'") @Query("SELECT * FROM question WHERE type IN ('single_choice', 'this_or_that', 'scale') AND status = 'active'")
suspend fun getQuestionsForPrediction(): List<QuestionEntity> suspend fun getQuestionsForPrediction(): List<QuestionEntity>
@Query("SELECT * FROM question WHERE id LIKE :pattern AND status = 'active'") @Query("SELECT * FROM question WHERE sex = :sex AND status = 'active'")
suspend fun getDesireSyncQuestions(pattern: String): List<QuestionEntity> suspend fun getDesireSyncQuestions(sex: String): List<QuestionEntity>
@Query("SELECT * FROM question WHERE is_premium = 0 AND status = 'active'") @Query("SELECT * FROM question WHERE is_premium = 0 AND status = 'active'")
suspend fun getFreeQuestions(): List<QuestionEntity> suspend fun getFreeQuestions(): List<QuestionEntity>

View File

@ -16,5 +16,6 @@ data class QuestionEntity(
@ColumnInfo(name = "answer_config") val answerConfig: String, @ColumnInfo(name = "answer_config") val answerConfig: String,
@ColumnInfo(name = "pack_id") val packId: String?, @ColumnInfo(name = "pack_id") val packId: String?,
@ColumnInfo(name = "created_at") val createdAt: Long, @ColumnInfo(name = "created_at") val createdAt: Long,
@ColumnInfo val status: String @ColumnInfo val status: String,
@ColumnInfo val sex: String? = null
) )

View File

@ -28,7 +28,8 @@ fun QuestionEntity.toQuestion(): Question {
answerConfig = parseAnswerConfig(answerConfig, type), answerConfig = parseAnswerConfig(answerConfig, type),
packId = packId, packId = packId,
createdAt = createdAt, createdAt = createdAt,
status = status status = status,
sex = sex
) )
} }

View File

@ -48,6 +48,6 @@ class RoomQuestionRepository @Inject constructor(
} }
override suspend fun getDesireSyncQuestions(sex: String): List<Question> { override suspend fun getDesireSyncQuestions(sex: String): List<Question> {
return questionDao.getDesireSyncQuestions("sexual_preferences_${sex}_%").map { it.toQuestion() } return questionDao.getDesireSyncQuestions(sex).map { it.toQuestion() }
} }
} }

View File

@ -64,5 +64,6 @@ data class Question(
val answerConfig: AnswerConfig? = null, val answerConfig: AnswerConfig? = null,
val packId: String? = null, val packId: String? = null,
val createdAt: Long = System.currentTimeMillis(), val createdAt: Long = System.currentTimeMillis(),
val status: String = "active" val status: String = "active",
val sex: String? = null
) )

View File

@ -130,8 +130,10 @@ class DesireSyncViewModel @Inject constructor(
.onFailure { Log.w(TAG, "load male failed", it) } .onFailure { Log.w(TAG, "load male failed", it) }
.getOrElse { emptyList() } .getOrElse { emptyList() }
val maleById = male.associateBy { it.id.replace("_male_", "_") } val filteredFemale = female.filter { it.sex == "female" }
val pairs = female val filteredMale = male.filter { it.sex == "male" }
val maleById = filteredMale.associateBy { it.id.replace("_male_", "_") }
val pairs = filteredFemale
.filter { isBinaryQuestion(it) } .filter { isBinaryQuestion(it) }
.shuffled() .shuffled()
.take(SESSION_SIZE) .take(SESSION_SIZE)

View File

@ -60,6 +60,7 @@ def build_database(json_dir: str, output_path: str) -> None:
pack_id TEXT, pack_id TEXT,
created_at INTEGER NOT NULL, created_at INTEGER NOT NULL,
status TEXT NOT NULL, status TEXT NOT NULL,
sex TEXT,
PRIMARY KEY (id) PRIMARY KEY (id)
) )
''') ''')
@ -198,12 +199,15 @@ def build_database(json_dir: str, output_path: str) -> None:
tags_json = json.dumps(tags, separators=(',', ':')) tags_json = json.dumps(tags, separators=(',', ':'))
ac_json_str = json.dumps(ac_json, separators=(',', ':')) ac_json_str = json.dumps(ac_json, separators=(',', ':'))
# Extract optional sex field (used for Desire Sync filtering)
sex = q.get('sex')
# Insert question # Insert question
cursor.execute(''' cursor.execute('''
INSERT OR REPLACE INTO Question INSERT OR REPLACE INTO Question
(id, text, category_id, depth_level, is_premium, type, tags, answer_config, (id, text, category_id, depth_level, is_premium, type, tags, answer_config,
created_at, status) created_at, status, sex)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', ( ''', (
question_id, question_id,
text, text,
@ -214,7 +218,8 @@ def build_database(json_dir: str, output_path: str) -> None:
tags_json, tags_json,
ac_json_str, ac_json_str,
int(json_file.stat().st_mtime), # Use file mtime as created_at int(json_file.stat().st_mtime), # Use file mtime as created_at
'active' 'active',
sex
)) ))
questions_inserted += 1 questions_inserted += 1