Skip to content

Commit

Permalink
[docs] Reviews Rating (MystenLabs#16520)
Browse files Browse the repository at this point in the history
## Description 

Describe the changes or additions included in this PR.

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and do not break anything, you can
skip the following section. Otherwise, please briefly describe what has
changed under the Release Notes section.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes

---------

Co-authored-by: Ronny Roland <[email protected]>
Co-authored-by: Ashok Menon <[email protected]>
Co-authored-by: ronny-mysten <[email protected]>
  • Loading branch information
4 people authored May 8, 2024
1 parent 622f7d0 commit edd3ece
Show file tree
Hide file tree
Showing 8 changed files with 923 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/content/guides/developer/app-examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ Sui is dedicated to providing a wide range of examples to guide you in proper pr
- [Tic-tac-toe](./app-examples/tic-tac-toe.mdx): Three implementations of the classic tic-tac-toe game on the Sui network to demonstrate different approaches to user interaction.
- [Trustless Swap](./app-examples/trustless-swap.mdx): This example demonstrates trustless swaps on the Sui blockchain using a shared object as an escrow account.
- [Weather Oracle](./app-examples/weather-oracle.mdx): The Sui Weather Oracle demonstrates how to create a basic weather oracle that provides real-time weather data.
- [Reviews Rating](./app-examples/reviews-rating.mdx): This example demonstrates implementing a reviews-rating platform for the food service industry on Sui.
453 changes: 453 additions & 0 deletions docs/content/guides/developer/app-examples/reviews-rating.mdx

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/content/sidebars/guides.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ const guides = [
},
'guides/developer/app-examples/plinko',
'guides/developer/app-examples/recaptcha',
'guides/developer/app-examples/reviews-rating',
'guides/developer/app-examples/tic-tac-toe',
{
type: 'category',
Expand Down
10 changes: 10 additions & 0 deletions examples/move/reviews_rating/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "reviews_rating"
version = "0.0.1"
edition = "2024.beta"

[dependencies]
Sui = { local = "../../../crates/sui-framework/packages/sui-framework", override = true }

[addresses]
reviews_rating = "0x0"
30 changes: 30 additions & 0 deletions examples/move/reviews_rating/sources/dashboard.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module reviews_rating::dashboard {
use std::string::String;

use sui::dynamic_field as df;

/// Dashboard is a collection of services
public struct Dashboard has key, store {
id: UID,
service_type: String
}

/// Create a new dashboard
public fun create_dashboard(
service_type: String,
ctx: &mut TxContext,
) {
let db = Dashboard {
id: object::new(ctx),
service_type
};
transfer::share_object(db);
}

public fun register_service(db: &mut Dashboard, service_id: ID) {
df::add(&mut db.id, service_id, service_id);
}
}
44 changes: 44 additions & 0 deletions examples/move/reviews_rating/sources/moderator.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module reviews_rating::moderator {
use sui::tx_context::{sender};

/// Represents a moderator that can be used to delete reviews
public struct Moderator has key {
id: UID,
}

/// A capability that can be used to setup moderators
public struct ModCap has key, store {
id: UID
}

fun init(ctx: &mut TxContext) {
let mod_cap = ModCap {
id: object::new(ctx)
};
transfer::transfer(mod_cap, sender(ctx));
}

/// Adds a moderator
public fun add_moderator(
_: &ModCap,
recipient: address,
ctx: &mut TxContext
) {
// generate an NFT and transfer it to moderator who may use it to delete reviews
let mod = Moderator {
id: object::new(ctx)
};
transfer::transfer(mod, recipient);
}

/// Deletes a moderator
public fun delete_moderator(
mod: Moderator
) {
let Moderator { id } = mod;
object::delete(id);
}
}
102 changes: 102 additions & 0 deletions examples/move/reviews_rating/sources/review.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

module reviews_rating::review {
use std::string::String;

use sui::clock::Clock;
use sui::math;

const EInvalidContentLen: u64 = 1;

const MIN_REVIEW_CONTENT_LEN: u64 = 5;
const MAX_REVIEW_CONTENT_LEN: u64 = 1000;

/// Represents a review of a service
public struct Review has key, store {
id: UID,
owner: address,
service_id: ID,
content: String,
// intrinsic score
len: u64,
// extrinsic score
votes: u64,
time_issued: u64,
// proof of experience
has_poe: bool,
// total score
total_score: u64,
// overall rating value; max=5
overall_rate: u8,
}

/// Creates a new review
public(package) fun new_review(
owner: address,
service_id: ID,
content: String,
has_poe: bool,
overall_rate: u8,
clock: &Clock,
ctx: &mut TxContext
): Review {
let len = content.length();
assert!(len > MIN_REVIEW_CONTENT_LEN && len <= MAX_REVIEW_CONTENT_LEN, EInvalidContentLen);
let mut new_review = Review {
id: object::new(ctx),
owner,
service_id,
content,
len,
votes: 0,
time_issued: clock.timestamp_ms(),
has_poe,
total_score: 0,
overall_rate,
};
new_review.total_score = new_review.calculate_total_score();
new_review
}

/// Deletes a review
public(package) fun delete_review(rev: Review) {
let Review {
id, owner: _, service_id: _, content: _, len: _, votes: _, time_issued: _,
has_poe: _, total_score: _, overall_rate: _
} = rev;
object::delete(id);
}

/// Calculates the total score of a review
fun calculate_total_score(rev: &Review): u64 {
let mut intrinsic_score: u64 = rev.len;
intrinsic_score = math::min(intrinsic_score, 150);
let extrinsic_score: u64 = 10 * rev.votes;
let vm: u64 = if (rev.has_poe) { 2 } else { 1 };
(intrinsic_score + extrinsic_score) * vm
}

/// Updates the total score of a review
fun update_total_score(rev: &mut Review) {
rev.total_score = rev.calculate_total_score();
}

/// Upvotes a review
public fun upvote(rev: &mut Review) {
rev.votes = rev.votes + 1;
rev.update_total_score();
}

public fun get_id(rev: &Review): ID {
rev.id.to_inner()
}

public fun get_total_score(rev: &Review): u64 {
rev.total_score
}

public fun get_time_issued(rev: &Review): u64 {
rev.time_issued
}
}
Loading

0 comments on commit edd3ece

Please sign in to comment.