# Bookie
- Resource manager: the one that accepts or declines booking requests.
- Resouce user: the one that requests to use a resource
## User Stories
- The resource manager should be able to create a bookable resource
- The resource manager should be able to create bookable slots for their resources
- from this time
- to this time
- Anyone should be able to see all the available booking slots for a resource
- Anyone should be able to create booking requests for a slot
- The resource user should be able to cancel their own requests
- The resource manager should be able to decline requests for the resource they manage
- The resource manager should be able to accept requests for the resource they manage
- Then that slot should be locked and not available anymore
- The resource manager should be able to see all the bookings for a resource
## Data structures
```rust
Resource {
name: String,
created_at: Timestamp,
author: AgentPubKeyB64
}
BookingSlot {
resource_hash: EntryHashB64,
time_range: TimeRange
}
BookingRequest {
booking_slot_hashes: Vec<EntryHashB64>,
resource_user: AgentPubKeyB64,
managers_pub_keys: Vec<AgentPubKeyB64>
// TODO: is timestamp required?
}
Booking {
slots: Vec<BookingSlots>,
resource_user: AgentPubKey
}
TimeRange {
start_time: Timestamp,
end_time: Timestamp,
}
```
## Diagrams
Key:
- Block: entry
- Black line: Link
- Dotted line: Reference by hash in entry
### State of a request
```mermaid
stateDiagram-v2
state if_state <<choice>>
[*] --> Pending: create
Pending --> if_state: Approve
if_state --> Pending: if pending_managers_to_approve > 0
if_state --> Booked: else
Pending --> Rejected: reject
```
### Entry relationships
```mermaid
graph TD;
ManagerPubKey1
ManagerPubKey2
ManagerPubKey2-->BookingResource2
ManagerPubKey1-->BookingResource1
BookingResource1-->|time_range|BookingSlot1
BookingRequest1-->Booking1
BookingSlot1-->|booked|BookingRequest1
BookingResource1-->|time_range|BookingSlot2
BookingSlot2-->|booked|BookingRequest2
BookingRequest2-->|accepted|ManagerPubKey1
ManagerPubKey2-->|pending|BookingRequest2
BookingResource2-->|time_range|BookingSlot3
BookingRequest2-.->BookingSlot2
BookingRequest2-.->BookingSlot3
```
## Zome functions
- [x] create_bookable_resource(resource_name: String)
- create_entry(resource)
- create_link(Path::from("all_resources") -> resource_hash)
- [x] get_all_resources() -> Vec<BTreeMap<EntryHashB64, Resource>>
- get_links(Path::from("all_resources"))
- for every link, get(link.target)
- [x] create_bookable_slot(resource_hash: EntryHashB64, time_range: TimeRange) ->ExternResult<BTreeMap<EntryHashB64, BookingSlot>>>
- create_entry(slot)
- create_link(resource -> slot)
- [x] get_bookings_slots(resource_hash: EntryHashB64) -> ExternResult<BTreeMap<EntryHashB64, BookingSlot>>
- get_links(resource)
- for every link, get(link.target)
- [ ] create_booking_request(booking_slot: EntryHashB64)
- create_entry(request)
- create_link(slot -> request, "pending")
- [ ] cancel_booking_request(booking_request_hash: EntryHashB64)
- delete_entry(booking_request_hash)
- [ ] get_booking_requests(slot: slot_hash: EntryHashB64) -> Vec<BTreeMap<EntryHashB64, (BookingRequest, RequestStatus)>>
- get_links_details(slot_hash)
- all the links with "pending" LinkTag -> request pending
- all the deleted links -> request rejected
- all the links with "booked" -> request booked
- get everything
- if an entry is undefined -> it means canceled, filter out
- [ ] decline_booking_request(booking_request_hash: EntryHashB64)
- get(booking_request)
- get_links(booking_request.slot_hash))
- filter links where link.target == booking_request_hash, delete_link(slot -> request)
- [ ] accept_booking_request(booking_request_hash: EntryHashB64)
- create_entry(booking)
- create_link(slot -> booking, "booked")
## Use Case
- Viktor opens the app and creates a meeting room for everyone in the village to enjoy his amazing space.
- Viktor creates the slots that are available for the meeting room.
- Then, David wants to use the room.
- He goes into the room and sees what slots are available.
- Argh most don't work, but tomorrow night does! David requests to use that slot.
- Viktor gets a notification, oh David wants to use the room! So nice to have this kind of collaborative thingies in the village.
- Viktor sees the requests from David
- He checks that everything is right with the room that day, and accepts it
- David gets a notification that Viktor has accepted his request. He's really happy, so much so that he donates to the opencollective for Bookie
---
- The day of the event, David goes in the meeting room.
- Viktor is not there, but her colleague Linda scans the QR code from David's phone (the booking entry, which is countersigned) and says yeah okey. (OUT OF SCOPE)
## Time Slot management
How would we generate the timeslot for a resource based on parameters? What are the parameters?
Example: A car, available **dayly every day**. Multiple days can be booked.
Or a space being available in the following times:
08.30 - 11.30
11.30 - 13.00
13.00 - 16.00
16.00 - 19.00
19.00 - 23.00
Each day of each week.
A possibility is to set a "model day", where you drag to create the timeslots where a resource is available and then mark dates in a calendar for when that model should be applied in order to generate timeslots for a number of days ahead.