feat(user): WI-1.7 boost/undo + repo refactor#85
Merged
Conversation
Reduce boost_status to a todo!() placeholder until Task 11 implements the flow, dropping the unrelated dead_code annotations and arg-rename diff from the find_by_original_uri commit.
Wires the existing domain flow as a public `#[ic_cdk::query]` endpoint, removes the now-dead `expect(dead_code)` guard, and syncs `user.did` with the new method plus the `spoiler_text`/`sensitive` fields on `Status`.
Sync the mdBook docs to reflect the boost-status implementation: - interface/types.md: add `spoiler_text` / `sensitive` to Status, plus new GetLocalStatus and FetchStatus sections; cross-link from BoostStatus to the fetch flow. - project.md: add `get_local_status` to the User Canister interface and `fetch_status` to the Federation Canister interface. - project/flows.md: replace the Boost Status diagram with the fetch_status -> get_local_status -> wrapper insert -> Announce pipeline; document the shared snowflake and idempotency. - architecture.md: add a Boost Flow sub-section mirroring the diagram. - architecture/database-schema.md: clarify that boosts.id is shared with the wrapper status, feed entry, and Announce activity id. - specs/status.md: note that spoiler_text and sensitive flow into wrapper rows when a status is boosted. - specs/urls.md: document the wrapper status URL as the Announce id. - activitypub.md: mark Announce / Undo(Announce) as M1 implemented and point at boost_status / handle_announce / handle_undo_announce.
Extend FeedItem with `liked` and `boosted` booleans so clients can render
"you liked / you boosted" markers on each feed entry without an extra
round-trip. Both flags are populated in `hydrate_outbox` and
`hydrate_inbox` by querying the viewer's `liked` and `boosts` tables for
the canonical status URI. Inbox `Create(Note)` activities resolve the
note's `id` (or fall back to `{actor}/statuses/{id}` when the note id is
emitted as a bare snowflake).
Centralises transaction lifecycle so repositories no longer drive commits themselves. Generic over schema; `run` auto-rolls back on Err.
Mirror the block repository shape: `LikedRepository { tx: Option<TransactionId> }`
with `oneshot()` / `with_transaction(tx)` constructors and a private `db()`
helper that picks oneshot vs from_transaction. All four public methods
(`like_status`, `unlike_status`, `is_liked`, `get_liked`) become `&self`.
All 15 call sites across feed, liked/like, liked/unlike, and liked/get_liked
updated to `LikedRepository::oneshot().…`. No behavior change.
Mirrors the canonical pattern from block/liked/profile: oneshot() constructor for plain calls, with_transaction(tx) for splicing into externally-driven transactions, and a private db() helper that dispatches to the right WasmDbmsDatabase. All public methods become &self; record_to_follower stays a private associated fn. No internal transactions in this repo. Updated all FollowerRepository call sites to ::oneshot().METHOD(...). The accept_follow_transaction raw DBMS_CONTEXT block is intentionally left untouched and will migrate to Transaction::run in a follow-up once FollowRequest gets the same refactor.
Convert FollowingRepository to instance-based pattern with oneshot() and with_transaction() constructors plus a private db() helper. The internal transaction in update_status is removed: callers must now wrap the call in Transaction::run to preserve atomicity across the underlying delete + insert. handle_incoming::handle_accept and the corresponding tests now wrap update_status in Transaction::run::<_, _, _, CanisterError>(Schema, ..), preserving the existing error mapping. All other call sites switch to FollowingRepository::oneshot(). Schema gains Copy so it can satisfy the Transaction::run bound.
Convert UserRepository to an instance-based struct exposing oneshot()/with_transaction() constructors, matching the canonical repository pattern used by status/boost/tombstone/moderators. The repo now exposes &self methods only and never opens or commits a transaction internally — callers wrap multi-step writes in Transaction::run. Update every directory caller (api flows, sign_up/delete_profile state machines, test_utils, search_profiles) to use UserRepository::oneshot() for single-row reads and writes. Add a CanisterError::Internal variant so transaction-aware tests can inject a sync error and assert rollback. Add Copy to the directory Schema (matches user-canister Schema), so callers can pass it to Transaction::run. New tests cover: tx commit, tx rollback for sign_up, atomic sign_up + set_user_canister inside one tx, rollback of set_user_canister when the closure errors, remove_user inside a tx, and rollback of remove_user.
Centralises `feed` table writes behind a single repository so subsequent status / boost / inbox refactors can route their inserts through one lifecycle-aware entry point. Reads are still served by the existing `read_feed` flow, which performs the cross-table hydration join. Follows the canonical `oneshot` / `with_transaction` pattern: callers own transaction lifecycle, the repo never commits or begins transactions. Tests cover both source variants, deletion, transactional commit and rollback semantics.
- Add `db_utils::repository::Repository` trait providing default `db()` accessor; impls supply schema/oneshot/with_transaction/tx. - Migrate all 12 user/directory repositories onto the trait, dropping inherent oneshot/with_transaction/db boilerplate; callers import the trait. - Move boost orchestration helpers (`insert_boost_with_wrapper`, `delete_boost_with_wrapper`) next to the flows that drive them (`boost_status.rs` / `undo_boost.rs`); tests follow. - Drop now-reachable `#[allow(dead_code)]` from feed/status repos.
|
✔️ 7054634...6775cea - Conventional commits check succeeded. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements WI-1.7 Boost / Undo Boost for the user canister and refactors the repository layer used by both
useranddirectorycanisters.WI-1.7 boost feature
Statusextended withspoiler_text+sensitive;BoostRepositoryaddsfind_by_original_uri;StatusRepositorygainsincrement_boost_count/decrement_boost_count.did::user::GetLocalStatus+did::federation::FetchStatustypes.federationcanister:fetch_statusflow (local-only) and update endpoint;usercanister addsfederation::fetch_statusadapter.user::get_local_statusquery with caller-scoped visibility.boost_statusflow (fetch + insert wrapper Status/Boost/FeedEntry + Announce dispatch) andundo_boostflow (delete + Undo(Announce) dispatch).AnnounceandUndo(Announce); outbox/inbox renderers surfaceboosted_by+ original author; feed items now expose viewerliked/boostedflags.Repository refactor
db_utils::transaction::Transactionprimitive (begin/commit/rollback/run) so callers own transaction lifecycle.user: block, follower, following, follow_request, liked, profile, status, feed, boost;directory: users, moderators, tombstone) converted from associated-function style to instance-based with optionalTransactionId.db_utils::repository::Repositorytrait withSchemaassociated type and requiredoneshot/with_transaction/tx/schemamethods, providing a defaultdb()accessor — drops the per-repodb()boilerplate.BoostRepositoryinto per-flow helpers (boost_status::insert_boost_with_wrapper,undo_boost::delete_boost_with_wrapper); each repo writes only its own table.Test plan
just check_code(fmt + clippy-D warnings)just test— 341 user, 170 directory, 81 db-utils, 39 federation, 4 ic-utils, all passingjust build_all— directory/federation/user WASM artefacts rebuild cleanjust integration_test— pocket-ic suites green, including new boost/undo_boost end-to-end coverage