feat(projects): three tables, schema 20 -> 21
Phase 2 of docs/project-feature.md. Still nothing that writes a row: this is the shape, the keys and the queries each screen will want. A project's contents are real foreign keys into this room's own rows, with CASCADE, like every reference in this family. That is the one-room scope decision made load-bearing rather than documented: a membership naming a version this device does not hold fails at insert, loudly, instead of landing as a row pointing at nothing that every later read has to be defensive about. Projects that span rooms take those keys away again -- Phase 9, following `parentChatRoomId`, which is deliberately not a foreign key because a dangling value is the normal state there -- and that is a migration rather than something to carry unused until then. `MantraProjectDaoJvmTest` asserts the refusal, which is also what says Room has foreign keys switched on at all. The owners are a comma-joined sorted string with an `ownerPublicKeySet()` accessor beside it, which is what `DkgSession.participantPublicKeys` already does with a set of keys, sort included and for the same reason. A fourth table would buy querying by owner, which no screen does. A set stored as text is a shape that rots, so the accessor is tested against spacing, empty entries and the single-entry case rather than the happy path. `fromProjectEvent` refuses an event with no name, no creator or no owners rather than filling the gap from local knowledge -- which is exactly the failure the tags exist to prevent. The empty-owner refusal does double duty: an owner list that comes back empty is what `ROLE_OWNER` missing from `KNOWN_ROLES` looks like from here, so the guard against a malformed event is also the alarm for that bug. No `toProjectEvent()`. Those eight rebuilds serve rooms whose work predates `GroupSignedEvent` at v13; projects arrive at v21, so every project this app will ever hold is on file as a signed event. Adding three more would be adding to a mechanism with a removal checklist already written for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d0a5ce50f
commit
7afda9cf80
10 files changed
+7062
-1
No files matched your search
@@ -29,6 +29,9 @@ import press.mantra.compose.database.dao.MantraChapterDao
|
||||
import press.mantra.compose.database.dao.MantraChunkDao
|
||||
import press.mantra.compose.database.dao.MantraDao
|
||||
import press.mantra.compose.database.dao.MantraDialectDao
|
||||
import press.mantra.compose.database.dao.MantraProjectArtifactVersionDao
|
||||
import press.mantra.compose.database.dao.MantraProjectDao
|
||||
import press.mantra.compose.database.dao.MantraProjectTranslationArtifactVersionDao
|
||||
import press.mantra.compose.database.dao.MantraTranslationArtifactVersionDao
|
||||
import press.mantra.compose.database.dao.MantraTranslationArtifactVersionContributorDao
|
||||
import press.mantra.compose.database.dao.MantraTranslationChapterDao
|
||||
@@ -81,6 +84,9 @@ 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.MantraProjectArtifactVersion
|
||||
import press.mantra.compose.database.model.MantraProjectTranslationArtifactVersion
|
||||
import press.mantra.compose.database.model.MantraTranslation
|
||||
import press.mantra.compose.database.model.MantraTranslationArtifactVersion
|
||||
import press.mantra.compose.database.model.MantraTranslationArtifactVersionContributor
|
||||
@@ -146,6 +152,9 @@ val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L)
|
||||
MantraChapter::class,
|
||||
MantraChunk::class,
|
||||
MantraDialect::class,
|
||||
MantraProject::class,
|
||||
MantraProjectArtifactVersion::class,
|
||||
MantraProjectTranslationArtifactVersion::class,
|
||||
MantraTranslation::class,
|
||||
MantraTranslationArtifactVersion::class,
|
||||
MantraTranslationArtifactVersionContributor::class,
|
||||
@@ -177,7 +186,7 @@ val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L)
|
||||
UnsignedNostrEvent::class,
|
||||
Zap::class
|
||||
],
|
||||
version = 20,
|
||||
version = 21,
|
||||
autoMigrations = [
|
||||
// v2 only adds the DkgSession/DkgParticipantMessage tables, so Room can
|
||||
// generate the migration itself — nothing existing changes shape.
|
||||
@@ -321,6 +330,22 @@ val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L)
|
||||
// which is what they were, and any identity may drain them. The broadcast
|
||||
// queue deliberately gets no owner: a signed event is anyone's to carry.
|
||||
AutoMigration(from = 19, to = 20),
|
||||
// v21 adds the three project tables -- a project, and one row per source
|
||||
// version or translation that is part of it. Three new tables and
|
||||
// nothing existing changes shape, so Room generates this itself.
|
||||
//
|
||||
// A project's contents are foreign keys into this room's own rows, with
|
||||
// CASCADE, like every other reference in this family. That is the
|
||||
// one-room scope decision made load-bearing: a membership naming a
|
||||
// version this device does not hold fails at insert rather than landing
|
||||
// as a row pointing at nothing. Projects that span rooms take those keys
|
||||
// away again -- see Phase 9 of docs/project-feature.md -- and that is a
|
||||
// migration rather than something to carry unused until then.
|
||||
//
|
||||
// The owners are a comma-joined sorted string on the project row rather
|
||||
// than a fourth table, which is what DkgSession.participantPublicKeys
|
||||
// already does with a set of keys and for the same reason.
|
||||
AutoMigration(from = 20, to = 21),
|
||||
]
|
||||
)
|
||||
@ColumnTypeConverters(MantraConverters::class)
|
||||
@@ -368,6 +393,12 @@ abstract class MantraDatabase: RoomDatabase() {
|
||||
|
||||
abstract fun mantraDialectDao(): MantraDialectDao
|
||||
|
||||
abstract fun mantraProjectDao(): MantraProjectDao
|
||||
|
||||
abstract fun mantraProjectArtifactVersionDao(): MantraProjectArtifactVersionDao
|
||||
|
||||
abstract fun mantraProjectTranslationArtifactVersionDao(): MantraProjectTranslationArtifactVersionDao
|
||||
|
||||
abstract fun mantraTranslationArtifactVersionDao(): MantraTranslationArtifactVersionDao
|
||||
|
||||
abstract fun mantraTranslationArtifactVersionContributorDao(): MantraTranslationArtifactVersionContributorDao
|
||||
|
||||
Reference in new issue
Block a user