Repository navigation
EAP
PingPong Q&A helps communities share and build knowledge in a simple, organized way. By making it easy to ask questions, find answers, and recognize contributions, it encourages people to engage and learn together. With smart search, badges, and an interface that works on any device, the platform makes knowledge easier to discover, trust, and keep for the long term.
This artifact specifies the web architecture for the PingPong Q&A platform. It defines the catalog of resources (pages and API endpoints), their required permissions, and their request/response formats. This specification adheres to the OpenAPI standard (using YAML) to provide a clear blueprint for the vertical prototype.
This section provides a high-level overview of the application's architecture, organized into functional modules that group related web resources.
| Module Name | Description |
|---|---|
| M01: Authentication and User Profile | Web resources associated with user authentication, account management, and personal profile operations. Includes registration, login and session management, profile view and edit, viewing own questions and answers, and password recovery initiation. |
| M02: Questions and Answers | Web resources associated with creating, viewing, and managing questions and answers. Includes posting questions and answers, editing and deleting own questions and answers and editing tags on own questions. |
| M03: Search and Discovery | Web resources associated with browsing and filtering content. Includes exact match and full-text search across questions and answers, viewing top or trending questions, and accessing personal feeds of relevant content. |
| M04: Moderation and Administration | Web resources associated with moderation and administrative operations. Includes reviewing and managing reported content, deleting inappropriate content, managing tags (create/edit/delete/synonyms), managing user accounts and roles, and enforcing anonymization and account deletion. |
| M05: Static Pages and General Information | Web resources associated with non-interactive informational content. Includes static pages such as About, Contact, and other informational sections, as well as a simple landing or home page with public highlights. |
This section defines the permission codes used throughout the API, specifying the access rights required for each type of user, from public visitors to administrators.
| Code | Name | Description |
|---|---|---|
| PUB | Public | Users without authentication; can browse public content and static pages. |
| USR | User | Authenticated users with general access to platform features such as viewing, replying, searching and asking questions. |
| OWN | Owner | Authenticated users acting on resources they created or own (e.g., their own profile, questions, answers, or comments). |
| MOD | Moderator | Users with moderation privileges; can review reports, remove inappropriate content, and enforce rules. |
| ADM | Administrator | System administrators with full control over users, tags, and platform configuration. |
The following YAML document provides the complete and formal OpenAPI specification for the web resources, pages, and API endpoints included in the vertical prototype.
openapi: 3.0.0
info:
version: '1.0'
title: 'PingPong Q&A Web API'
description: 'Web Resources Specification (A7) for the PingPong Q&A'
servers:
- url: http://lbaw.fe.up.pt
description: Production server
tags:
- name: 'M01: Authentication and User Profile'
- name: 'M02: Questions and Answers'
- name: 'M03: Search and Discovery'
- name: 'M04: Moderation and Administration'
- name: 'M05: Static Pages and General Information'
paths:
/register:
get:
operationId: R101
summary: 'R101: Registration Form'
description: 'Display the sign-up form. Access: PUB'
tags:
- 'M01: Authentication and User Profile'
responses:
'200':
description: 'OK. Show registration UI.'
post:
operationId: R102
summary: 'R102: Registration Action'
description: 'Process the sign-up submission and create a member account. Access: PUB'
tags:
- 'M01: Authentication and User Profile'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
username:
type: string
email:
type: string
format: email
password:
type: string
format: password
displayName:
type: string
required:
- username
- email
- password
responses:
'302':
description: 'Redirect after creating the account.'
headers:
Location:
schema:
type: string
examples:
success:
description: 'Account created; redirect to personal feed.'
value: '/me/feed'
failure:
description: 'Validation failed; redirect back to registration.'
value: '/register'
/login:
get:
operationId: R103
summary: 'R103: Login Form'
description: 'Display the login form. Access: PUB'
tags:
- 'M01: Authentication and User Profile'
responses:
'200':
description: 'OK. Show login UI.'
post:
operationId: R104
summary: 'R104: Login Action'
description: 'Authenticate member credentials and start a session. Access: PUB'
tags:
- 'M01: Authentication and User Profile'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
username:
type: string
password:
type: string
format: password
rememberMe:
type: boolean
required:
- username
- password
responses:
'302':
description: 'Redirect after login attempt.'
headers:
Location:
schema:
type: string
examples:
success:
description: 'Authentication succeeded; redirect to personal feed.'
value: '/me/feed'
failure:
description: 'Authentication failed; redirect back to login.'
value: '/login'
/logout:
post:
operationId: R105
summary: 'R105: Logout Action'
description: 'Invalidate the current session. Access: USR'
tags:
- 'M01: Authentication and User Profile'
responses:
'302':
description: 'Redirect after logout.'
headers:
Location:
schema:
type: string
example: '/'
/me/profile:
get:
operationId: R201
summary: 'R201: View Own Profile'
description: 'Display the authenticated member profile information. Access: OWN'
tags:
- 'M01: Authentication and User Profile'
responses:
'200':
description: 'OK. Show profile UI.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileDetail'
put:
operationId: R202
summary: 'R202: Update Own Profile'
description: 'Update display name, bio, avatar and preferences. Access: OWN'
tags:
- 'M01: Authentication and User Profile'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
displayName:
type: string
bio:
type: string
avatar:
type: string
format: binary
preferences:
type: object
additionalProperties: true
responses:
'200':
description: 'Profile updated. Return the fresh data.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileDetail'
/me/profile/edit:
get:
operationId: R208
summary: 'R208: Edit Profile Form'
description: 'Display profile edit form. Access: OWN'
tags:
- 'M01: Authentication and User Profile'
responses:
'200':
description: 'OK. Show profile edit UI.'
/users/{id}:
get:
operationId: R209
summary: 'R209: View User Profile'
description: 'Display another user profile information. Access: USR'
tags:
- 'M01: Authentication and User Profile'
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
'200':
description: 'OK. Show user profile UI.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileDetail'
/me/feed:
get:
operationId: R203
summary: 'R203: Personal Feed'
description: 'List personalized feed entries for followed tags and questions. Access: USR'
tags:
- 'M03: Search and Discovery'
parameters:
- in: query
name: page
schema:
type: integer
minimum: 1
required: false
- in: query
name: pageSize
schema:
type: integer
default: 20
required: false
responses:
'200':
description: 'OK. Return paginated feed entries.'
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/FeedItem'
pagination:
$ref: '#/components/schemas/PaginationMetadata'
/search:
get:
operationId: R206
summary: 'R206: Search Page'
description: 'Display search interface. Access: USR'
tags:
- 'M03: Search and Discovery'
responses:
'200':
description: 'OK. Show search UI.'
/api/search:
get:
operationId: R207
summary: 'R207: Search API'
description: 'Search API endpoint for questions. Access: USR'
tags:
- 'M03: Search and Discovery'
parameters:
- in: query
name: q
schema:
type: string
description: 'Search query.'
responses:
'200':
description: 'OK. Return search results.'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/QuestionSummary'
/me/questions:
get:
operationId: R204
summary: 'R204: List Own Questions'
description: 'Retrieve a paginated list of questions authored by the member. Access: OWN'
tags:
- 'M01: Authentication and User Profile'
parameters:
- in: query
name: page
schema:
type: integer
minimum: 1
- in: query
name: status
schema:
type: string
description: 'Optional status filter (open, answered, closed).'
responses:
'200':
description: 'OK. Return question summaries.'
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/QuestionSummary'
pagination:
$ref: '#/components/schemas/PaginationMetadata'
/me/answers:
get:
operationId: R205
summary: 'R205: List Own Answers'
description: 'Retrieve a paginated list of answers authored by the member. Access: OWN'
tags:
- 'M01: Authentication and User Profile'
parameters:
- in: query
name: page
schema:
type: integer
minimum: 1
responses:
'200':
description: 'OK. Return answer summaries.'
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/AnswerSummary'
pagination:
$ref: '#/components/schemas/PaginationMetadata'
/questions:
get:
operationId: R301
summary: 'R301: Browse & Search Questions'
description: 'Browse public questions with support for pagination and exact/full-text search. Access: PUB'
tags:
- 'M03: Search and Discovery'
parameters:
- in: query
name: q
schema:
type: string
description: 'Search phrase applied to titles and content.'
- in: query
name: match
schema:
type: string
enum:
- exact
- full
description: 'Select between exact-match (US11) or full-text (US12) search.'
- in: query
name: page
schema:
type: integer
minimum: 1
description: 'Pagination page number.'
- in: query
name: pageSize
schema:
type: integer
default: 20
description: 'Number of results per page.'
responses:
'200':
description: 'OK. Return question results.'
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/QuestionSummary'
pagination:
$ref: '#/components/schemas/PaginationMetadata'
post:
operationId: R302
summary: 'R302: Create Question'
description: 'Submit a new question with title, body and tags. Access: USR'
tags:
- 'M02: Questions and Answers'
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
title:
type: string
body:
type: string
tags:
type: array
items:
type: string
attachments:
type: array
items:
type: string
format: binary
required:
- title
- body
responses:
'201':
description: 'Question created.'
headers:
Location:
schema:
type: string
example: '/questions/42'
/top:
get:
operationId: R303
summary: 'R303: Top Questions'
description: 'Retrieve highlighted questions sorted by score and acceptance. Access: PUB'
tags:
- 'M03: Search and Discovery'
parameters:
- in: query
name: limit
schema:
type: integer
default: 10
description: 'Maximum number of highlighted questions.'
responses:
'200':
description: 'OK. Return highlighted questions.'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/QuestionSummary'
/questions/{questionId}:
put:
operationId: R304
summary: 'R304: Update Question'
description: 'Edit the title and body of an owned question. Access: OWN, MOD'
tags:
- 'M02: Questions and Answers'
parameters:
- in: path
name: questionId
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
body:
type: string
required:
- title
- body
responses:
'200':
description: 'Question updated.'
content:
application/json:
schema:
$ref: '#/components/schemas/QuestionDetail'
delete:
operationId: R305
summary: 'R305: Delete Question'
description: 'Remove an owned question (with anonymization rules applied). Access: OWN, MOD'
tags:
- 'M02: Questions and Answers'
parameters:
- in: path
name: questionId
schema:
type: integer
required: true
responses:
'204':
description: 'Question removed.'
/questions/{questionId}/tags:
put:
operationId: R306
summary: 'R306: Update Question Tags'
description: 'Replace the tag set of an owned question. Access: OWN, MOD'
tags:
- 'M02: Questions and Answers'
parameters:
- in: path
name: questionId
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
tags:
type: array
items:
type: string
required:
- tags
responses:
'200':
description: 'Tags updated.'
content:
application/json:
schema:
$ref: '#/components/schemas/QuestionDetail'
/questions/{questionId}/answers:
post:
operationId: R401
summary: 'R401: Post Answer'
description: 'Submit an answer to a question. Access: USR'
tags:
- 'M02: Questions and Answers'
parameters:
- in: path
name: questionId
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
body:
type: string
required:
- body
responses:
'201':
description: 'Answer created.'
headers:
Location:
schema:
type: string
example: '/answers/128'
/answers/{answerId}:
put:
operationId: R402
summary: 'R402: Update Answer'
description: 'Edit an owned answer. Access: OWN, MOD'
tags:
- 'M02: Questions and Answers'
parameters:
- in: path
name: answerId
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
body:
type: string
required:
- body
responses:
'200':
description: 'Answer updated.'
content:
application/json:
schema:
$ref: '#/components/schemas/AnswerDetail'
delete:
operationId: R403
summary: 'R403: Delete Answer'
description: 'Remove an owned answer. Access: OWN, MOD'
tags:
- 'M02: Questions and Answers'
parameters:
- in: path
name: answerId
schema:
type: integer
required: true
responses:
'204':
description: 'Answer removed.'
/moderator/reports:
get:
operationId: R501
summary: 'R501: List Content Reports'
description: 'Retrieve reported content with context for triage. Access: MOD'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: query
name: status
schema:
type: string
enum:
- pending
- in_review
- resolved
required: false
responses:
'200':
description: 'OK. Return reported items.'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ReportEntry'
/moderator/cases/{type}/{id}:
put:
operationId: R502
summary: 'R502: Update Case Status'
description: 'Update the status or actions taken for a moderation case. Access: MOD'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: type
schema:
type: string
required: true
description: 'The type of content (question, answer, comment).'
- in: path
name: id
schema:
type: integer
required: true
description: 'The ID of the content.'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
status:
type: string
enum:
- pending
- in_review
- resolved
resolutionNotes:
type: string
responses:
'200':
description: 'Case updated.'
content:
application/json:
schema:
$ref: '#/components/schemas/ReportEntry'
/admin:
get:
operationId: R600
summary: 'R600: Admin Dashboard'
description: 'Display admin dashboard. Access: ADM'
tags:
- 'M04: Moderation and Administration'
responses:
'200':
description: 'OK. Show admin dashboard.'
/admin/tags:
get:
operationId: R601
summary: 'R601: List Tags'
description: 'Retrieve available tags for management. Access: ADM'
tags:
- 'M04: Moderation and Administration'
responses:
'200':
description: 'OK. Return tags.'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/TagDetail'
post:
operationId: R602
summary: 'R602: Create Tag'
description: 'Create a new tag or synonym. Access: ADM'
tags:
- 'M04: Moderation and Administration'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
synonyms:
type: array
items:
type: string
required:
- name
responses:
'201':
description: 'Tag created.'
headers:
Location:
schema:
type: string
example: '/admin/tags/12'
/admin/tags/{tagId}:
put:
operationId: R603
summary: 'R603: Update Tag'
description: 'Edit an existing tag or its synonyms. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: tagId
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
synonyms:
type: array
items:
type: string
responses:
'200':
description: 'Tag updated.'
content:
application/json:
schema:
$ref: '#/components/schemas/TagDetail'
delete:
operationId: R604
summary: 'R604: Delete Tag'
description: 'Remove a tag from the taxonomy. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: tagId
schema:
type: integer
required: true
responses:
'204':
description: 'Tag deleted.'
/admin/tags/{tag}/merge:
get:
operationId: R604a
summary: 'R604a: Show Tag Merge Form'
description: 'Display form to merge tags. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: tag
schema:
type: integer
required: true
responses:
'200':
description: 'OK. Show merge form.'
post:
operationId: R604b
summary: 'R604b: Merge Tags'
description: 'Merge one tag into another. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: tag
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
targetTagId:
type: integer
required:
- targetTagId
responses:
'200':
description: 'Tags merged.'
/admin/tags/{tag}/synonyms:
post:
operationId: R604c
summary: 'R604c: Add Tag Synonym'
description: 'Add a synonym to a tag. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: tag
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
synonym:
type: string
required:
- synonym
responses:
'200':
description: 'Synonym added.'
delete:
operationId: R604d
summary: 'R604d: Remove Tag Synonym'
description: 'Remove a synonym from a tag. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: tag
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
synonym:
type: string
required:
- synonym
responses:
'200':
description: 'Synonym removed.'
/admin/users:
get:
operationId: R605
summary: 'R605: Search Users'
description: 'Search, filter and list user accounts. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: query
name: query
schema:
type: string
description: 'Search by username or email.'
- in: query
name: role
schema:
type: string
enum:
- member
- moderator
- admin
required: false
responses:
'200':
description: 'OK. Return user accounts.'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/UserAdminSummary'
post:
operationId: R606
summary: 'R606: Create User Account'
description: 'Create a new user account or elevate roles. Access: ADM'
tags:
- 'M04: Moderation and Administration'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
email:
type: string
format: email
role:
type: string
enum:
- member
- moderator
- admin
temporaryPassword:
type: string
required:
- username
- email
responses:
'201':
description: 'User account created.'
headers:
Location:
schema:
type: string
example: '/admin/users/73'
/admin/users/{userId}:
get:
operationId: R607
summary: 'R607: View User Account'
description: 'Fetch account details and roles. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: userId
schema:
type: integer
required: true
responses:
'200':
description: 'OK. Return account detail.'
content:
application/json:
schema:
$ref: '#/components/schemas/UserAdminDetail'
put:
operationId: R608
summary: 'R608: Update User Account'
description: 'Edit account fields and roles. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: userId
schema:
type: integer
required: true
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserAdminUpdate'
responses:
'200':
description: 'Account updated.'
content:
application/json:
schema:
$ref: '#/components/schemas/UserAdminDetail'
delete:
operationId: R609
summary: 'R609: Delete User Account'
description: 'Delete a user account according to policy. This action automatically anonymizes all user contributions (questions, answers, comments) as per BR.011. Access: ADM'
tags:
- 'M04: Moderation and Administration'
parameters:
- in: path
name: userId
schema:
type: integer
required: true
responses:
'204':
description: 'User deleted.'
components:
schemas:
PaginationMetadata:
type: object
properties:
page:
type: integer
pageSize:
type: integer
totalItems:
type: integer
totalPages:
type: integer
ProfileDetail:
type: object
properties:
id:
type: integer
username:
type: string
displayName:
type: string
bio:
type: string
avatarUrl:
type: string
format: uri
preferences:
type: object
additionalProperties: true
FeedItem:
type: object
properties:
id:
type: integer
type:
type: string
enum:
- question
- answer
question:
$ref: '#/components/schemas/QuestionSummary'
answer:
$ref: '#/components/schemas/AnswerSummary'
createdAt:
type: string
format: date-time
QuestionSummary:
type: object
properties:
id:
type: integer
title:
type: string
excerpt:
type: string
score:
type: integer
answersCount:
type: integer
tags:
type: array
items:
type: string
createdAt:
type: string
format: date-time
QuestionDetail:
allOf:
- $ref: '#/components/schemas/QuestionSummary'
- type: object
properties:
body:
type: string
AnswerSummary:
type: object
properties:
id:
type: integer
questionId:
type: integer
excerpt:
type: string
score:
type: integer
createdAt:
type: string
format: date-time
AnswerDetail:
allOf:
- $ref: '#/components/schemas/AnswerSummary'
- type: object
properties:
body:
type: string
ReportEntry:
type: object
properties:
id:
type: integer
contentType:
type: string
enum:
- question
- answer
- comment
contentId:
type: integer
reporter:
type: string
reason:
type: string
status:
type: string
enum:
- pending
- in_review
- resolved
submittedAt:
type: string
format: date-time
resolutionNotes:
type: string
TagDetail:
type: object
properties:
id:
type: integer
name:
type: string
synonyms:
type: array
items:
type: string
UserAdminSummary:
type: object
properties:
id:
type: integer
username:
type: string
email:
type: string
role:
type: string
UserAdminDetail:
allOf:
- $ref: '#/components/schemas/UserAdminSummary'
- type: object
properties:
displayName:
type: string
reputation:
type: integer
badges:
type: array
items:
type: string
UserAdminUpdate:
type: object
properties:
email:
type: string
format: email
role:
type: string
enum:
- member
- moderator
- admin
temporaryPassword:
type: string
notes:
type: stringThe Vertical Prototype delivers a fully functional slice of the application's core, validating the architectural stack from the database to the user interface by implementing high-priority user stories. Its primary goal is to prove the technical feasibility of critical features and establish a stable foundation for subsequent development phases.
The following table lists the user stories completed in this prototype, including their priority and the developer responsible for their implementation.
| User Story reference | Name | Priority | Responsible | Description |
|---|---|---|---|---|
| US01 | Sign-up / Registration | Very High | Simão Barbosa | As a Visitor, I want to register an account, so that I can become an authenticated member and contribute to the community. |
| US02 | Sign-in / Login | Very High | Simão Barbosa | As a Visitor, I want to log in, so that I can access member-only features. |
| US11 | Exact Match Search | High | Raul Oliveira | As a User, I want to perform an exact-match search over questions and answers, so that I can find specific phrases or precise content. |
| US12 | Full-text Search | High | Alexandre Ferreira | As a User, I want to perform full-text search across questions and answers, so that I can find relevant discussions using natural language queries. |
| US13 | View Top Questions (Home Highlights) | Medium | Raul Oliveira | As a User, I want to view the top (highest voted/accepted) questions on the homepage, so that I can quickly find high-quality content. |
| US14 | Browse Questions (pagination/list) | High | Dinis Lima | As a User, I want to browse questions in a paginated/list view, so that I can explore topics without needing to search. |
| US21 | View Personal Feed (followed tags/questions) | High | Dinis Lima | As a Member, I want to view a personal feed of questions and answers based on my followed tags and follows, so that I can see relevant, personalized content. |
| US22 | Post Question | Very High | Simão Barbosa | As a Member, I want to post a new question (title, body, tags, optional attachments), so that I can ask the community for help or share knowledge. |
| US23 | Post Answer | Very High | Raul Oliveira | As a Member, I want to post answers to questions, so that I can contribute solutions and be recognized by the community. |
| US24 | Edit Own Profile (view & edit) | High | Alexandre Ferreira | As a Member, I want to view and edit my profile (display name, bio, picture, preferences), so that my public presence is accurate and helpful. |
| US25 | Login/Logout (session management) | High | Simão Barbosa | As a Member, I want to log out and have session management (remember me), so that my account is secure and accessible when needed. |
| US26 | View My Questions | Medium | Simão Barbosa | As a Member, I want a page listing my own questions (with status & metrics), so that I can manage and follow progress on my posts. |
| US27 | View My Answers | Medium | Raul Oliveira | As a Member, I want a page listing my own answers (with metrics), so that I can track my contributions and follow-up. |
| US31 | Edit Question (own) | High | Dinis Lima | As an Author, I want to edit my own question (title, body), so that I can clarify or correct information after posting. |
| US32 | Delete Question (own) | High | Simão Barbosa | As an Author, I want to delete my own question, so that I can remove content I no longer want public (subject to anonymization rules). |
| US33 | Edit Answer (own) | High | Raul Oliveira | As an Author, I want to edit my own answers, so that I can improve accuracy or fix mistakes. |
| US34 | Delete Answer (own) | High | Raul Oliveira | As an Author, I want to delete my own answer, so that I can remove outdated or incorrect contributions. |
| US35 | Edit Question Tags (own question) | High | Dinis Lima | As an Author, I want to edit the tags on my question, so that it is categorized correctly and reaches the right audience. |
| US41 | Review and Manage Content Reports | High | Simão Barbosa | As a Moderator, I want to view and triage reported content with context and history, so that I can decide on appropriate moderation actions. |
| US42 | Delete Content (questions/answers/comments) | High | Dinis Lima | As a Moderator, I want to delete or remove content that violates rules, so that the community remains safe and high-quality. |
| US51 | Manage Tags (create/edit/delete, synonyms) | Very High | Dinis Lima | As an Administrator, I want to manage tags (create, merge, delete, add synonyms), so that taxonomy is consistent and searchable. |
| US52 | Administer User Accounts (search/view/edit/create) | High | Alexandre Ferreira | As an Administrator, I want to search for, view, edit, and create user accounts (including promoting to moderator/admin), so that I can maintain community membership and roles. |
| US53 | Enforce Account Deletion Anonymization Rule | Very High | Alexandre Ferreira | As an Administrator, I want the system to anonymize contributions upon account deletion (retain content but remove PII), so that privacy rules are respected while preserving knowledge. |
| US54 | Delete User Account | High | Alexandre Ferreira | As an Administrator, I want to delete user accounts when necessary, so that I can remove inappropriate accounts in accordance with platform policies. |
This section maps the implemented functionality to specific web resources and their corresponding URLs, organized by module.
| Web Resource Reference | URL |
|---|---|
| R101: Registration Form | GET /register |
| R102: Registration Action | POST /register |
| R103: Login Form | GET /login |
| R104: Login Action | POST /login |
| R105: Logout Action | POST /logout |
| R201: View Own Profile | GET /me/profile |
| R202: Update Own Profile | PUT /me/profile |
| R205: List Own Answers | GET /me/answers |
| Web Resource Reference | URL |
|---|---|
| R302: Create Question | POST /questions |
| R305: Delete Question | DELETE /questions/{id} |
| R401: Post Answer | POST /questions/{id}/answers |
| R402: Update Answer | PUT /answers/{id} |
| R403: Delete Answer | DELETE /answers/{id} |
| Web Resource Reference | URL |
|---|---|
| R203: Personal Feed | GET /me/feed |
| R301: Browse & Search Questions | GET /search |
| R303: Top Questions | GET /top |
| R307: View Question Details | GET /questions/{id} |
| Web Resource Reference | URL |
|---|---|
| R600: Admin Dashboard | GET /admin |
| R605: Search Users | GET /admin/users |
| R606: Create User Account | POST /admin/users |
| R607: View User Account | GET /admin/users/{id} |
| R608: Update User Account | PUT /admin/users/{id} |
| R609: Delete User Account | DELETE /admin/users/{id} |
The prototype Docker image can be run with:
docker run -d --name lbaw2522 -p 8001:80 gitlab.up.pt:5050/lbaw/lbaw2526/lbaw2522The application will be available at http://localhost:8001.
To stop and remove the container:
docker stop lbaw2522
docker rm lbaw2522
| Role | Username | Password |
|---|---|---|
| Admin | admin_user |
1234 |
| Moderator | mod_user |
1234 |
| Member | raul |
1234 |
| Member | simao |
1234 |
| Member | alex |
1234 |
| Member | dinis |
1234 |
Changes made to the first submission:
- None
GROUP2522, 25/11/2025
- Alexandre Ferreira, up202307780@up.pt
- Dinis Lima, up202304083@up.pt
- Raul Oliveira, up202303446@up.pt (editor)
- Simão Barbosa, up202306609@up.pt