Commit 9bdef2907fdc3f37fc2f21885d045f520680b0e2
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} |
Makefile
View file @
9bdef29
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 ../$< |