Commit 9bdef2907fdc3f37fc2f21885d045f520680b0e2

Authored by Andrew Buss
1 parent 68603caeec
Exists in master

Converted design use cases to tex.. in progress

Showing 2 changed files with 2019 additions and 2 deletions Inline Diff

DesignUseCases.tex View file @ 9bdef29
File was created 1 \documentclass[letterpaper]{scrartcl} % or whatever
2 \usepackage{tgpagella}
3 \setkomafont{disposition}{\normalfont\bfseries}
4 %\usepackage[markuppercase]{scrpage2}
5 \title{\huge Design Use Cases}
6 \date{\today}
7 \author{\Large Students With A Goal (S.W.A.G.)}
8 \usepackage[pass]{geometry}
9 \usepackage{hyperref}
10 \usepackage{enumitem}
11 \setlist[description]{style=multiline,leftmargin=3cm,font=\normalfont\textbf}
12 \setlistdepth{9}
13
14 \setlist[itemize,1]{label=$\bullet$}
15 \setlist[itemize,2]{label=$\bullet$}
16 \setlist[itemize,3]{label=$\bullet$}
17 \setlist[itemize,4]{label=$\bullet$}
18 \setlist[itemize,5]{label=$\bullet$}
19 \setlist[itemize,6]{label=$\bullet$}
20 \setlist[itemize,7]{label=$\bullet$}
21 \setlist[itemize,8]{label=$\bullet$}
22 \setlist[itemize,9]{label=$\bullet$}
23 \renewlist{itemize}{itemize}{9}
24 \begin{document}
25 \maketitle
26 \begin{center}
27 \begin{tabular}{l r}
28 Melody Jeng & System Architect \\
29 Arno Gau & Senior System Analyst \\
30 Rachel Lee & Software Development Lead \\
31 Laura Hawkins & Project Manager \\
32 Rohan Rangray & Algorithms Specialist\\
33 Andrew Buss & Database Specialist \\
34 Phuong Tran & Quality Assurance Lead \\
35 Chung Kang Wang & Business Analyst\\
36 Masud Rahman & User Interface Specialist\\
37 Kevin Mach & User Interface Specialist\\
38 \end{tabular}
39 \end{center}
40 \begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
41 \tableofcontents
42 \newpage
43 \section{Accounts}
44 \subsection{[A1] User Registration}
45 \begin{description}[style=multiline,leftmargin=3cm]
46 \item[Description]{To create and save decks, the system requires the user
47 to create an account prior. The user will be able to create an account
48 through registering.}
49 \item[Desired Outcome]{An account will be created for the user from the
50 specified username, password, email. The user will be able to log into
51 the aforementioned account.}
52
53 \item[User Goals]{The user shall have an account to participate in the
54 website's activities.}
55
56 \item[Primary Actor]{~User (student)}
57
58 \item[Dependency Use Cases]{~None}
59
60 \item[Priority Level]{~``Must''}
61
62 \item[Status]{Not Implemented}
63
64 \item[Pre-conditions]
65
66 \item[Post-conditions]
67
68 \begin{itemize}
69 \itemsep1pt\parskip0pt\parsep0pt
70 \item
71 {The user has an account registered with the system.}
72 \end{itemize}
73
74 \item[Trigger]{The user wants to create an account.}
75
76 \item[Workflow]
77
78 \begin{enumerate}
79 \itemsep1pt\parskip0pt\parsep0pt
80 \item
81 {The user shall click the sign up button.}
82 \item
83 {The client renders a registration form and displays it to the user}
84 \item
85 {The user fills the form}
86 \item
87 {The client checks that the provided email is not invalid, and that
88 the password is not valid. If anything is not valid, it displays an
89 error and returns this to the user. }
90 \item
91 {If the form is valid, the client POSTs the form in JSON format to the
92 server API at /api/users/me.}
93 \item
94 {The server deserializes and validates the data. If it's not valid, it
95 returns an error to the client.}
96 \item
97 {The server creates a new User object from the provided data, filling
98 in the appropriate fields}
99 \item
100 {The server saves the user object}
101 \item
102 {The server marks the user's email as unverified}
103 \item
104 {The server sends an email to the user's address with a link to
105 validate the user's email address.}
106 \item
107 {The server responds with success and logs the user in on a new
108 session for the user. }
109 \item
110 {The client reports success to the user and stores the sessionid for
111 future requests.}
112 \end{enumerate}
113
114 {}
115 {Verification Workflow:}
116
117 \begin{enumerate}
118 \itemsep1pt\parskip0pt\parsep0pt
119 \item
120 {The user receives an email with a link to verify their email. The
121 user clicks the link}
122 \item
123 {The client submits the verification code to the server}
124 \item
125 {The server validates the code. If the code is not valid, it returns
126 an error to the client.}
127 \item
128 {The server marks the user's email as valid and saves the User object
129 again. The user's account is now active}
130 \item
131 {The client reports success. }
132 \end{enumerate}
133
134 \end{description}
135
136 \newpage
137 \subsection{\texorpdfstring{{{[}A2{]} User
138 Login}}{{[}A2{]} User Login}}
139
140 \begin{description}
141 \item[Description]{User is able to login to personal account.}
142
143 {Desired Outcome:}{~The user shall be able to provide their username and
144 password to access their courses and flash cards. The user shall gain
145 access to the list of the courses they have added, and be able to review
146 the flash cards they have added to their decks.}
147
148 \item[User Goals]{The user wants to resume use of the site on another
149 device, or use the site after logging out.}
150
151 \item[Primary Actor]{~User (student)}
152
153 \item[Dependency Use Cases]{~{[}A1{]} User Registration}
154
155 \item[Priority Level]{~``Must''}
156
157 \item[Status]{Not Implemented}
158
159 \item[Pre-conditions]
160
161 \begin{itemize}
162 \itemsep1pt\parskip0pt\parsep0pt
163 \item
164 {The user has created an account before.}
165 \end{itemize}
166
167 \item[Post-conditions]
168
169 \begin{itemize}
170 \itemsep1pt\parskip0pt\parsep0pt
171 \item
172 {The user can navigate the site and see their data.}
173 \end{itemize}
174
175 \item[Trigger]{The User shall enter their email and password into the Login
176 form. The user then submits this information by clicking the ``Login''
177 button or pressing the return key.}
178
179 \item[Workflow]
180
181 \begin{enumerate}
182 \itemsep1pt\parskip0pt\parsep0pt
183 \item
184 {api.py verifies that the User has submitted an email and password}
185 \item
186 {api.py authenticates the User's email and password and checks if the
187 User is active}
188 \item
189 {api.py logs the User in using the Django login feature}
190 \item
191 {Front-end displays the home page for the User}
192 \end{enumerate}
193
194 \newpage
195
196 \subsection{\texorpdfstring{{{[}A3{]} Add a
197 Class}}{{[}A3{]} Add a Class}}
198
199 {Description:}{~The user shall be able to add a class and access the
200 flashcards associated with that class.}
201
202 {Desired Outcome: }{The class shall be linked with the student's account
203 and the student shall have the ability to read and publish flashcards
204 for this class.}
205
206 \item[User Goals]{The user wants to publish flashcards for this class, and
207 reads the flashcards for this class that are published by other users.}
208
209 {Primary Actor}{: User (student)}
210
211 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
212 Login}
213
214 {Priority Level: }{``Must''}
215
216 \item[Status]{Not implemented}
217
218 \item[Pre-conditions]
219
220 \begin{itemize}
221 \itemsep1pt\parskip0pt\parsep0pt
222 \item
223 {The user has created an account.}
224 \item
225 {The user is logged in to his/her account}
226 \item
227 {The user has been whitelisted by the instructor of the class, if
228 required.}
229 \end{itemize}
230
231 \item[Post-conditions]
232
233 \begin{itemize}
234 \itemsep1pt\parskip0pt\parsep0pt
235 \item
236 {The user can read the flashcards being published for the class and
237 add them to his/her deck.}
238 \item
239 {The user can publish flashcards to be viewed and added by other users
240 in the same class.}
241 \end{itemize}
242
243 \item[Trigger]{The user clicks an ``Add Class'' button to add a class to
244 his/her list of ``Enrolled Classes''}
245
246 {Workflow: }
247
248 \begin{enumerate}
249 \itemsep1pt\parskip0pt\parsep0pt
250 \item
251 {The client shall show a dialog to search for classes.}
252 \item
253 {The user begins to type their class name or number}
254 \item
255 {The text box will show suggestions as a user types~~~~~~~~}
256 \end{enumerate}
257
258 \begin{itemize}
259 \itemsep1pt\parskip0pt\parsep0pt
260 \item
261 {Implementation unspecified at present; need to do further research
262 (django-autocomplete-lite?)}
263 \end{itemize}
264
265 \begin{enumerate}
266 \setcounter{enumi}{3}
267 \itemsep1pt\parskip0pt\parsep0pt
268 \item
269 {The user shall select a class by clicking an ``Add Class'' button
270 associated with a specific class}
271 \item
272 {The client shall submit a POST request to /api/users/me/sections with
273 the course ID that they would like to add. }
274 \item
275 {The server shall check if there is a whitelist for the class that the
276 user is trying to add}
277 \item
278 {If there is a whitelist, the server shall check if the user is on the
279 whitelist}
280 \item
281 {If the class does not have a whitelist or if the user is in the
282 whitelist for that class, the system shall add the section to the
283 user's list of classes. }
284 \end{enumerate}
285 \end{description}
286 {}
287
288 \newpage
289
290 {}
291
292 \subsection{\texorpdfstring{{{[}A4{]} }{Drop a
293 Class}}{{[}A4{]} Drop a Class}}
294
295 \begin{description}
296 \item[Description]{The user can remove themselves from a course he/she is
297 registered to}
298
299 {Desired Outcome:}{~The user has dropped the class and no longer need
300 access to the flashcards for said class. This means they can no longer
301 see the flashcards associated to the class that they dropped }
302
303 \item[User Goals]{The user shall not have access to a class and the
304 flashcards associated with that class. They will no longer see the class
305 listed in their list of ``Enrolled Classes''}
306
307 \item[Primary Actor]{~User (student)}
308
309 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
310 Login, {[}A3{]} Add a Class}
311
312 \item[Priority Level]{~ ``Should''}
313
314 \item[Status]{Not Implemented }
315
316 {Pre-conditions: }
317
318 \begin{itemize}
319 \itemsep1pt\parskip0pt\parsep0pt
320 \item
321 {User has a valid account.}
322 \item
323 {User is logged in.}
324 \item
325 {User has enrolled in classes.}
326 \end{itemize}
327
328 \item[Post-conditions]{~}
329
330 \begin{itemize}
331 \itemsep1pt\parskip0pt\parsep0pt
332 \item
333 {User shall no longer have access to dropped class, or associated
334 flashcards}
335 \end{itemize}
336
337 {Trigger:}{~User clicked button to drop class.}
338
339 {Workflow: }
340
341 \begin{enumerate}
342 \itemsep1pt\parskip0pt\parsep0pt
343 \item
344 {The user shall click ``Drop'' (or equivalent) button.}
345 \item
346 {The client shall ~display a dialogue box which will say ``Are you
347 sure you want to drop this class?''}
348 \item
349 {The user shall click ``Yes'' to confirm that they want to drop the
350 class}
351 \item
352 {The client shall submit a DELETE request to
353 /api/users/me/sections/\textless{}section ID number\textgreater{}.}
354 \item
355 {If the user is not already enrolled in the section, the server will
356 return a 404 Not Found error, which the client shall handle. (The
357 client should not show an error to the user)}
358 \item
359 {The server shall remove the selected class from a user's list of
360 classes. }
361 \item
362 {The server shall return success to the client}
363 \end{enumerate}
364 \end{description}
365 \newpage
366
367 {}
368
369 \subsection{\texorpdfstring{{{[}A5{]} Password
370 change}}{{[}A5{]} Password change}}
371
372 \begin{description}
373 \item[Description]{The user shall be able to change the password for their
374 account in the account settings. This requires that they are logged in.
375 }
376
377 {Desired Outcome:}{~The user's password shall be changed and the user
378 shall be able to log in with the new password in the future}
379
380 \item[User Goals]{The user wants to use a different password in the future}
381
382 \item[Primary Actor]{~User (student)}
383
384 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
385 Login}
386
387 {Details: }{The user provides their current password and a new password
388 in a form. If the current password is correct, the system updates their
389 password to the requested new password.}
390
391 \item[Priority Level]{~``Must''}
392
393 \item[Status]{Not }{implemented}
394
395 \item[Pre-conditions]
396
397 \begin{itemize}
398 \itemsep1pt\parskip0pt\parsep0pt
399 \item
400 {The user has created an account}
401 \item
402 {The user has logged in }
403 \item
404 {The user knows their current password}
405 \end{itemize}
406
407 \item[Post-conditions]
408
409 \begin{itemize}
410 \itemsep1pt\parskip0pt\parsep0pt
411 \item
412 {The user's password is changed}
413 \item
414 {The user can log in with the new password}
415 \end{itemize}
416
417 \item[Trigger]{User clicks ``Change Password'' button in Accounts page}
418
419 {Workflow: }
420
421 \begin{enumerate}
422 \itemsep1pt\parskip0pt\parsep0pt
423 \item
424 {The user shall press the ``Change Password'' button}
425 \item
426 {The client shall render a form that requires the user to enter their
427 old password and new password}
428 \item
429 {The user shall enter their current password and the desired new
430 password}
431 \item
432 {The client shall verify that no fields are blank}
433 \item
434 {The client shall submit the data to the server by sending a PATCH
435 request to /api/users/me containing ``old\_password'' and
436 ``new\_password'' values.}
437 \item
438 {The server shall validate the pre-existing password}
439 \item
440 {If server cannot validate the pre-existing password, the client will
441 render the same form with a message informing the user that the
442 pre-existing password that they have provided is incorrect}
443 \item
444 {If the server successfully validates the pre-existing password, the
445 system shall change the user's password}
446 \item
447 {The client shall return a success to the user}
448 \end{enumerate}
449 \end{description}
450 {}
451
452 \newpage
453
454 {}
455
456 \subsection{\texorpdfstring{{{[}A6{]} Password reset
457 }}{{[}A6{]} Password reset }}
458
459 \begin{description}
460 \item[Description]{The user shall be able to reset their password without
461 being logged in }
462
463 {Desired Outcome:}{~The user's password shall be changed to one that
464 they remember}
465
466 \item[User Goals]{The user does not know their current password but wants
467 to log into the site}
468
469 \item[Primary Actor]{~User (student)}
470
471 {Dependency Use Cases: }{{[}A1{]} User Registration}
472
473 {Details: }{The user provides their email in a password reset form. If
474 the address is valid, the site sends a password reset link with a random
475 token to that address. If the address is invalid, the site does not send
476 a link. For security reasons, we do not reveal to the user whether the
477 email address was valid, and we expire the link after 24 hours. When a
478 user visits the link emailed to them, they are able to specify a new
479 password in a form. When they submit the form, their password is updated
480 if the token is correct. }
481
482 \item[Priority Level]{~``Must''}
483
484 \item[Status]{Not i}{mplemented}
485
486 \item[Pre-conditions]
487
488 \begin{itemize}
489 \itemsep1pt\parskip0pt\parsep0pt
490 \item
491 {The user has created an account before}
492 \item
493 {The user knows the email address attached to their account}
494 \end{itemize}
495
496 \item[Post-conditions]
497
498 \begin{itemize}
499 \itemsep1pt\parskip0pt\parsep0pt
500 \item
501 {The user's password is changed}
502 \item
503 {The user can log in with the new password}
504 \end{itemize}
505
506 \item[Trigger]{User clicks ``Forgot Password'' button on the login page}
507
508 \item[Workflow, requesting password reset]
509
510 \begin{enumerate}
511 \itemsep1pt\parskip0pt\parsep0pt
512 \item
513 {The user shall click ``Forgot Password'' (or equivalent) button}
514 \item
515 {The client shall prompt the user for their current email}
516 \item
517 {The user shall submit their email address}
518 \item
519 {The client shall validate that the email address is formatted
520 correctly}
521 \item
522 {The client shall submit the email address to the server in a POST
523 request to /api/reset\_password with an ``email'' value}
524 \item
525 {The server shall check if an account exists with the email entered by
526 the user}
527 \item
528 {If no such account exists, the server shall return an error to the
529 frontend, which will display it to the user}
530 \item
531 {If the account does exist, the server will:}
532 \end{enumerate}
533
534 \begin{enumerate}
535 \itemsep1pt\parskip0pt\parsep0pt
536 \item
537 {Create a new password reset token for the user}
538 \item
539 {Send an email to the user with a link containing the token and the
540 user's ID}
541 \end{enumerate}
542
543 \item[Workflow, resetting password]
544
545 \begin{enumerate}
546 \setcounter{enumi}{8}
547 \itemsep1pt\parskip0pt\parsep0pt
548 \item
549 {The user shall click the link in the email and visit
550 /app/password\_reset}
551 \item
552 {The client shall render a form that will prompt the user for a new
553 password}
554 \item
555 {The user shall provide a new password in the form}
556 \item
557 {The client shall submit the password to the server}
558 \item
559 {If the user tries to submit without a password in the text field, the
560 client shall display a message saying ``Password cannot be blank.''}
561 \item
562 {The server first verifies that the token is valid for the user}
563 \item
564 {The server then verifies that the user's new password is non-blank}
565 \item
566 {If neither of the above verifications fail, the server shall change
567 the password associated with the user's email. }
568 \end{enumerate}
569 \end{description}
570 \newpage
571
572 {}
573
574 \subsection{\texorpdfstring{{{[}A7{]} Limit Student Access to Courses
575 }}{{[}A7{]} Limit Student Access to Courses }}
576
577 \begin{description}
578 \item[Description]{The instructor shall be able to limit access to the
579 courses that he is in charge of by whitelisting only those students that
580 are actually in the class.}
581
582 {Desired Outcome:}{~The class will have limited access and only those
583 users who are whitelisted may enroll in the class.}
584
585 \item[User Goals]{The instructor wants to limit access to his class so only
586 the students who are actually in his class participate, and nobody
587 else.}
588
589 {Primary Actor: }{User (instructor)}
590
591 {Dependency Use Cases: }{{[}A1{]} User Registration, {[}A2{]} User
592 Login}
593
594 {Priority Level: }{``Should''}
595
596 \item[Status]{Not Implemented}
597
598 {Pre-condition:}
599
600 \begin{itemize}
601 \itemsep1pt\parskip0pt\parsep0pt
602 \item
603 {User has valid instructor's account}
604 \end{itemize}
605
606 {Post-condition: }
607
608 \begin{itemize}
609 \itemsep1pt\parskip0pt\parsep0pt
610 \item
611 {Only those users who were whitelisted may add the class.}
612 \end{itemize}
613
614 \item[Trigger]{The instructor emails the administrator and requests to
615 limit access to his class.}
616
617 {Workflow: }
618
619 \begin{enumerate}
620 \itemsep1pt\parskip0pt\parsep0pt
621 \item
622 {The instructor emails the administrators from his UCSD email address
623 and requests to limit access to his course. He provides a list of
624 emails of the students that are to be whitelisted.}
625 \item
626 {The administrators visit a custom admin page, select the course, and
627 paste the list of emails. They submit the page directly (no separate
628 frontend here) to the server.}
629 \item
630 {The server shall create a WhitelistedAddress for each provided email,
631 attaching it to the section taught by the instructor.}
632 \item
633 {The server shall add any existing users whose email addresses appear
634 in the whitelist to the class. }
635 \end{enumerate}
636 \end{description}
637 \newpage
638
639
640
641 \subsection{\texorpdfstring{{{[}A8{]} User
642 Logout}}{{[}A8{]} User Logout}}
643
644 \begin{description}
645 \item[Description]{The user shall be able to log out of his/her account on
646 the site.}
647
648 {Desired Outcome:}{~The user's information and data will no longer be
649 accessible after logging out. }
650
651 \item[User Goals]{The user is done with his/her session of using the
652 website, and wants to make sure others cannot access the data in his/her
653 account.}
654
655 \item[Primary Actor]{~User (student)}
656
657 \item[Dependency Use Cases]
658
659 \item[Priority Level]{~``Must''}
660
661 \item[Status]{Implemented}
662
663 {Pre-conditions: }{The user is logged into their account}
664
665 \item[Post-conditions]{~}{The user's data can no longer be accessed.}
666
667 {Trigger:}{~User clicks ``Logout'' button}
668
669 \item[Workflow]
670
671 \begin{enumerate}
672 \itemsep1pt\parskip0pt\parsep0pt
673 \item
674 {api.py logs the User out using the Django logout feature}
675 \item
676 {Front-end displays application login page}
677 \end{enumerate}
678
679
680
681 \newpage
682
683
684
685 \subsection{\texorpdfstring{{{[}A9{]} Contact
686 Admin}}{{[}A9{]} Contact Admin}}
687
688 \begin{description}
689 \item[Description]{The user shall be able to contact the admin.}
690
691 {Desired Outcome:}{~The user shall send a message to the admin; the
692 admin shall receive the message.}
693
694 {User Goals:}{~The user sends a message to the admin.}
695
696 \item[Primary Actor]{~User}
697
698 \item[Dependency Use Cases]{~None}
699
700 {Priority Level: }{``Must''}
701
702 \item[Status]{Not implemented}
703
704 \item[Pre-conditions]{~None.}
705
706 \item[Post-conditions]{~The admin receives the user's message.}
707
708 {Trigger:}{~User has navigated to our website. }
709
710 \item[Workflow]
711
712 \begin{enumerate}
713 \itemsep1pt\parskip0pt\parsep0pt
714 \item
715 {The frontend displays the admin email address on every page in the
716 application.}
717 \end{enumerate}
718 \end{description}
719 \newpage
720
721 {}
722
723 \subsection{\texorpdfstring{{{[}F1{]} Push Flashcard
724 }}{{[}F1{]} Push Flashcard }}
725
726 \begin{description}
727 \item[Description]{The user shall be able to create a flashcard with their
728 input. }
729
730 {Desired Outcome:}{~The user shall have the flashcard added to their own
731 deck and the Live Feed. }
732
733 \item[User Goals]{The user will see their flashcard in their deck and the
734 flashcard will be shared with others. }
735
736 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
737 Login, {[}A3{]} Add a Class}
738
739 {Pre-conditions: }
740
741 \begin{itemize}
742 \itemsep1pt\parskip0pt\parsep0pt
743 \item
744 {The User has an account }
745 \item
746 {The User has added at least one class}
747 \item
748 {The User is on the class' page}
749 \end{itemize}
750
751 \item[Post-conditions]
752
753 \begin{itemize}
754 \itemsep1pt\parskip0pt\parsep0pt
755 \item
756 {The User has flashcard added to their deck}
757 \item
758 {The Flashcard is shown in the Live Feed}
759 \item
760 {Other users can add this flashcard to their decks}
761 \end{itemize}
762
763 {Trigger:}{~}
764
765 \begin{itemize}
766 \itemsep1pt\parskip0pt\parsep0pt
767 \item
768 {The User has clicked on the button ``Make New Flashcard''.}
769 \item
770 {The Server receives a POST request containing the flashcard data.}
771 \end{itemize}
772
773 {Workflow: }
774
775 \begin{enumerate}
776 \itemsep1pt\parskip0pt\parsep0pt
777 \item
778 {The User is at the live feed for the class.}
779 \item
780 {The User shall click on the button}{Push
781 Flashcard}
782 \item
783 {The
784 }{Client}{shall
785 present a dialog box for inputting the flashcard text to the User.}
786 \item
787 {The User shall input the flashcard text.}
788 \item
789 {Optionally, the User shall mark keywords in the flashcard text.}
790 \item
791 {If the User creates this flashcard outside of the lecture time, he
792 will get the option to change the material date.}
793 \item
794 {The User shall click on the `Submit' button to submit the flashcard
795 text, blanks, and material date, in JSON form as a POST request.}
796 \item
797 {The Server shall obtain the flashcard information by deserializing
798 the JSON in the POST request.}
799 \item
800 {The Server shall create a new record for this flashcard in the
801 Flashcards table in the database.}
802 \item
803 {The Server shall publish the newly created card to the live feed of
804 the class.}
805 \end{enumerate}
806 \end{description}
807 {Alternative Workflow:}
808
809 \begin{enumerate}
810 \itemsep1pt\parskip0pt\parsep0pt
811 \item
812 {The User shall view a flashcard that he/she did not create}
813 \item
814 {The User shall click ``Edit''}
815 \item
816 {The client shall present a dialog box for editing the existing
817 flashcard text}
818 \item
819 {The User shall make edits}
820 \item
821 {The User shall click ``save''}
822 \item
823 {The client shall send a POST request}
824 \item
825 {The server shall remove the original card from user's deck}
826 \item
827 {The Server shall obtain the flashcard information by deserializing
828 the JSON in the POST request.}
829 \item
830 {The Server shall create a new record for this flashcard in the
831 Flashcards table in the database.}
832 \item
833 {The Server shall publish the newly created card to the live feed of
834 the class.}
835 \end{enumerate}
836
837 \newpage
838
839 {}
840
841 \subsection{\texorpdfstring{{{[}F2{]} Edit
842 Flashcard}}{{[}F2{]} Edit Flashcard}}
843
844 \begin{description}
845 \item[Description]{The user shall be able to edit the text on their own
846 flashcard }
847
848 {Desired Outcome:}{~Flashcard is edited and saved appropriately}
849
850 \item[User Goals]{To be able to change text on a flashcard}
851
852 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
853 Login, {[}A3{]} Add a Class, {[}F1{]} Push Flashcard, {[}F3{]} Pull
854 Flashcard}
855
856 \item[Pre-conditions]
857
858 \begin{itemize}
859 \itemsep1pt\parskip0pt\parsep0pt
860 \item
861 {Flashcard is created}
862 \item
863 {Flashcard in user's deck}
864 \item
865 {Flashcard is viewable}
866 \end{itemize}
867
868 \item[Post-conditions]
869
870 \begin{itemize}
871 \itemsep1pt\parskip0pt\parsep0pt
872 \item
873 {Flashcard is edited}
874 \end{itemize}
875
876 {Trigger:}{~User has clicked ``Edit'' button when viewing a specific
877 flashcard}
878
879 {Workflow: }
880
881 \begin{enumerate}
882 \itemsep1pt\parskip0pt\parsep0pt
883 \item
884 {The user shall view their deck}
885 \item
886 {The client shall present user with a grid view of cards in
887 chronological creation order}
888 \item
889 {The user shall select a flashcard and click `Edit'}
890 \item
891 {The client shall produce an editable dialog box containing flashcard
892 text}
893 \item
894 {The user shall make desired changes}
895 \item
896 {The user shall click `Save'}
897 \item
898 {The client shall generate a POST request for a new flashcard and send
899 it to the server}
900 \item
901 {If the user changed only the blanks of the cards, the server shall
902 create a new FlashcardMask object and update the appropriate
903 UserFlashcard object with a reference to it.}
904 \item
905 {If the user changed the text of the card, the server will instead:}
906 \end{enumerate}
907
908 \begin{enumerate}
909 \itemsep1pt\parskip0pt\parsep0pt
910 \item
911 {create a new flashcard for the section}
912 \item
913 {push it to the feed}
914 \item
915 {add it to the user's deck}
916 \item
917 {hide the old card from the user}
918 \item
919 {and return the new card to the user}
920 \end{enumerate}
921 \end{description}
922 {}
923
924 \newpage
925
926 {}
927
928 \subsection{\texorpdfstring{{{[}F3{]} Pull
929 Flashcard}}{{[}F3{]} Pull Flashcard}}
930
931 {Description:}{~The User shall be able to add flash cards to their own
932 deck from the Live Feed. }
933
934 {Desired Outcome:}{~The User shall have the flashcard added to their own
935 deck }
936
937 \item[User Goals]{The user will be able to review that flashcard. }
938
939 \item[Primary Actor]{~User (student)}
940
941 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
942 Login, ~{[}A3{]} Add a Class, {[}F1{]} Push Flashard}
943
944 \item[Priority Level]{~``Must'' }
945
946 \item[Status]{Not Implemented}
947
948 {Pre-conditions: }
949
950 \begin{itemize}
951 \itemsep1pt\parskip0pt\parsep0pt
952 \item
953 {Flashcard has been created }
954 \item
955 {That flashcard is in the Live Feed}
956 \end{itemize}
957
958 \item[Post-conditions]
959
960 \begin{itemize}
961 \itemsep1pt\parskip0pt\parsep0pt
962 \item
963 {User shall have that flashcard added to their deck}
964 \item
965 {User can review this flashcard later}
966 \end{itemize}
967
968 {Trigger:}{~User has clicked on the flashcard in the Live Feed.}
969
970 {Workflow: }
971
972 \begin{enumerate}
973 \itemsep1pt\parskip0pt\parsep0pt
974 \item
975 {The User is in the Live Feed.}
976 \item
977 {User shall click on the ``Pull Flashcard'' button on a Flashcard in
978 the Feed.}
979 \item
980 {The Client shall make the pulled Flashcard disappear from the Live
981 Feed}
982 \item
983 {The Client shall make the pulled Flashcard appear in the User's Deck
984 on the sidebar.}
985 \item
986 {The Client shall submit a POST request to
987 /api/flashcards/\textless{}flashcard id\textgreater{}/pull}
988 \item
989 {The server shall create a UserFlashcard object to represent that the
990 user's deck contains the card.}
991 \item
992 {The server shall notify connected clients about the new card rating,
993 if any}
994 \item
995 {Connected clients will take the new rating into account when next
996 rearranging the feed.}
997 \end{enumerate}
998 \end{description}
999 \newpage
1000
1001 {}
1002
1003 \subsection{\texorpdfstring{{{[}F4{]} Flag Inappropriate
1004 Cards}}{{[}F4{]} Flag Inappropriate Cards}}
1005
1006 \begin{description}
1007 \item[Description]{Cards may be flagged indicating inappropriate content}
1008
1009 {Desired Outcome:}{~The flashcard's inappropriateness variable is
1010 adjusted}
1011
1012 \item[User Goals]{To note if a card should not belong in the class and
1013 should not be displayed in the feed}
1014
1015 \item[Primary Actor]{~~User (Student)}
1016
1017 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
1018 Login, {[}A3{]} Add a Class, {[}F1{]} Push Flashcard}
1019
1020 \item[Priority Level]{~``Should''}
1021
1022 \item[Status]{Unimplemented}
1023
1024 \item[Pre-conditions]
1025
1026 \begin{itemize}
1027 \itemsep1pt\parskip0pt\parsep0pt
1028 \item
1029 {User is enrolled in a class}
1030 \end{itemize}
1031
1032 \begin{itemize}
1033 \itemsep1pt\parskip0pt\parsep0pt
1034 \item
1035 {Flashcard is created}
1036 \item
1037 {Flashcard is viewable in feed}
1038 \end{itemize}
1039
1040 \item[Post-conditions]
1041
1042 \begin{itemize}
1043 \itemsep1pt\parskip0pt\parsep0pt
1044 \item
1045 {Flashcard is hidden from user}
1046 \item
1047 {Flashcard internal variable is adjusted}
1048 \end{itemize}
1049
1050 {Trigger:}{~User clicks flag on a specific flashcard}
1051
1052 \item[Workflow]
1053
1054 \begin{enumerate}
1055 \itemsep1pt\parskip0pt\parsep0pt
1056 \item
1057 {The User is at a page of their classes.}
1058 \item
1059 {The User selects one of their classes to enter the Live Feed.}
1060 \item
1061 {The User is on the Live Feed for his/her class.}
1062 \item
1063 {The User shall identify an inappropriate card and flag the card.}
1064 \item
1065 {The User clicks the ``Flag as Inappropriate'' button on the flashcard
1066 that he/she wants to report}
1067 \item
1068 {The Client shall hide the card from the user}
1069 \item
1070 {The server shall create a FlashcardReport object}
1071 \end{enumerate}
1072 \end{description}
1073 {}
1074
1075 {}
1076
1077 \newpage
1078
1079 {}
1080
1081 \subsection{\texorpdfstring{{{[}F5{]} Filter
1082 Flashcards}}{{[}F5{]} Filter Flashcards}}
1083
1084 \begin{description}
1085 \item[Description]{The user is able to filter for flashcards by date}
1086
1087 {Desired Outcome:}{~The user shall see flashcards based on the filter
1088 options}
1089
1090 {User Goals:}{~The user can find what he/she is specifically looking
1091 for}
1092
1093 \item[Primary Actor]{~User (student)}
1094
1095 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
1096 Login, {[}A3{]} Add a Class, {[}F1{]} Push Flashcard, {[}F3{]} Pull
1097 Flashcard}
1098
1099 \item[Priority Level]{~~''Should''}
1100
1101 \item[Status]{Not}{~}{Implemented }
1102
1103 {Pre-conditions: }
1104
1105 \begin{itemize}
1106 \itemsep1pt\parskip0pt\parsep0pt
1107 \item
1108 {User has registered for the course }
1109 \item
1110 {Flashcards exist in the course}
1111 \end{itemize}
1112
1113 \item[Post-conditions]{~}
1114
1115 \begin{itemize}
1116 \itemsep1pt\parskip0pt\parsep0pt
1117 \item
1118 {User only sees specific flashcards}
1119 \end{itemize}
1120
1121 {Trigger:}{~User has selected advanced options from menu}
1122
1123 \item[Workflow]
1124
1125 \begin{enumerate}
1126 \itemsep1pt\parskip0pt\parsep0pt
1127 \item
1128 {The User chooses one of their classes.}
1129 \item
1130 {The User presses the class they want to view.}
1131 \item
1132 {The Client displays the Live Feed.}
1133 \item
1134 {The User is at the Live Feed.}
1135 \item
1136 {The User wants to filter the cards on the Live Feed.}
1137 \item
1138 {The User shall select what filter option they want from a drop down
1139 menu.}
1140 \item
1141 {The Client shall display only relevant flashcards.}
1142 \end{enumerate}
1143 \end{description}
1144 {}
1145
1146 \newpage
1147
1148 {}
1149
1150 \subsection{\texorpdfstring{{{[}F6{]} Blank Out Words in
1151 Flashcard}}{{[}F6{]} Blank Out Words in Flashcard}}
1152
1153 \begin{description}
1154 \item[Description]{The User shall be able to blank out keywords in any
1155 flashcard in his deck. }
1156
1157 {Desired Outcome: }{The blanked out words in the flashcard notify the
1158 System that they are keywords. }
1159
1160 \item[User Goals]{The User shall mark some words as keywords so the System
1161 may later quiz theirself by blanking out the keywords and having the
1162 User guess what they are.}
1163
1164 {Primary Actor: }{User (student)}
1165
1166 {Dependency Use Cases: }{{[}A1{]} User Registration, {[}A2{]} User
1167 Login, {[}A3{]} Add a Class, {[}F1{]} Push Flashcard}
1168
1169 {Priority Level: }{``Must''}
1170
1171 \item[Status]{Not implemented.}
1172
1173 {Pre-conditions: }
1174
1175 \begin{itemize}
1176 \itemsep1pt\parskip0pt\parsep0pt
1177 \item
1178 {The User has the flashcard he wishes to blank out words from in his
1179 deck.}
1180 \item
1181 {The User shall (be on the class page and) view deck}
1182 \end{itemize}
1183
1184 {Post-conditions: }
1185
1186 \begin{itemize}
1187 \itemsep1pt\parskip0pt\parsep0pt
1188 \item
1189 {The blanked out words in the flashcard are marked as keywords.}
1190 \item
1191 {The System shall blank out the keywords and let the User guess what
1192 they are when it presents the flashcard to the User for reviewing.}
1193 \end{itemize}
1194
1195 \item[Trigger]{The User clicks on a flashcard.}
1196
1197 {Workflow: }
1198
1199 \begin{enumerate}
1200 \itemsep1pt\parskip0pt\parsep0pt
1201 \item
1202 {The Client shall a show deck to user}
1203 \item
1204 {The User shall click on the flashcard in his deck that he wants to
1205 blank out words from}
1206 \item
1207 {The client shall bring user to edit flashcard page/popup}
1208 \item
1209 {The User shall click on the words that he wishes to blank out}
1210 \item
1211 {The client shall specify a character range as blank}
1212 \item
1213 {The server shall mark those words by updating the Flashcard Mask for
1214 that flashcard. }
1215 \item
1216 {The User shall click on `Save' or the equivalent button to save the
1217 changes}
1218 \item
1219 {The server will save the blanked out words as keywords to the
1220 Flashcard Mask to review}
1221 \item
1222 {The client shall cover the keywords with whitespace to hide them from
1223 the User}
1224 \end{enumerate}
1225
1226 {Alternative Workflows:}
1227
1228 \begin{enumerate}
1229 \itemsep1pt\parskip0pt\parsep0pt
1230 \item
1231 {The User shall (be on the class page and) click ``Make New
1232 Flashcard''}
1233 \item
1234 {The client shall present user with a new flashcard to fill in}
1235 \item
1236 {The User shall fill in the information}
1237 \item
1238 {The client shall ask if the user wants to specify blanks}
1239 \item
1240 {The System will save the blanked out words as keywords to the
1241 Flashcard Mask to review}
1242 \item
1243 {The client shall cover the keywords with whitespace to hide them from
1244 the User}
1245 \end{enumerate}
1246 \end{description}
1247 {}
1248
1249 \newpage
1250
1251 {}
1252
1253 \subsection{\texorpdfstring{{{[}F7{]} Fix
1254 Flashcard}}{{[}F7{]} Fix Flashcard}}
1255
1256 \begin{description}
1257 \item[Description]{The User shall be able to alter a flashcard he/she made
1258 originally and not have to make a new copy of it.}
1259
1260 {Desired Outcome:}{~The User shall alter one flashcard and that
1261 alteration will be shown to all users of that flashcard}
1262
1263 \item[User Goals]{The user shall make the flashcard say something different
1264 than it did originally.}
1265
1266 \item[Primary Actor]{~User (student) }
1267
1268 \item[Dependency Use Cases]{~{[}A1{]} User Registration, {[}A2{]} User
1269 Login, {[}A3{]} Add a Class, {[}F1{]} Push Flashcard}
1270
1271 \item[Priority Level]{Must}
1272
1273 \item[Status]{Not Implemented}
1274
1275 {Pre-conditions: }
1276
1277 \begin{itemize}
1278 \itemsep1pt\parskip0pt\parsep0pt
1279 \item
1280 {User has created the flashcard}
1281 \end{itemize}
1282
1283 \item[Post-conditions]{~}
1284
1285 \begin{itemize}
1286 \itemsep1pt\parskip0pt\parsep0pt
1287 \item
1288 {The user shall see their alteration for that flashcard}
1289 \item
1290 {Other users will be notified of the alteration}
1291 \end{itemize}
1292
1293 {Trigger:}{~User (creator of original card) has clicked on the button
1294 ``Edit''}
1295
1296 {Workflow: }
1297
1298 \begin{enumerate}
1299 \itemsep1pt\parskip0pt\parsep0pt
1300 \item
1301 {User shall select one of the Flashcards they authored.}
1302 \item
1303 {User shall select ``Edit'' button on the flashcard.}
1304 \item
1305 {Client shall display an ``Edit Flashcard'' view.}
1306 \item
1307 {The Flashcard will display editable fields/areas.}
1308 \item
1309 {The User shall input any changes to the Flashcard.}
1310 \item
1311 {The User shall select the ``Done Editing'' button.}
1312 \item
1313 {The Client shall close the ``Edit Flashcard'' view.}
1314 \item
1315 {The server shall update the Flashcard's content.}
1316 \item
1317 {Client shall notify users with the Flashcard that the Flashcard has
1318 been edited, allowing the other users to keep or to discard the
1319 changes.}
1320 \end{enumerate}
1321 \end{description}
1322 {}
1323
1324 {}
1325
1326 {}
1327
1328 \newpage
1329
1330 {}
1331
1332 \subsection{\texorpdfstring{{{[}F8{]} Hide cards from
1333 feed}}{{[}F8{]} Hide cards from feed}}
1334
1335 \begin{description}
1336 \item[Description]{The user shall be able to hide cards from feed}
1337
1338 {Desired Outcome:}{~The card is no longer visible to the user}
1339
1340 \item[User Goals]{The card has been looked at and should be hidden to
1341 reduce screen clutter}
1342
1343 {Primary Actor: }{User (Student)}
1344
1345 \item[Dependency Use Cases]{~}{~}{{[}A1{]} User Registration, {[}A2{]} User
1346 Login, {[}A3{]} Add a Class, {[}F1{]} Push Flashcard}
1347
1348 \item[Priority Level]{~``Should''}
1349
1350 {Status:}{~Not implemented}
1351
1352 \item[Pre-conditions]{~Flashcard is created, flashcard is viewable by user}
1353
1354 \item[Post-conditions]{~Flashcard is not viewable by user}
1355
1356 {Trigger:}{~Card is flagged; Card is noted to be hidden}
1357
1358 {Workflow: }
1359
1360 \begin{enumerate}
1361 \itemsep1pt\parskip0pt\parsep0pt
1362 \item
1363 {The User chooses a class from the dashboard.}
1364 \item
1365 {The Client shows the Live Feed for the selected class.}
1366 \item
1367 {The User sees a card they want to hide from the Live Feed.}
1368 \item
1369 {The User shall press a ``Hide Flashcard'' button on the card to be
1370 hidden.}
1371 \item
1372 {The Client shall hide the card of interest from the Live Feed, for
1373 only that User.}
1374 \end{enumerate}
1375
1376 \end{description}
1377
1378 \newpage
1379
1380 {}
1381
1382 \subsection{\texorpdfstring{{{[}F9{]} View a
1383 Feed}}{{[}F9{]} View a Feed}}
1384
1385 \begin{description}
1386 \item[Description]{The user shall be able to view Live Feeds for different
1387 classes}
1388
1389 {Desired Outcome:}{~The system shall only show the user Live Feeds for
1390 specific classes. }
1391
1392 \item[User Goals]{The user will see only one Live Feed at a time. }
1393
1394 \item[Dependency Use Cases]{~}{~}{{[}A1{]} User Registration, {[}A2{]} User
1395 Login, {[}A3{]} Add a Class}
1396
1397 \item[Priority Level]{~``Must''}
1398
1399 {Status:}{~Not implemented}
1400
1401 \item[Pre-conditions]{~User has added a class}
1402
1403 \item[Post-conditions]{~User shall see the Live Feed for that class}
1404
1405 {Trigger:}{~User shall select a class}
1406
1407 {Workflow: }
1408
1409 \begin{enumerate}
1410 \itemsep1pt\parskip0pt\parsep0pt
1411 \item
1412 {The User logs into their account.}
1413 \item
1414 {The System verifies the User's credentials and saves their session.}
1415 \item
1416 {The User is at their dashboard.}
1417 \item
1418 {The Client shows the User's dashboard.}
1419 \item
1420 {The User selects a class from their dashboard.}
1421 \item
1422 {The Client displays the Live Feed for the class.}
1423 \end{enumerate}
1424
1425 \end{description}
1426 \newpage
1427
1428 {}
1429
1430 \subsection{\texorpdfstring{{{[}-D2-{]} Making a
1431 deck}}{{[}-D2-{]} Making a deck}}
1432
1433 \begin{description}
1434 \item[Description]{Upon selecting the right course, the student has the
1435 power to make a deck by either selecting existing flashcard or adding a
1436 new flashcard.}
1437
1438 {Desired Outcome:}{~The user can keep track of cards that s/he wants.}
1439
1440 \item[User Goals]{The user has a personal deck ready for review later.}
1441
1442 \item[Primary Actor]{~User (student)}
1443
1444 \item[Dependency Use Cases]{~Add a class {[}A3{]}, Add Flashcards to Deck
1445 {[}F1{]}, Make a Flashcard {[}F3{]}}
1446
1447 \item[Priority Level]{~``Must''}
1448
1449 \item[Status]{In Progress}
1450
1451 \item[Pre-conditions]
1452
1453 \begin{itemize}
1454 \itemsep1pt\parskip0pt\parsep0pt
1455 \item
1456 {The user has an account with the application. }
1457 \item
1458 {The user has been added to the desired class.}
1459 \end{itemize}
1460
1461 \item[Post-conditions]
1462
1463 \begin{itemize}
1464 \itemsep1pt\parskip0pt\parsep0pt
1465 \item
1466 {Desired cards are added to user's deck to the specific class }
1467 \item
1468 {User's deck is added to the database.}
1469 \end{itemize}
1470
1471 {Trigger:}{~User has selected a card from the pool. ~User submitted a
1472 new flashcard after ``Make New Flashcard''.}
1473
1474 \item[Workflow]
1475
1476 \begin{enumerate}
1477 \itemsep1pt\parskip0pt\parsep0pt
1478 \item
1479 {User is at their dashboard.}
1480 \item
1481 {User selects the class of interest that they had no activity in yet.}
1482 \item
1483 {Client displays the Live Feed for the class.}
1484 \item
1485 {User presses ``Pull Flashcard'' button on a Flashcard that they want
1486 in their Deck.}
1487 \item
1488 {The server creates a Deck for the User for the Class of interest.}
1489 \item
1490 {The server adds the Flashcard to the User's Deck.}
1491 \item
1492 {The Client makes the Flashcard disappear from the Live Feed.}
1493 \item
1494 {The Client displays the Flashcard in the User's Deck in the sidebar.}
1495 \end{enumerate}
1496
1497 {Alternate Workflow:}
1498
1499 \begin{enumerate}
1500 \itemsep1pt\parskip0pt\parsep0pt
1501 \item
1502 {User is at their dashboard.}
1503 \item
1504 {User selects the class of interest that they had no activity in yet.}
1505 \item
1506 {Client displays the Live Feed for the class.}
1507 \item
1508 {The User adds a Flashcard into the Class.}
1509 \item
1510 {The server creates a Deck for the User for the Class of interest.}
1511 \item
1512 {The server adds the new Flashcard to the User's Deck.}
1513 \item
1514 {The Client makes the Flashcard disappear from the Live Feed.}
1515 \item
1516 {The Client displays the Flashcard in the User's Deck in the sidebar.}
1517 \end{enumerate}
1518 \end{description}
1519 \newpage
1520
1521 {}
1522
1523 \subsection{\texorpdfstring{{{[}D1{]} Remove a card from a
1524 deck}}{{[}D1{]} Remove a card from a deck}}
1525
1526 \begin{description}
1527 \item[Description]{The user can remove flashcards from their deck.}
1528
1529 {Desired Outcome:}{~The user will not be notified about that card. }
1530
1531 \item[User Goals]{To only review cards that the user wants to review. }
1532
1533 \item[Primary Actor]{~User (student)}
1534
1535 \item[Dependency Use Cases]{~Add a class {[}A3{]}, Add Flashcards to Deck
1536 {[}F1{]}, Make a Flashcard {[}F3{]}}
1537
1538 \item[Priority Level]{~``Must''}
1539
1540 \item[Status]{Unimplemented}
1541
1542 \item[Pre-conditions]
1543
1544 \begin{itemize}
1545 \itemsep1pt\parskip0pt\parsep0pt
1546 \item
1547 {The User has an account with the application}
1548 \item
1549 {The User is logged in}
1550 \end{itemize}
1551
1552 \item[Post-conditions]
1553
1554 \begin{itemize}
1555 \itemsep1pt\parskip0pt\parsep0pt
1556 \item
1557 {Desired cards are hidden to the user.}
1558 \end{itemize}
1559
1560 {Trigger:}{~User has selected a card to be hidden.}
1561
1562 \item[Workflow]
1563
1564 \begin{enumerate}
1565 \itemsep1pt\parskip0pt\parsep0pt
1566 \item
1567 {The Client shows the user the dashboard.}
1568 \item
1569 {The User shall select the appropriate class.}
1570 \item
1571 {The System checks if the class is in session.}
1572 \item
1573 {The User shall select deck view.}
1574 \item
1575 {The Client shall route the user to the deck view.}
1576 \item
1577 {The User clicks a flashcard's remove button.}
1578 \item
1579 {The Client shall send a DELETE request to the server}{~}{at
1580 /api/flashcard/\textless{}flashcard ID\textgreater{}/remove}
PNGS = built/use_cases_diagram.png built/schema_diagram.png built/schema_graph.png 1 1 PNGS = built/use_cases_diagram.png built/schema_diagram.png built/schema_graph.png
2 PDFS = built/DesignUseCases.pdf
2 3
all: built/ $(PNGS) 3 4 all: built/ $(PNGS) $(PDFS)
4 5
built/: 5 6 built/:
mkdir -p built 6 7 mkdir -p built
7 8
built/schema_diagram.png: 8 9 built/schema_diagram.png:
sqlt-diagram --color -c 3 -t png -o built/schema_diagram.png --gutter 60 --from PostgreSQL db_schema.sql --title "Flashy" 9 10 sqlt-diagram --color -c 3 -t png -o built/schema_diagram.png --gutter 60 --from PostgreSQL db_schema.sql --title "Flashy"
10 11
built/schema_graph.png: 11 12 built/schema_graph.png:
sqlt-graph -o built/schema_graph.png --from PostgreSQL db_schema.sql 12 13 sqlt-graph -o built/schema_graph.png --from PostgreSQL db_schema.sql
13 14
built/%.png: %.dot 14 15 built/%.png: %.dot
dot -Tpng -o $@ $< 15 16 dot -Tpng -o $@ $<
17
18 built/%.pdf: %.tex
19 cd built/; pdflatex ../$<