Init.
This commit is contained in:
commit
4c5d5bdea2
|
@ -0,0 +1,6 @@
|
|||
#*
|
||||
*#
|
||||
.#*
|
||||
*~
|
||||
venv/
|
||||
node_modules/
|
|
@ -0,0 +1,11 @@
|
|||
# from http://flask.pocoo.org/ tutorial
|
||||
from flask import Flask
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/") # take note of this decorator syntax, it's a common pattern
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
|
@ -0,0 +1,183 @@
|
|||
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 client’s 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
|
||||
coach’s 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.
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
-- Users known by the application. "Nickname" is a misnomer. Nom de
|
||||
-- user was too pretentious. It's how the customer wishes to be
|
||||
↓-- addressed, but "address" would be confusing.
|
||||
|
||||
CREATE TABLE users (
|
||||
id SERIAL,
|
||||
email CITEX UNIQUE NOT NULL,
|
||||
nickname TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Users who are currently staff
|
||||
|
||||
CREATE TABLE staff (
|
||||
staff_id INTEGER UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
active BOOLEAN
|
||||
);
|
||||
|
||||
-- Users who are currently clients
|
||||
|
||||
CREATE TABLE clients (
|
||||
client_id INTEGER UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
active BOOLEAN
|
||||
);
|
||||
|
||||
-- This is interesting, because we've basically created a M:1
|
||||
-- relationship of staff and clients, but a 1:1 relationship of
|
||||
-- clients to staff. That satisfies the current assignment, mostly.
|
||||
-- An appointment can then be made my a client, and there's only one
|
||||
-- staff person who it could apply to, so the query is straightforward
|
||||
-- then.
|
||||
--
|
||||
-- To extend this into a M:M relationship, you'd have to remove the
|
||||
-- "UNIQUE" setting from the staff_id field and use the
|
||||
-- relationship.id field instead for appointments.
|
||||
|
||||
CREATE TABLE relationship (
|
||||
id SERIAL,
|
||||
client_id INTEGER NOT NULL REFERENCES clients(client_id) ON DELETE CASCADE,
|
||||
staff_id INTEGER UNIQUE NOT NULL REFERENCES staff(staff_id) ON DELETE CASCADE
|
||||
);
|
||||
|
Loading…
Reference in New Issue