officehours/notes/bs.md

201 lines
7.0 KiB
Markdown
Raw Normal View History

2016-02-07 19:15:39 +00:00
Note: "BS" stands for BrainStorming.
#Arivale Coding Problem
## Problem description:
When clients sign up for the Arivale service, they develop a 1:1
relationship with a wellness coach over the course of a year. These
coaches help them interpret their personal health data as well as
make actionable recommendations to improve a clients overall
wellness. Clients need to schedule coaching calls on a monthly
basis. We want to create a web based experience that makes it easy
for clients to schedule a call. Clients should be able to see their
coachs availability and then book hour long coaching slot. Once a
slot is booked, other clients should not be able to book that slot
with the same coach.
2016-02-08 23:09:08 +00:00
## Alternatives
Google Calendar offers an "office hours" appointment mechanism. It
doesn't quite do what the problem requires; it's only available to
other members of the same school or corporate group account.
There's also a Django app, django-appointments, that probably does
most of what is asked of in this demo, but... I think I'd like to
take a crack at it with Flask (which I don't know), Psycopg2, and
doing most of the work (including a lot of the business logic) in
Postgres, just to see if I can.
2016-02-08 23:09:08 +00:00
2016-02-07 19:15:39 +00:00
## Solution requirements:
* Data Store
* Middle Tier
* Front-End
## Actors
* Staff
* Client
## Tables
* Table of *Users* (flags "staff," "client," "staff_active," "client_active") [User]
** Is there redundant information in those flags? Table-level
constraints to prevent "client = false" "client_active = true"
on the same object, for example?
* Table of *User/user relationships* [Staff_client_relationship]
** staff_user_id (constraint: staff flag must be TRUE, staff_active flag must be TRUE)
** client_user_id (constraint: user flag must be TRUE, user_active flag must be TRUE)
* Table of OfficeHours
** When the staff are available:
*** staff_id
*** availability: [(timestamp, timestamp)] defining TSRange: Availability
* Table of *Appointments*
** staff_client_relationship_id: ID
** reservation: (timestamp, timestamp) defining TSRANGE: Reservation
* Business rules -> rule values
** This could get ugly. What are the limits? One rule table per
rule datatype? Does Postgres have a union type, and how
horrible is it to work with?
## Accesses
* Client
** Retrieve: View upcoming appointments
** Create: Create a new appointment
** Update: Move an existing appointment
** Delete: Delete an existing appointment
** UNANSWERED QUESTIONS
*** Recurring appointments? Set/no set? How do others handle this?
REST Documents:
Appointment request: user, staff, time range
* payload schema check
User present and active?
Staff present and active?
Relationship present? (note: Never publish staff or relationship ID; user a slug for the customer if possible)
Time range sane?
* Positive length?
** Assertion
* Not in the past?
** Assertion (review: "What programmers believe about time")
** No, really: Timezones, Daylight Savings, all that jazz
* Legitimate length
** Business Rule
* Not too far in the future?
** Business Rule
** Can the business rules be stored in the database?
** If so, you'll need an admin page for them.
* Assume attack:
** Handle true fuzz.
** Handle corruptions.
** Handle crap.
** WHITELIST RULES ONLY
Time range available?
** OFFICE HOURS - for Coach only.
** Database can handle (Postgres has a RANGE operator now)
** Questions about performance, but don't care at this
point; just throw more metal at it.
* Can the INSERT detect user/staff/relationship validity?
* Can the INSERT deal with (some of) the time issues?
* What happens on INSERT failure?
** How to report?
Update request:
* All of the above, plus:
** Existing appointment?
** Add-then-delete as a transaction, OR Update? Read pros/cons
Retrieve:
* Is about permissions and ranges
** What the user sees is what the database allows them to see
* No further back in the past than (Business Rule) weeks
* If as OPA (i.e. JSON), retrieve a couple weeks in advance,
with scaling lookahead; Like you did for Spiral's data
sources list; the scaling rate can be found in Python List
implementation, I think. Or fibonacci with a limiter.
* 300ms or twiddle.
** The above is front-end stuff.
** No Bad Ideas. :-)
Delete:
* Appoinment exist?
* This user?
Other:
Non-REST issue
* Progressive Enhancement. If it doesn't work in Lynx, it
doesn't work.
** Some kind of second-page form for a time range?
* ARIA/Section 508 coverage?
Unit tests:
Create: An appointment is a USER wanting a RANGE
Logged in?
Good/bad user?
Good/bad range?
Good/bad placement?
Delete:
Logged in?
Yours?
Update:
Same as create plus:
Yours?
Retrieve:
Only the user ID and the start of the week matter.
Constraint: No past views. Not too far in the future
** Business Rule again
Secondary considerations: A staff member has a M:1 relationship with
clients, but clients have only a 1:1 with staff. Encoding that into the
Users table would make sense, only the staff's field would be Null.
While I want to enforce NO-NULL idiom as much as possible, the separate
table for that relationship [1] could be overkill; [2] permits the
development of a M:M relationship where a user could have more than one
coach, time and money permitting, but [2a] (probably) YAGNI.
Backend: Postgres, naturally. Leveraged as far as humanely possible.
It's been a few years, but I'm genuinely impressed with what it does.
Middle Tier: What's the lightest Python application server there is?
Flask?
Front End: HAML/Less/A script I don't know (Like Clojure, Pure, or Type?
Something fun and different!)
What we don't care about (thus far):
Logging in.
Session management.
TODO VirtualEnv
TODO Flask
TODO PsychoPG2
TODO Flask skeleton
TODO Postgres Database
TODO Postgres retrieval example
TODO Postgres range example
TODO Deliver home page
TODO Deliver retreivals
2016-02-08 23:09:08 +00:00
---
Quick thoughts:
Craft views or
2016-02-07 19:15:39 +00:00