Skip to content

Latest commit

 

History

History
352 lines (256 loc) · 12.1 KB

File metadata and controls

352 lines (256 loc) · 12.1 KB

Developer notes

These notes are now stale and reflect thoughts at a mid-way stage in updating to the revised version of book. So don't be mislead by detail. Retaining for troubleshooting purposes.

Scripts

npm run dev
npm run build

Testing

Using vitest:

npm install -D vitest
npm install --save-dev @vue/test-utils

add to package.json scripts list:

    "test:unit": "vitest run --environment jsdom"

Checking the typescript settings

the answer says update typescript, and node (both badly out of date, e.g. node was at 12, latest is 19.6.0)

And that fixed it.

Also install jsdom

npm install -D jsdom

mock localstorage

npm install -D vitest-localstorage-mock

Edit vite.config.js as per install info at link

local storage mocking

consider this

Or do this fix to use actual local storage.

trouble shooting

if you get an error message about perf hooks, then ensure you are using the latest version of node (nvwm is recommended for managing node versions).

Features

typical use case - prebooked session, and access for limited window.

How do we share that with a user? we can set sessionIDs and policies as URL params, e.g.

https://uoe.practable.io/book/?sid=some_session_id&pid=some_policy_id

  • user cannot cancel sessionID bookings, because they might be shared in a group.

If that link is too clunky, we can always shorten it with a link shortener (e.g. using bitly or the university of edinburgh link shortener)

If we need to send multiples then we can do arrays .... need to check formatting. Some examples here and here.

but maybe ..

We can treat a one-off session as a user, if we book the session under a unique user name, e.g. a descriptive name including the date (soe-engdes1-23-feb-17-tues-1400-1500-spinner-00. Even though the system treats it as a user, we have the UI request this as a code to be typed in for a "session" and it gets all the bookings for that user as well. This user can be added to the localstorage to provide persistance if the machine is rebooted. Which identity does david use for the analytics?

We can have a single primary userID, to be used for analytics, and multiple "sessions". Users should be able to change their primary userID. The primary userID is what their bookings are made against.

All users are anonymous at present. There are persistent and epheremal user ids, so we can support staff pre-booking activities for students.

For example, hand out airport-style quick-reference codes which refer to a token containing a username and booking id code for a booking to borrow.

The booking is accessed as that user, but the persistent identity of the user remains intact for use with analytics.

Each instance has its own unique anonymous identity, generated by the book server.

You can change to another anonymous identity, e.g. to share the same account across multiple devices.

You can borrow a booking by entering a user-name and bookingID (can you do this in advance, or only at the time?)

Analytics server would still pick up the anonymous identity of the user

Allow users to change their user name, to transfer from another device. limit user names to the number of characters, letters and numbers that we expect from xid. show green or red depending on whether the format is met. run bad words filter Keep a history of user names so users can revert (e.g. if they make a mistake, and have bookings)

Allow users to put in an short code that retrieves user/booking combo from another server. An endpoint for this would be useful .... publish shortcodes on page so anyone can copy? put behind a button so shoulder surfing cannot be used to steal a booking?

Booking has to be set to shareable for this to work? I.e. students can protect their own bookings from being shared? Would need an endpoint for making the booking shareable or unsharable. What if it is made unsharable after being shared? The short code no longer works, and is not re-used... need to keep a list of stale short codes....

could use words for ease, but wordlists like '/usr/share/dict/words' have offensive words. scowl lists some words as offensive, but not nearly enough.

filtering with bad words list discussed here but this is incomplete.

EFF did this already although it still has some words I wouldn't want to see in a phrase given to students.

moving to vite

migration guide

then

npm install -g vite

then npm run dev

<snip>
import { performance } from 'node:perf_hooks'
       ^

SyntaxError: Unexpected token {
<snip>

Looks like this perf hooks issue, solution proposed is

 npm i --save-dev @types/node

and that fixed it.

Except that could not find global css or main.js

localhost/:8 
 GET http://localhost:3000/global.css net::ERR_ABORTED 404 (Not Found)
localhost/:10 
 GET http://localhost:3000/src/main.js net::ERR_ABORTED 404 (Not Found)
client.ts:16 [vite] connecting...
client.ts:53 [vite] connected.

oops ... main.js is now main.ts!

fix ... but then repeated reloads with errors, similar to this bad gateway for deps

<snip>
[vite] error while updating dependencies:
Error: ENOTEMPTY: directory not empty, rmdir '/home/tim/sources/bookjs/src/node_modules/.vite/deps'
<snip>

asdfasdf

rm -r 

Also, env vars need changing to prefix VITE

To prevent accidentally leaking env variables to the client, only variables prefixed with VITE_ are exposed to your Vite-processed code. e.g. for the following env variables:

VITE_SOME_KEY=123
DB_PASSWORD=foobar 

Only VITE_SOME_KEY will be exposed as import.meta.env.VITE_SOME_KEY to your client source code, but DB_PASSWORD will not.

changed all VUE_APP to VITE_APP, and now running fine locally on npm run dev with development env.vars pointing to the existing AWS server instantiation (for convenience in avoiding setting up local services).

Now try production build with base path and host on dev.practable.io/book ...

npm run build

Still got the base_path problem with css and js assets, being looked for at https://dev.practable.io/css/<name> and https://dev.practable.io/js/<name> so page is not loading, and can't check whether the routing etc is working yet.

base path for local dev server origin, base href

added base href, did not fix issue...

not sure about this router config as seems different, but apparently works

Font Awesome

icon colour changes

for all icons in project put this in css

.fa {
  color : red;
}

XState

Logging in

stateDiagram-v2
    [*] --> UserNameFromStorage 
    UserNameFromStorage --> LoginTokenFetch : OK
    UserNameFromStorage --> UserNameFetch : Error
    UserNameFetch --> UserNameAwaitResponse
    UserNameAwaitResponse --> UserNameStore : OK
    UserNameStore --> LoginTokenFetch
    UserNameAwaitResponse --> UserNameWaitBackOff : Error
    UserNameWaitBackOff --> UserNameFetch
    LoginTokenFetch --> LoginTokenAwaitResponse
    LoginTokenAwaitResponse --> StoreLoginToken : OK
    LoginTokenAwaitResponse --> LoginTokenWaitBackOff : Error
    LoginTokenWaitBackOff --> LoginTokenFetch
    StoreLoginToken --> RefreshAwait 
    RefreshAwait --> LoginTokenFetch : RefreshRequested
    RefreshAwait --> UserNameFromStorage : UserNameChanged

Showing kit and taking bookings

stateDiagram-v2
    [*] --> RefreshLoginToken
    GetGroups --> GetBookings
    RefreshLoginToken --> GetGroups 
    GetBookings --> Wait
    Wait --> RefreshLoginToken : RefreshRequested
    Wait --> GetGroupDetails : GroupSelected
    GetGroupDetails --> GetPolicies
    GetPolicies -->  Wait
    Wait --> GetSlots : PolicySelected
    GetSlots --> DisplaySuggestedBookingTimes
    DisplaySuggestedBookingTimes --> Wait
    Wait --> MakeBooking : TimeSelected
    MakeBooking --> GetBookings : OK
    Wait --> StartBooking : ClickOpen
    StartBooking --> Wait
    Wait --> CancelBooking : ClickCancel
    CancelBooking --> GetBookings
stateDiagram-v2
    [*] --> RefreshLoginToken
    GetGroups --> Wait
    RefreshLoginToken --> GetGroupsAndBookings
    GetGroupsAndBookings --> Wait
    GetBookings --> Wait
    Wait --> RefreshLoginToken : RefreshRequested
    Wait --> CheckGroupDetails : GroupSelected
    CheckGroupDetails --> GetGroupDetails : Stale
    CheckGroupDetails --> CheckSlotAvailabilities: Fresh
    CheckSlotAvailabilities --> GetSlotAvailabilities : Stale
    CheckSlotAvailabilities  --> DisplaySuggestedBookingTimes : Fresh
    GetGroupDetails --> GetPolicies
    GetPolicies -->  GetSlotAvailabilities
    GetSlotAvailabilities--> CalculateSuggestedBookingTimes
    CalculateSuggestedBookingTimes --> DisplaySuggestedBookingTimes
    DisplaySuggestedBookingTimes --> Wait
    Wait --> MakeBooking : TimeSelected
    MakeBooking --> GetBookings : OK
    Wait --> StartBooking : ClickOpen
    StartBooking --> Wait
    Wait --> CancelBooking : ClickCancel
    CancelBooking --> GetBookings
    Wait --> AddGroup
    AddGroup --> GetGroups  
    Wait --> GetSlotAvailabilities : UserRequestedRefresh

 stateDiagram-v2
    [*] --> RefreshLoginToken
    GetGroups --> Wait
    RefreshLoginToken --> GetGroupsAndBookings
    GetGroupsAndBookings --> Wait
    GetBookings --> Wait
    Wait --> RefreshLoginToken : ForceRefreshLogin
    Wait --> GetBookings : ForceRefreshBookings
    Wait --> CheckGroupDetails : GroupSelected
    CheckGroupDetails --> GetGroupDetails : Stale
    CheckGroupDetails --> CheckSlotAvailabilities: Fresh
    CheckSlotAvailabilities --> GetSlotAvailabilities : Stale
    CheckSlotAvailabilities  --> Wait: Fresh
    GetGroupDetails --> GetPolicies
    GetPolicies -->  GetSlotAvailabilities
    GetSlotAvailabilities--> GetIndividualSlotAvailability
    GetIndividualSlotAvailability --> CalculateSuggestedBookingTimes
    CalculateSuggestedBookingTimes --> GetIndividualSlotAvailability : NextSlot
    CalculateSuggestedBookingTimes --> Wait : Done
    Wait --> MakeBooking : TimeSelected
    MakeBooking --> GetBookings : OK
    Wait --> StartBooking : ClickOpen
    StartBooking --> Wait
    Wait --> CancelBooking : ClickCancel
    CancelBooking --> GetBookings
    Wait --> AddGroup
    AddGroup --> GetGroups  
    Wait --> GetGroupDetails : ForceRefreshGroupDetails
    Wait --> GetIndividualSlotAvailability : ForceRefreshOneSlot
    Wait --> GetSlotAvailabilities : ForceRefreshAll

RefreshMachine

stateDiagram-v2
    [*] --> AwaitToken
    AwaitToken --> Fetch : TokenRefreshed
    Fetch --> Fresh : OK
    Fetch --> AwaitToken : Unauthorised
    Fetch --> Backoff : Error
    Backoff --> Fetch : Timeout
    Fresh --> Stale : Timeout
    Fresh --> Fresh : Refresh (NOOP)
    Stale --> Fetch : Refresh

KindRefreshMachine

stateDiagram-v2
    [*] --> AwaitToken
    AwaitToken --> Fetch : TokenRefreshed
    Fetch --> Fresh : OK
    Fetch --> AwaitToken : Unauthorised
    Fetch --> Backoff : Error
    Backoff --> Fetch : Timeout
    Fresh --> Stale : Timeout
    Fresh --> Fresh : KindRefresh (NOOP)
    Stale --> Fetch : KindRefresh, ForceRefresh
    Fresh --> Fetch : ForceRefresh
	```