Compare View

switch
from
...
to
 
Commits (2)

Diff

Showing 1 changed file Inline Diff

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