# MailBoox design spec # Application Synopsis Enter the books that are in your bookshelf in order to make them visible to your community. Users can request to borrow books from each other and if possible the owner can put the book in his/her Mailbox in order to make it easily available for the borrower to pick-up. # Entry relationships schema ## Books zome ```mermaid graph TD subgraph Books zome subgraph anchors all_groups all_groups all_groups all_genres all_genres end subgraph Groups all_groups --> Alice_appartment_building all_groups --> Friends_of_Bob end subgraph Genre all_genres --> Sci-fi all_genres --> Anthropology end subgraph Books Sci-fi --> Asimovs_foundation Anthropology --> Debt end subgraph Players Alice -.book_owner.-> Asimovs_foundation Asimovs_foundation --> Alice Bob -.book_owner.-> Debt Debt --> Bob Alice -.part_of_group.-> Alice_appartment_building Alice_appartment_building --> Alice Bob -.part_of_group.-> Friends_of_Bob Friends_of_Bob --> Bob end end ``` ## Loans zome ```mermaid graph TD subgraph Loans zome subgraph anchors all_loans end subgraph Loan_requests Loan_request1 Loan_request2 end subgraph Loans Loan_request1 -.informs.-> Loan1 Loan_request2 -.informs.-> Loan2 all_loans --> Loan1 all_loans --> Loan2 end subgraph agents Loan1 -.lender.-> Alice Loan1 -.borrower.-> Bob end subgraph books Loan1 -.item_borrowed.- Book1 Loan2 -.item_borrowed.- Book2 end end ``` # Zome designs ## Books zome ```rust #[derive(Serialize, Deserialize, Debug, DefaultJson)] struct Book { name: String, author: String, genre: String, blurb: String, isbn: String, book_owner: Address } create_book: { inputs: |book: Book|, outputs: |result: ZomeApiResult<Address>|, handler: handle_create_book } get_book: { inputs: |address: Address|, outputs: |result: ZomeApiResult<GetEntryResult>|, // Another change request from guillem, this GetEntryResult type can be returned by using https://developer.holochain.org/api/latest/hdk/api/fn.get_entry_result.html handler: handle_get_book } get_my_books: { inputs: | |, outputs: |result: ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>>|, handler: handle_get_books } get_owner: { inputs: |address: Address|, outputs: |result: ZomeApiResult<Address>|, handler: handle_get_owner } ``` ## Loans zome ```rust #[derive(Serialize, Deserialize, Debug, DefaultJson)] struct LoanRequest { item_address: Address, borrower_address: Address, created_at: i64, } #[derive(Serialize, Deserialize, Debug, DefaultJson)] struct Loan { item_address: Address, borrower_address: Option<Address>, started_at: Option<i64> finished_at: Option<i64> comment: Option<String> return_by: Option<i64> } // Create a loan request entry // Called by the person who wants to borrow request_to_borrow(item_address: Address, created_at: i64): -> ZomeApiResult<Address> get_my_loan_requests() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>> // This assumes that the books zome has a way of getting all the items of an owner get_item_loan_requests(item_address: Address) -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>> // Create a loan entry // Called by the person who owns the item // Steps // 1. Get the loan request // 2. Get the loan entry // 3. If the loan entry does not exist, create it only with item_address // 4. Update the loan entry with the new information // 5. Create a link from the borrower agent address to the address of the updated entry (not the original entry address) // 6. Delete the loan request create_loan(loan_request_address: Address, started_at: i64, return_by: i64) -> ZomeApiResult<Address> // Remove a loan request // Called by the person who owns the item decline_loan(loan_request_address: Address) -> ZomeApiResult<()> get_loan_history(item_address: Address) -> ZomeApiResult<Option<EntryHistory>> get_loan_status(item_address: Address) -> ZomeApiResult<Option<Entry>> // Has to be called by the borrower first and the by the lender // If double signature, remove link between borrower agent address and loan finish_loan(item_address: Address, finished_at: i64, comment: Option<String>) -> ZomeApiResult<()> // Retrieve the loans throught the borrower->loans links get_my_active_loans() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>> ``` ## Further implementations ```rust #[derive(Serialize, Deserialize, Debug, DefaultJson)] struct Collection { name: String, } #[derive(Serialize, Deserialize, Debug, DefaultJson)] struct User { name: String, street: String, zip: String, city: String, country: String, } get_my_address: { inputs: | |, outputs: |result: JsonString|, handler: handle_get_my_address } create_collection: { inputs: |name: String|, outputs: |result: JsonString|, handler: handle_create_collection } create_user: { inputs: |name: String, street: String, zip: String, city: String, country: String|, outputs: |result: JsonString|, handler: handle_create_user } get_user_data: { inputs: |address: Address|, outputs: |result: JsonString|, handler: handle_get_user_data } add_book_to_collection: { inputs: |book_address: Address, collection_address: Address|, outputs: |result: JsonString|, handler: handle_add_book_to_collection } get_books_in_collection: { inputs: |collection_address: Address, tag: String|, outputs: |result: JsonString|, handler: handle_get_books_in_collection } get_collections_book_is_in: { inputs: |book_address: Address, tag: String|, outputs: |result: JsonString|, handler: handle_get_collections_book_is_in } //retrieve all books linked to the anchor shelf get_books: { inputs: |shelf_address: Address, tag: String|, outputs: |result: JsonString|, handler: handle_get_books } get_owners: { inputs: |book_address: Address, tag: String|, outputs: |result: JsonString|, handler: handle_get_owners } request_to_borrow: { inputs: |borrower_address: Address, book_address: Address|, outputs: |result: JsonString|, handler: handle_request_to_borrow } get_requests_by_user: { inputs: |borrower_address: Address|, outputs: |result: JsonString|, handler: handle_get_requests_by_user } get_book_requests: { inputs: |book_address: Address|, outputs: |result: JsonString|, handler: handle_get_book_requests } create_loan: { inputs: |book_address: Address, borrower_address: Address, return_by: String|, outputs: |result: JsonString|, handler: handle_create_loan } ```