My 5 Biggest Accomplishments
What I learned most
My Role: Deployment Engineer
1. My Frontend to Backend Development
The first time that I actually created something connecting to the backend was a simple API model called random facts. Without knowing much about the backend, I decided to step out of my comfort zone and explore new functions like CRUD. This led me to create another API called tasks, evolving from a regular API to a static database API.
Before:
After:
Task API Implementation:
from sqlite3 import IntegrityError
from __init__ import app, db
from model.user import User
class Task(db.Model):
"""
Task Model
Represents individual tasks stored in the database.
"""
__tablename__ = 'user_tasks'
id = db.Column(db.Integer, primary_key=True)
_task = db.Column(db.String(255), nullable=False, unique=True)
def __init__(self, task):
""" Constructor for Task """
self._task = task
def __repr__(self):
""" String representation of a Task object """
return f"Task(id={self._task})"
def create(self):
""" Adds the task to the database """
try:
db.session.add(self)
db.session.commit()
except Exception as e:
db.session.rollback()
raise e
def read(self):
""" Returns task data as a dictionary """
return {
"id": self.id,
"task": self._task,
}
def update(self):
""" Updates task data in the database """
try:
db.session.commit()
except Exception as e:
db.session.rollback()
raise e
def delete(self):
""" Deletes the task from the database """
try:
db.session.delete(self)
db.session.commit()
except Exception as e:
db.session.rollback()
raise e
@staticmethod
def restore(data):
""" Restores task data if needed """
for task_data in data:
task_data.pop('id', None)
task_name = task_data.get("task", None)
existing_task = Task.query.filter_by(_task=task_name).first()
if existing_task:
existing_task.update(task_data)
else:
new_task = Task(**task_data)
new_task.update(task_data)
new_task.create()
# Initialize Tasks
def inittasks():
"""
Creates the database and initializes sample task data.
"""
with app.app_context():
db.create_all()
tasks = [
Task(task='Review the key concepts from your last lesson.'),
Task(task='Read an article or a chapter from your textbook.'),
Task(task='Practice solving math problems for 30 minutes.'),
Task(task='Write a summary of what you learned today.')
]
for task in tasks:
try:
task.create()
print(f"Record created: {repr(task)}")
except IntegrityError:
db.session.remove()
print(f"Duplicate or error with task: {task._task}")
# **2. Learning Deployment, AWS, and Ubuntu**
## **Step 1: Changing the Ports**
Before deploying our application to AWS, we first had to modify the ports to ensure proper connectivity. This required updating all API fetch links, as everything is now hosted on our AWS server.
<img width="541" alt="Image" src="https://github.com/user-attachments/assets/db3b1f2f-3ce6-4d99-bcf5-1f601262d07d" />
### **Changes Made:**
1. Updated the ports to align with our AWS deployment.
2. Modified all API fetch links to point to our AWS server.
3. Ensured all configurations matched the new deployment environment.
---
## **Step 2: Deploying on Ubuntu**
Once the ports were set, the next step was to deploy our backend on an **Ubuntu server**.
<img width="700" alt="Image" src="https://github.com/user-attachments/assets/5944ab9e-a692-4b04-a27f-6b567b22ccfa" />
### **Deployment Process:**
1. **Build the Docker containers**
Run the following command to build the backend site:
```bash
docker-compose build
docker-compose up -d
docker ps
Step 3: Ensuring Server Security
Now that our server is up and running, we need to verify its security to prevent vulnerabilities and unauthorized access.
Security Check Process
- Access the backend URL
- Open a web browser and navigate to the backend endpoint.
- Verify HTTPS and SSL Certification
- Ensure the site has a valid SSL certificate to encrypt communication.
- Look for the padlock icon in the browser address bar.
- Run security tests
- Check for potential vulnerabilities using tools like:
- Nmap (
nmap yourserver.com) - SSL Labs (to analyze SSL configuration)
- Fail2Ban (to protect against brute-force attacks)
- Nmap (
- Check for potential vulnerabilities using tools like:
- Monitor access logs
- Run the following command to inspect server logs:
sudo journalctl -u nginx --since "1 hour ago" - Look for unusual access attempts or errors.
- Run the following command to inspect server logs:
Example: Checking HTTPS Security
If configured correctly, the backend should display a secure connection in the browser:
By following these security measures, we can ensure our AWS-hosted backend remains protected from potential threats. 🔒🚀
Benefits of Learning AWS, Ubuntu, and Deployment
Learning AWS, Ubuntu, and Deployment equips you with essential skills for managing cloud-based applications, ensuring scalability, security, and efficiency. You’ll gain hands-on experience with server configuration, Docker, and networking, enabling you to deploy and maintain real-world applications.
Mastering these technologies enhances your problem-solving abilities, strengthens your resume, and opens doors to high-demand roles in DevOps, cloud engineering, and backend development. 🚀
3. Frontend Feature
Overview
The goal of my frontend feature was to help users manage their daily tasks effectively through the Study Buddy Task Manager. I created two APIs for this project, focusing on usability and design. The first API generates random tasks for users, while the second allows users to assign tasks to specific days. The UI was built with extensive use of CSS, especially for the calendar design, allowing for an intuitive task management experience.
Features:
- Random Task API: Users can instantly get random tasks based on selected categories.
- Task Management API: Users can create, edit, delete, and fetch tasks that are assigned to specific days.
- Calendar Interface: The design utilizes CSS to provide a dynamic calendar layout where users can manage their tasks by day.
Visuals
JavaScript Logic:
document.addEventListener("DOMContentLoaded", () => {
const titleInput = document.getElementById("title-input");
const addTaskButton = document.getElementById("add-task-button");
const errorMessage = document.getElementById("error-message");
const calendarContainer = document.getElementById("calendar-container");
const monthHeader = document.getElementById("month-header");
const overlay = document.getElementById("overlay");
const closeOverlayButton = document.getElementById("close-overlay-button");
// Generate calendar days dynamically
function generateCalendarDays() {
const daysInMonth = 31;
const monthName = new Date().toLocaleString('default', { month: 'long' });
monthHeader.textContent = monthName;
calendarContainer.innerHTML = "";
for (let i = 1; i <= daysInMonth; i++) {
const dayElement = document.createElement("div");
dayElement.classList.add("calendar-day");
dayElement.innerHTML = `<span>${i}</span>`;
dayElement.addEventListener("click", () => showTasksForDay(i));
calendarContainer.appendChild(dayElement);
}
}
// Fetch tasks for the selected day
async function fetchTasks() {
try {
const response = await fetch(`${pythonURI}/api/tasks`);
const tasks = await response.json();
// Handle task display
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
// Add new task to the list
async function addTask(taskText) {
if (!taskText.trim()) {
errorMessage.textContent = "Please enter a task.";
return;
}
try {
const response = await fetch(`${pythonURI}/api/tasks`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ task: taskText })
});
const result = await response.json();
// Reload tasks after adding
} catch (error) {
alert("Error adding task.");
}
}
addTaskButton.addEventListener("click", () => {
const taskText = titleInput.value;
addTask(taskText);
});
// Random Task Generator
document.getElementById("random-task-button").addEventListener("click", async () => {
const selectedCategory = document.getElementById("category-select").value;
const url = selectedCategory ? `https://studybuddy.stu.nighthawkcodingsociety.com/api/random-tasks?category=${encodeURIComponent(selectedCategory)}` : "https://studybuddy.stu.nighthawkcodingsociety.com/api/random-tasks";
try {
const res = await fetch(url);
const data = await res.json();
document.getElementById("random-task-box").textContent = data.task || "No task found.";
} catch (error) {
document.getElementById("random-task-box").textContent = "Error fetching task.";
}
});
generateCalendarDays(); // Initialize Calendar on page load
});
4. Ideation and Teamwork
This trimester was an incredible journey—not just in coding but in teamwork and collaboration. Working with my group made the experience truly enjoyable. We always had each other’s backs, offering help when needed, which made problem-solving feel more like an exciting challenge rather than a frustration. Along the way, I formed great friendships, and that sense of camaraderie made this class one of my absolute favorites.
Looking back, I wouldn’t be where I am now, especially in backend development, without the encouragement of my teammates and even others outside my group. Their support and collaboration laid the foundation for everything we built together, and I’m grateful for the experience.
Burndown List
As a user, I want a task manager to organize my assignments, tests, and deadlines so I can prioritize my tasks and avoid last-minute stress.
- Let users add new tasks to their list and delete them, and save changes to the backend when loading/exiting the page.
- Options for due dates, subject, description, etc. It can be edited and changed as necessary.
- Implement a calendar interface to visually organize tasks by day.
- Ensure tasks appear under the correct day when assigned.
- Create an overlay that displays tasks for a selected day.
- Integrate a task editing feature with inline text modification.
- Implement a delete confirmation prompt for task removals.
- Fetch tasks dynamically from the backend when clicking on a calendar day.
- Improve UI styling with a modern, dark-themed design and responsive layout.
- Add hover effects to interactive elements to improve UX.
- Implement a “random task” generator with selectable categories.
- Ensure random tasks come from an external API and display properly.
- Add error handling for API calls (random task, fetching tasks, etc.).
- Implement input validation for adding tasks (empty tasks are not allowed).
- Ensure real-time feedback for users when tasks are added, edited, or deleted.
- Use modal overlays for better task visualization and interaction.
- Implement a reward system concept (frontend elements prepared, backend integration pending).
- Optimize API calls to reduce redundant fetch operations.
- Award users experience and rewards for completing tasks.
📌 Check out my user story here: User Story 3
5. Databases and CRUD Operations
This trimester, one of my biggest learning milestones was understanding databases and CRUD (Create, Read, Update, Delete) operations. These concepts are fundamental for any full-stack application, as they serve as the backbone for data management. It was challenging at first to understand how the backend communicates with the frontend to create a dynamic application, but once I understood the flow, everything clicked.
The hands-on experience of building and connecting a database to my application has been invaluable. It gave me a deeper understanding of how data is stored, accessed, and modified in an application. Using SQLAlchemy with Flask made this process easier, as it allowed me to write Python code to interact with the database instead of manually writing SQL queries.
In my project, the backend was responsible for handling CRUD operations related to tasks, which users could create, view, update, and delete. The real magic came when I connected the backend to the frontend, and I could see how the changes in the database reflected on the user interface in real-time.
API/MODEL Burndown List
- Create a Task model in the backend with CRUD methods (create, read, update, delete).
- Implement API routes for each CRUD operation (POST, GET, PUT, DELETE).
- Connect the backend API to the frontend to fetch and display tasks dynamically.
- Ensure tasks are stored and retrieved from the database correctly.
- Add error handling for failed database operations (e.g., missing data, invalid updates).
- Implement task updating functionality so users can modify task details.
- Ensure tasks are deleted from the database when removed from the frontend.
- Add validation to ensure tasks are not empty before saving to the database.
- Use a unique constraint on the task field to prevent duplicate tasks.
- Ensure API returns meaningful error messages for failed operations.
- Test all CRUD operations thoroughly with valid and invalid data.
- Implement database seeding for initial data in the development environment.
- Optimize API responses for faster performance.
📌 Backend Ideation: Connecting Frontend Code to Backend API
📌 Backend Integration Issue: Integrating API Logic
My database
With the most important part of my model
Task Model
Key Attributes
- id: A unique identifier for each task.
- _task: A string field representing the task description. This field is required and must be unique.
Methods
__init__(self, task): Initializes a new task object with the task description.create(): Adds the task to the database and commits the transaction.read(): Retrieves the task’s data as a dictionary.update(): Updates an existing task in the database.delete(): Deletes the task from the database.restore(): Restores tasks from a given dataset, either updating existing tasks or creating new ones.
Database Operations
The model uses SQLAlchemy’s ORM to interact with the database. It allows seamless creation, reading, updating, and deletion of tasks from the SQLite database.
Example Usage
- Create a Task:
new_task = Task(task="Complete the assignment.") new_task.create()