62 lines
2.1 KiB
Markdown
62 lines
2.1 KiB
Markdown
# Design: Leave & Stop-Forward (m9-leave-revocation)
|
|
|
|
## Architecture
|
|
|
|
Backend-only. No UI changes. Touches 6 files.
|
|
|
|
## Storage
|
|
|
|
**Tag::CommunityLeave = 0x11** added to `storage/keys.rs` (after PurgeManifest = 0x10).
|
|
|
|
Key format: `encode_key(EntityId::new(user_id), Tag::CommunityLeave, b"")` — no suffix.
|
|
|
|
Value format: `[status: 1 byte (0=Active, 1=Left)][left_at_ns: 8 bytes LE]` — fixed 9 bytes.
|
|
|
|
Stored in the **users** storage partition via `storage.users_engine()`.
|
|
|
|
## Data Types (entities/community.rs)
|
|
|
|
Appended to existing `CommunityMembershipIndex`:
|
|
|
|
```rust
|
|
pub enum MembershipStatus { Active, Left }
|
|
pub struct CommunityMembership { user_id, status, left_at_ns: Option<u64> }
|
|
pub fn serialize_membership(m: &CommunityMembership) -> [u8; 9]
|
|
pub fn deserialize_membership(user_id: u64, bytes: &[u8]) -> Option<CommunityMembership>
|
|
```
|
|
|
|
## TidalDb Field (db/mod.rs)
|
|
|
|
```rust
|
|
community_leave_status: dashmap::DashMap<u64, crate::entities::CommunityMembership>,
|
|
```
|
|
|
|
Added after `community_membership`. Initialized to `DashMap::new()` in both `from_config` and `from_parts`.
|
|
|
|
## API (db/community.rs)
|
|
|
|
Three new public methods appended to the existing `TidalDb` impl:
|
|
|
|
- `leave_community_layer(user_id)` — creates Left membership, persists, inserts into DashMap
|
|
- `rejoin_community_layer(user_id)` — creates Active membership (preserving left_at_ns), persists, inserts
|
|
- `community_layer_status(user_id)` — reads from DashMap, returns default_active if absent
|
|
- `persist_leave_record(membership)` — private helper: writes to users_engine via Tag::CommunityLeave
|
|
|
|
## Gate (db/signals.rs)
|
|
|
|
Added to BOTH `try_cohort_attribution` and `try_community_forwarding`:
|
|
|
|
```rust
|
|
if self.community_leave_status.get(&user_id)
|
|
.map_or(false, |m| m.status == MembershipStatus::Left)
|
|
{
|
|
return;
|
|
}
|
|
```
|
|
|
|
Placed at top of each function before any other work.
|
|
|
|
## Startup Restore (db/state_rebuild.rs)
|
|
|
|
`rebuild_community_leave_status(storage, map)` scans users_engine for Tag::CommunityLeave keys, deserializes each, inserts into DashMap. Called from `from_parts` after `rebuild_community_memberships`.
|