From 9bd4216867db3b2b3ebdcabc618deb9f68138399 Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Fri, 2 Oct 2026 19:30:18 +0200 Subject: [PATCH] feat(projects): the repository reads a project and what is in it Phase 6 of docs/project-feature.md. Six methods on `MantraRepository`, with `DatabaseMantraRepository` behind them and `NO_OP` returning empty for previews. The two contents queries return the versions rather than the join rows. No screen wants a join row, and the DAO resolves it in one indexed query instead of leaving an N+1 in a view model. Both inverses are here too -- which projects a version is part of -- because an artifact's own screen is where "what is this for" gets asked. Nothing in `MantraDao`. That path -- `addDialect`, `addArtifactVersion`, `rumorOf`, `submitToGroup` -- is the old submit flow, reached now only from its own test, and every entity a member creates is proposed for signing instead. An `addProject` there would be a second way to create a project that bypasses the quorum, which is the thing this feature is for. No query by creator or owner. Both are columns and a screen that wants them has the row; `getProjectsOwnedBy` would be a query with one caller and an index to go with it, and a room's project list is short. Add it when a screen asks. Co-Authored-By: Claude Opus 5 --- .../repository/DatabaseMantraRepository.kt | 30 ++++++++++++ .../compose/repository/MantraRepository.kt | 46 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt index 74552762..8eafb679 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/database/repository/DatabaseMantraRepository.kt @@ -9,6 +9,7 @@ import press.mantra.compose.database.model.MantraArtifactVersion import press.mantra.compose.database.model.MantraChapter import press.mantra.compose.database.model.MantraChunk import press.mantra.compose.database.model.MantraDialect +import press.mantra.compose.database.model.MantraProject import press.mantra.compose.database.model.MantraTranslationArtifactVersion import press.mantra.compose.database.model.MantraTranslationChapter import press.mantra.compose.database.model.MantraTranslationChunk @@ -41,6 +42,35 @@ class DatabaseMantraRepository( override suspend fun getChaptersForArtifactVersion(artifactVersionId: String): List = database.mantraChapterDao().getChaptersByArtifactVersionId(artifactVersionId) + override suspend fun getProjects(chatRoomId: String): List = + database.mantraProjectDao().getProjectsByChatRoomId(chatRoomId) + + override suspend fun getProject(id: String): MantraProject? = + database.mantraProjectDao().getProjectById(id) + + override suspend fun getProjectArtifactVersions( + projectId: String + ): List = + database.mantraProjectArtifactVersionDao().getArtifactVersionsByProjectId(projectId) + + override suspend fun getProjectTranslationArtifactVersions( + projectId: String + ): List = + database.mantraProjectTranslationArtifactVersionDao() + .getTranslationArtifactVersionsByProjectId(projectId) + + override suspend fun getProjectsForArtifactVersion( + artifactVersionId: String + ): List = + database.mantraProjectArtifactVersionDao() + .getProjectsByArtifactVersionId(artifactVersionId) + + override suspend fun getProjectsForTranslationArtifactVersion( + translationArtifactVersionId: String + ): List = + database.mantraProjectTranslationArtifactVersionDao() + .getProjectsByTranslationArtifactVersionId(translationArtifactVersionId) + override suspend fun getChapter(id: String): MantraChapter? = database.mantraChapterDao().getChapterById(id) diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt index 677998d6..3d197ad5 100644 --- a/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt +++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/repository/MantraRepository.kt @@ -6,6 +6,7 @@ import press.mantra.compose.database.model.MantraArtifactVersion import press.mantra.compose.database.model.MantraChapter import press.mantra.compose.database.model.MantraChunk import press.mantra.compose.database.model.MantraDialect +import press.mantra.compose.database.model.MantraProject import press.mantra.compose.database.model.MantraTranslationArtifactVersion import press.mantra.compose.database.model.MantraTranslationChapter import press.mantra.compose.database.model.MantraTranslationChunk @@ -56,6 +57,31 @@ interface MantraRepository { suspend fun getDialect(id: String): MantraDialect? + suspend fun getProjects(chatRoomId: String): List + + suspend fun getProject(id: String): MantraProject? + + /** + * The source versions a project is translating from. + * + * The versions, not the join rows: no screen wants a join row, and resolving + * it here is one indexed query instead of an N+1 in a view model. + */ + suspend fun getProjectArtifactVersions(projectId: String): List + + /** The translations a project is producing. */ + suspend fun getProjectTranslationArtifactVersions( + projectId: String + ): List + + /** The inverse: which projects a source version is part of. */ + suspend fun getProjectsForArtifactVersion(artifactVersionId: String): List + + /** The inverse again, for a translation. */ + suspend fun getProjectsForTranslationArtifactVersion( + translationArtifactVersionId: String + ): List + suspend fun addArtifactVersion( localChatRoom: LocalChatRoom, artifactId: HexKey, @@ -102,6 +128,26 @@ interface MantraRepository { override suspend fun getDialect(id: String): MantraDialect? = null + override suspend fun getProjects(chatRoomId: String): List = emptyList() + + override suspend fun getProject(id: String): MantraProject? = null + + override suspend fun getProjectArtifactVersions( + projectId: String + ): List = emptyList() + + override suspend fun getProjectTranslationArtifactVersions( + projectId: String + ): List = emptyList() + + override suspend fun getProjectsForArtifactVersion( + artifactVersionId: String + ): List = emptyList() + + override suspend fun getProjectsForTranslationArtifactVersion( + translationArtifactVersionId: String + ): List = emptyList() + override suspend fun addArtifactVersion( localChatRoom: LocalChatRoom, artifactId: HexKey,