dalten-collective / full-stop

A Period Tracker on Urbit
2 stars 1 forks source link

Front End Development Thread #1

Open rabsef-bicrym opened 1 year ago

rabsef-bicrym commented 1 year ago

Introduction

Full-Stop is a period tracker for Urbit. Both directly connected front-ends and offline->sync applications can communicate updates to Full-Stop allowing users to utilize offline local data storage when they are without internet, while maintaining an accurate record of data on their urbits. When offline systems sync, their changes are read and implemented (where appropriate) and the resultant data is sent back to the application to update local state.

Model Theory

Full-Stop operates on the following model:

  1. Always receive an indeterminately long list of update instructions
  2. Process each update instruction, from the tail (first in, first out), excluding those that have update dates prior to the most recent update date (mostly - some elements are not checked for sanity in this way, e.g. rate and spot).
  3. State-engine flop + Produce FE effects
  4. Almost never fail - provide the user with feedback as to why some state changes have not been accepted, such that offline applications can queue a list of changes and get back a list of updates and failures, both of which are legible for user and FE.
  5. Await next command list.

Subscription

Subscribe on [%website ~] for data.

On first subscription, receive full data set:

+$  state-0
  $:  %0
      =moon                                              ::  cycles
      =spot                                              ::  spotting
      =rain                                              ::  mucosal discharge
      =fire                                              ::  basal body temp
      =mate                                              ::  sexual encounters
      =bear                                              ::  pregnancy
      =hold                                              ::  birth control
      =opts                                              ::  system options
  ==
::
+$  moon  (cycle flow)                                   ::  track cycles
+$  flow                                                 ::  flow includes:
  $:  stop=(unit time)                                   ::    - stop date (or not)
      rate=(cycle rate)                                  ::    - flow rate (or none)
      edit=time                                          ::    - last edit date
  ==
::
+$  spot  (set time)                                     ::  track out of cycle bleeding, loosely (no edit filtering)
+$  rain  (cycle [p=cons edit=time])                     ::  track cervical mucousal viscocity
+$  fire  (cycle [p=base edit=time])                     ::  track basal body temperature
+$  mate  (set [p=time q=(unit @t) r=?])                 ::  track sexual encounters with optional details
+$  bear  (unit [star=time edit=time])                   ::  track pregnancy
+$  opts  [noti=? fert=? edit=time]                      ::  options - notifications and fertility predictions
+$  hold
  %-  unit
  $:  $=  type
      $%  [%pill h=@ud m=@ud am=? miss=(set time)]       ::  track hormonal pill b.c., record missed pills
          [%term wen=time again=time]                    ::  track implant/term b.c., record replacement date
      ==
      edit=time
  ==

Pokes and Outcomes

Pokes

Pokes are separated into 6 categories, each of which will be coded out in units for testing and FE work delegation. If a section below has not been completed assume that the code is subject to change.

The system always expects a drop which is a (list [activity time]). An activity is a blended case of all the pokes listed below, the time at the tail of the cell should be when the poke was made by the user, so that we can date it against conflicting updates from other sources, during sync.

Marks

The expected mark is a %dot-point. When there is a unit in a poke, I will write soft parsers - please assume that sending me 'garbage' or anything other than a reasonable answer will result in a null while a reasonable answer will be taken as the unit of itself.

Notes

Note: The user's experience, if it receives an empty data set from subscription, should be to enter a period they've experienced, from their past or currently using a [%flow wen=time], OR identify that they are pregnant, with a [%move wen=time due=?]. Almost all other activity is gated off of having some period recorded.

Note: Always Midnight, Sis. All times are interpreted as midnight on that day so don't try sending me something more specific. Or do. I don't really care. (this does not apply to the (list [activity **TIME**]) time, but anything called wen is midnight on that day.

Sanguine

Handles menstruation tracking.

+$  sanguine
  $%  [%flow wen=time]                                   ::  note menstruation start
      [%stop wen=time]                                   ::  note menstruation stop
      [%rate how=(unit rate) wen=time]                   ::  note flow rate
      [%spot wen=time]                                   ::  note spotting
  ==
Test Data

Load period data starting 11.1.2021 thru 8.5.2022:

:full-stop &dot-point ~[[stop+~2022.8.5 now] [flow+~2022.8.1 now] [stop+~2022.7.5 now] [flow+~2022.7.1 now] [stop+~2022.6.5 now] [flow+~2022.6.1 now] [stop+~2022.5.5 now] [flow+~2022.5.1 now] [stop+~2022.4.5 now] [flow+~2022.4.1 now] [stop+~2022.3.5 now] [flow+~2022.3.1 now] [stop+~2022.2.5 now] [flow+~2022.2.1 now] [stop+~2022.1.5 now] [flow+~2022.1.1 now] [stop+~2021.12.5 now] [flow+~2021.12.1 now] [stop+~2021.11.5 now] [flow+~2021.11.1 now]]

Add some rate reports:

:full-stop &dot-point ~[[rate+[`%1 ~2021.12.1] now] [rate+[`%2 ~2021.12.2] now] [rate+[`%3 ~2021.12.3] now] [rate+[`%4 ~2021.12.4] now] [rate+[`%5 ~2021.12.5] now]]

Add some spotting reports:

:full-stop &dot-point ~[[spot+~2021.11.6 now] [spot+~2021.12.7 now] [spot+~2022.1.8 now] [spot+~2022.2.9 now] [spot+~2022.3.10 now] [spot+~2022.4.11 now] [spot+~2022.5.12 now] [spot+~2022.6.13 now] [spot+~2022.7.14 now] [spot+~2022.8.15 now]]
[%flow wen=time]
[%stop wen=time]
[%spot wen=time]
[%rate how=(unit ?(%1 %2 %3 %4 %5) wen=time]

Physical

Handles fertility prediction aid tracking (basal body temp and cervical mucosal consistency)

+$  physical
  $%  [%temp baz=(unit base) wen=time]                   ::  note basal body temp for some day
      [%muco con=(unit cons) wen=time]                   ::  note cervical mucosal consistency
  ==
Test Data

Load some temps

:full-stop &dot-point ~[[temp+[`.98.6 now] now] [temp+[`.98.6 ~2022.8.9] now] [temp+[`.98.6 ~2022.8.8] now] [temp+[`.98.6 ~2022.8.7] now] [temp+[`.98.6 ~2022.8.6] now] [temp+[`.98.6 ~2022.8.5] now] [temp+[`.98.6 ~2022.8.4] now] [temp+[`.98.6 ~2022.8.3] now] [temp+[`.98.6 ~2022.8.2] now]]

Load some mucosal reports

:full-stop &dot-point ~[[muco+[`%1 now] now] [muco+[`%1 ~2022.8.9] now] [muco+[`%1 ~2022.8.8] now] [muco+[`%1 ~2022.8.7] now] [muco+[`%2 ~2022.8.6] now]  [muco+[`%3 ~2022.8.5] now]  [muco+[`%5 ~2022.8.4] now]  [muco+[`%1 ~2022.8.3] now] [muco+[`%1 ~2022.8.2] now]]
[%temp baz=(unit @rs) wen=time]
[%muco con=(unit cons) wen=time]

NOTE: %1 is "thick" and %5 is "thin" consistency wise - because %1 is the base state.

Controls

Handles birth control method tracking/alerting

Relation

Handles sexual encounter tracking

Election

Handles agent settings (notifications, fertility window predictions)

Pregnant

Handles pregnancy tracking

Scrys

[%x %all ~] Gives front end startup information

[%x %moon ?([%each ~] [%just @ ~] [%some @ @ ~])] Gives you all periods, a period (the one specified), or the periods between (the first one specified and the second one specified)

[%x %spot ~] Gives spot data

[%x %rain ~] Gives mucous data

[%x %fire ~] Gives basal body temp data

[%x %mate ~] Gives sex data

[%x %bear ~] Gives pregnancy data

[%x %hold ~] Gives birth control data

[%x %opts ~] Gives agent settings data

[%x %next ~] Gives a prediction of next period, if it can

  • On Error:
  • { need-next-data: ~ } - We need more consecutive periods to predict an outcome - basically we need at least 6 months of "consecutive" (more often than every 60 days, well over the normal variance) periods, recently, to be able to predict your next period. This means 7 start flow dates within 60 days of each other, end-over-end, and at least one within 45 days of now.bowl.
matildepark commented 1 year ago

We've run into a weird issue with it mounting. There's a branch set up at develop-ui with our boilerplate and we were working on just getting basic subscriptions down, but no matter what we do, when you access the page (on localhost:80 or localhost:3000, it doesn't matter), Eyre throws a stack trace:

crud: %request event failed
[%poke %request]
wire=/run-app-request/~.eyre_0v6.ddvhm.c728h.c2d3h.qa1e9.01kf9
  bar-stack
~[
  ~[//http-server/0v1s.dkq90/28/6]
  ~[
    /eyre/run-app-request/~.eyre_0v6.ddvhm.c728h.c2d3h.qa1e9.01kf9
    //http-server/0v1s.dkq90/28/6
  ]
  ~[//http-server/0v1s.dkq90/28/6]
]
take: failed
/sys/vane/eyre/hoon:<[2.356 3].[2.529 5]>
/sys/vane/eyre/hoon:<[2.357 3].[2.529 5]>
/sys/vane/eyre/hoon:<[2.359 3].[2.529 5]>
/sys/vane/eyre/hoon:<[2.368 3].[2.529 5]>
/sys/vane/eyre/hoon:<[2.370 3].[2.529 5]>
/sys/vane/eyre/hoon:<[2.370 7].[2.381 9]>
/sys/vane/eyre/hoon:<[2.372 7].[2.381 9]>
/sys/vane/eyre/hoon:<[2.375 28].[2.375 43]>
/sys/vane/eyre/hoon:<[2.385 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.388 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.389 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.390 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.396 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.397 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.399 5].[2.401 29]>
/sys/vane/eyre/hoon:<[2.400 7].[2.400 37]>
/sys/vane/eyre/hoon:<[1.807 5].[1.827 35]>
/sys/vane/eyre/hoon:<[1.809 5].[1.827 35]>
/sys/vane/eyre/hoon:<[1.809 9].[1.809 54]>
/sys/vane/eyre/hoon:<[1.809 20].[1.809 54]>

And if you browse the Network tab you can see that desk.js is spinning forever, never giving us its content. At first I thought it was because our scry or subscription requests were malformed, but even without any request to the back-end, Eyre throws its hands up trying to handle it. I wondered — "maybe the window.desk injection inside Eyre serving globs can't handle dashes in the desk name?" — but that's unclear, I removed all dashes and it just never showed up in Grid then. Well. Okay.

So. Here's what I'll say for reproduction:

Click "Full Stop" on the grid — you don't even have to run the dev server! You'll see the issue in the Dojo. The glob I've assigned to the docket is just the Grid, so you'd expect to see Grid, but instead nothing loads and it crashes on the back-end.