Data Persistence Layer
Relevant source files
The following files were used as context for generating this wiki page:The Data Persistence Layer in the SPK Kajek project is responsible for storing, retrieving, and managing all application data. Instead of a traditional database, the system employs a file-based persistence strategy, utilizing a combination of Microsoft Excel (.xlsx) and JSON (.json) files. This approach simplifies setup and deployment for the project's scope.
This layer handles three primary types of data: vendor information for TOPSIS analysis, user account details for authentication, and a historical log of past calculations. The FastAPI backend directly interacts with these files for all data operations, serving as the intermediary between the data files and the React frontend.
Sources: SUMMARY.md, backend/main.py
Architecture Overview
The persistence architecture is centered around the backend server, which reads from and writes to a set of predefined files located in the backend/ directory. The frontend communicates with the backend via a REST API to access or modify this data.
The diagram below illustrates the high-level architecture of the data layer.
This diagram shows the FastAPI backend acting as the sole gateway to the file-based data storage.
Sources: SUMMARY.md, backend/main.py:23-25
Data Sources
The system relies on three key files for data persistence.
1. Vendor Data (TOPSIS_Input_Level.xlsx)
This Excel file is the primary data source for the TOPSIS calculation, containing the list of VPS vendors and their corresponding criteria levels. The backend uses the pandas and openpyxl libraries to perform CRUD (Create, Read, Update, Delete) operations on this file.
Sources: backend/main.py:23, README.md
Schema
The data is stored in a sheet named 1. Input Level, starting from the third row. The structure is as follows:
| Column | Data Type | Description |
|---|---|---|
No | Integer | Unique identifier for the vendor entry. |
Vendor | String | The name of the cloud provider. |
Nama Paket (Plan) | String | The specific plan or package name. |
CPU_Level | Integer (1-5) | The performance level for CPU. |
RAM_Level | Integer (1-5) | The performance level for RAM. |
DiskIO_Level | Integer (1-5) | The performance level for Disk I/O. |
Price_Level | Integer (1-5) | The cost level for the price. |
Sources: backend/main.py:317-319, generate_excel_level.py:168-175
The schema can be visualized with the following ER diagram.
2. User Data (users.json)
This JSON file stores user account information for authentication. The backend loads this file to verify credentials and manage user profiles. If the file does not exist, it is created automatically with a default admin user.
Sources: backend/main.py:25, backend/main.py:113-124
Schema
The file contains a JSON object where each key is a username, and the value is an object containing the user's details.
| Field | Data Type | Description |
|---|---|---|
username | String | The user's login name. |
password | String | The hashed password (PBKDF2-HMAC-SHA256). |
email | String | The user's email address. |
display_name | String | The name shown in the UI. |
Sources: backend/main.py:115-121, backend/users.json
The diagram below shows the structure for a single user entry within the users.json object.
Security
Passwords are not stored in plaintext. They are hashed using the hashlib.pbkdf2_hmac function with sha256, a 16-byte salt, and 100,000 iterations.
Sources: backend/main.py:91-95, frontend/src/components/DocumentationView.tsx:69-73
3. Calculation History (calculation_history.json)
This file logs the results of past TOPSIS analyses. Each time a calculation is saved from the frontend, a new entry is prepended to an array in this file. The history is capped at the last 50 entries to prevent the file from growing indefinitely.
Sources: backend/main.py:24, backend/main.py:739-742
Schema
The file contains a JSON array of history entry objects.
| Field | Data Type | Description |
|---|---|---|
id | Integer | A unique identifier for the history entry. |
timestamp | String (ISO) | The date and time the calculation was saved. |
title | String | A user-defined title for the analysis. |
description | String | Optional notes about the analysis. |
tags | Array of Strings | User-defined tags for filtering. |
weights | Object | The weights used for the calculation (cpu, ram, disk, price). |
total_alternatives | Integer | The number of vendors analyzed. |
top_vendor | String | The name of the top-ranked vendor. |
top_score | Float | The score of the top-ranked vendor. |
rankings | Array of Objects | A list of the top 5 vendors from the analysis. |
Sources: backend/main.py:721-736, backend/calculation_history.json
The structure of a history entry is shown below.
Data Flow and Management
The backend/main.py file defines several utility functions and API endpoints to manage the data files.
Key Utility Functions
| Function | File | Description |
|---|---|---|
load_users() | backend/main.py:110 | Reads users.json into memory. Creates a default admin if the file is missing. |
save_users() | backend/main.py:126 | Writes the current user data object back to users.json. |
load_history() | backend/main.py:680 | Reads calculation_history.json into memory. |
save_history() | backend/main.py:687 | Writes the current history array back to calculation_history.json. |
Sources: backend/main.py
API Interaction Flow
All interactions with the data files are brokered by the API. The following sequence diagram illustrates the flow for reading all vendor data.
This diagram shows how a frontend request for data is handled by the backend, which reads the Excel file and returns a JSON response.
Sources: backend/main.py:315-323, SUMMARY.md
Data Management API Endpoints
The following table summarizes the API endpoints responsible for data persistence.
| Endpoint | Method | Description | Target File |
|---|---|---|---|
/api/data | GET | Retrieves all vendor data. | TOPSIS_Input_Level.xlsx |
/api/data | POST | Adds a new vendor. | TOPSIS_Input_Level.xlsx |
/api/data/{vendor_no} | PUT | Updates an existing vendor by its No. | TOPSIS_Input_Level.xlsx |
/api/data/{vendor_no} | DELETE | Deletes a vendor by its No. | TOPSIS_Input_Level.xlsx |
/api/profile | PUT | Updates the current user's profile. | users.json |
/api/change-password | POST | Changes the current user's password. | users.json |
/api/history | GET | Retrieves all calculation history. | calculation_history.json |
/api/history | POST | Saves a new calculation result to history. | calculation_history.json |
/api/history/{id} | DELETE | Deletes a specific history entry. | calculation_history.json |
Sources: backend/main.py, README.md
Conclusion
The data persistence layer of the SPK Kajek application is a pragmatic, file-based system tailored to the project's requirements. It uses an Excel file for primary analytical data and JSON files for user management and history logging. While this avoids the complexity of a full database setup, it centralizes data I/O within the FastAPI backend, which provides a clean, abstracted interface for the frontend through a well-defined REST API. This design is effective for the application's scale and purpose.
Sources: SUMMARY.md, backend/main.py