- When a user account is registered, both a
Pal
andMember
account are created for it, since the requirements suggest thatMember
s may double asPals
and can earn extraVisit
time by fulfilling appointments for otherMember
s Member
s have an ephemeral monthly allowance ofplan_minutes
, which turn over at the beginning of each month- NOTE this was not one of the requirements in the instructions - it was an aspect of the description of Papa which I had internalized
- Despite the complexity it adds to the code, I decided to keep it because I felt like it was exactly the sort of complication which comes up in feature work... and because it was a useful thought experiment :)
- "Banked" minutes are tracked via
MinuteLedger
- Both credits and debits live together in the table as positive and negative amounts, respectively
- Entries are linked to the underlying
User
account, since eachUser
has both aMember
andPal
account - A
Member
'splan_minutes
are not included in the table as a credit since they do not carry over at the end of the month (seevisits.model.Member.minutes_available()
for the details on how banked minutes are calculated)
- When a
Member
requests aVisit
, a debit is added to theirMinuteLedger
- When a
Pal
accepts aVisit
, aFulfillment
is created - Cancelling a
Visit
will also cancel any associatedFulfillment
s andMinuteLedger
s - Cancelling a
Fulfillment
makes theVisit
visible again to otherPal
s for scheduling - When a
Pal
completes aFulfillment
, a credit is added to theirMinuteLedger
, less our 15% cut
- Python and Django are (in theory) fairly readable, even for non-pythonistas
User
accounts are managed with Django's built in authentication system- Bootstrap is easy to set up and familiar enough that using it for a simple UI reduces the number of variables in building this project
- Python3 (aliased to
python
in example commands below) - sqlite3 (django defaults to sqlite for simple dev setup)
$ python -m pip install Django django-crispy-forms
$ git clone https://github.com/sysread/not-papa.git
$ cd not-papa
$ python manage.py migrate
$ python manage.py runserver
$ python manage.py test visits
$ python manage.py test -v2
$ python manage.py test --parallel=4
/admin
provides a fairly full-featured CRUD for a django app's database. In
order to log into it, you will need a superuser account.
python manage.py createsuperuser --username=someone [email protected]
Django provides some easy mechanisms for viewing the SQL generated by the ORM for a query as well as the query's execution plan.
Wherever you see a query, e.g.:
# From visits.views.list_visits()
query = request.user.member.visit_set.order_by("-when").filter(cancelled=False)
You can print the generated SQL out to view in the server log output:
print(query.query)
As well as the execution plan:
print(query.explain())
- Monthly roll-ups of the
MinuteLedger
to make calculation of banked minutes simpler and more efficient User
s' time zones should be detected and used to control the display of dates and times on relevant pages- "Request a
Visit
" form should have a usable date/time picker widget Member
s' address would be needed to schedule and make an actualVisit
- Insurance
Plan
model that includes the number of plan minutes - All the kinds of security required to make account registration safe
- On the
Member
'sVisits
list, convert individual forms into aFormSet
so we don't lose error messages on failed cancelations - Paginate the list of completed
Visits
when displaying aMember
'sVisits
- Segregate list of
Visit
s by status, with incompleteVisit
s in ascending order, but completedVisit
s in descending order - Profile page with transaction history and minutes balances
- Cron job to cancel
Visit
s which never get accepted by aPal
and notify theMember
Visit
s show names whenPal
hasVisit
ed theMember
in the past- Validation to ensure the same account does not fulfill its own
Visit
s - Browser tests (e.g., selenium)