-
Notifications
You must be signed in to change notification settings - Fork 1
Iteration 2: Design
Team Noname plans to provide Barrios Technology with a web application that gives users access to predictive modeling and forecasts based on past ISS consumables data. The application's interface will allow users to update past consumables data and view a dashboard that includes analysis of past outcomes and future predictions.
- Interactive dashboard that will include:
- A high-level overview of all current analyses and predictions
- The ability to upload updated datasets for adjusted analyses and predictions
- Detailed views of usage analysis, resupply predictions, and a detailed flight plan
- REST API that will include:
- Controller-based routing that will:
- Accept requests from the browser client
- Use request parameters to call methods on analysis and prediction models
- Coordinate data persistence through services or repositories
- Respond with either structured JSON data or a hypermedia representation of the data's state
- Models that will operate on data provided by the controller via a service or repository
- Services/repositories whose only responsibility will be to provide an interface to the persistence infrastructure
- Controller-based routing that will:
- Database that will provide the ability to:
- Store, update and retrieve user-provided datasets
- Store, update and retrieve prediction and analysis results
- Ability to choose from multiple analysis methods
- Upload Barrios user data
- Retrieve stored user data
- View accuracy analysis, forecasting, and optimization with graphical charts
- Retrieve and view past analyses
- Manage users and user roles
The Barrios analytics application will follow a server/client model with a Hypermedia/REST API (i.e., server endpoints respond with HTML fragments rather than JSON. This approach should simplify the client development by restricting the application state to the server. More advanced, "single-page application" style interactivity will be achieved by using HTMX.
The server will be implemented using the emmett framework. Emmett is an HTTP server framework written in Python that will allow the team to organize the code in whatever form necessary without the need to adhere to a framework's choice of architecture. While this may require some additional code, we hope that the effort saved by reducing front-end complexity can be devoted to crafting the server architecture.
The server's architecture will be modeled following a mixed approach that follows aspects of model-view-controller (MVC) and some aspects of a layered approach. The controllers will be the outer or topmost layer, which will respond to HTTP messages sent to various routes as required by UI functionality. Those controllers will call methods on services to coordinate data persistence/retrieval from repositories and instantiation of and communication with models.
Models will either represent optimized, forecast, or analysis data or act as the implementation of various analytics methods. Finally, at the infrastructure level, repositories will act as interfaces to databases — implementations of which will serve to communicate with their specific database drivers — allowing the developers to accommodate different database engines, depending on the client's needs or the current needs of the development process.
Pandas, Dask, and Numpy will be used to explore, analyze and clean user data and to extract the necessary values for analysis. Services may also use these libraries to transform persisted data for modeling functions.
classDiagram
class AccountsConfig {
default_auto_field : str
name : str
}
class CustomUser {
}
class CustomUserAdmin {
add_form
form
list_display : list
model
}
class CustomUserChangeForm {
}
class CustomUserCreationForm {
}
class LoginForm {
password : CharField
username : CharField
}
class Meta {
fields : tuple
model
}
class Meta {
fields : tuple
model
}
class Migration {
dependencies : list
initial : bool
operations : list
}
class Profile {
user : OneToOneField
}
CustomUserChangeForm --* CustomUserAdmin : form
CustomUserCreationForm --* CustomUserAdmin : add_form
CustomUser --* CustomUserAdmin : model
CustomUser --* Meta : model
CustomUser --* Meta : model
Data classes are meant to mirror the individual datasets provided by the client.
classDiagram
class Category {
category_id : IntegerField
category_name : CharField
rate_category : CharField
}
class Command {
handle()
}
class Consumable {
actual_rate : FloatField
assumed_rate : FloatField
category : ForeignKey
name : CharField
}
class DataConfig {
default_auto_field : str
name : str
}
class DataService {
file : str
get_count_by_slug(slug: str) int
get_data_by_slug(slug: str) Result
get_num_lines(csv_path)
get_uploaded_file(csv_path)
insert_csv(model_name: str, file_object) Result
keys_to_snake(original_dict)
}
class EmptyKeywordManager {
create()
}
class EmptyKeywordManager {
create()
}
class EmptyStringToNoneFloatField {
get_prep_value(value)
}
class EmptyStringToNoneIntegerField {
get_prep_value(value)
}
class FieldFileCsvHelper {
get_csv_column_dtypes(filepath)
get_csv_header(filepath)
get_file_info(filepath)
rewrite_csv(filepath: str, fieldnames: list[str]) Result
}
class FlightPlanManager {
create()
}
class FlightPlanManager {
create()
}
class ImsConsumablesCategoryLookup {
category : OneToOneField
category_name : CharField
module_id : IntegerField
module_name : CharField
readable_name : str
unique_cat_mod_id : CharField
}
class ImsFlightplanModel {
objects
}
class ImsManager {
date_fields : list
create()
}
class ImsModel {
objects
}
class InventoryMgmtSystemConsumables {
action_date : DateTimeField
barcode : CharField
calculated_volume
category : ForeignKey
category_name : CharField
children_volume
current_ip_owner : CharField
datedim : DateTimeField
diameter
english_name : CharField
expire_date : DateTimeField
fill_status : CharField
hazard : CharField
height
id_parent
id_path : CharField
ims_id
is_container : BooleanField
is_moveable : BooleanField
launch : CharField
length
location_name : CharField
move_date : DateTimeField
objects
operational_nomenclature : CharField
original_ip_owner : CharField
ovrrd_notes : CharField
part_number : CharField
quantity
readable_name : str
russian_name : CharField
serial_number : CharField
state : CharField
status : CharField
stwg_ovrrd_chldrn_vol
stwg_ovrrd_vol
subsystem : CharField
system : CharField
tree : CharField
tree_depth
type : CharField
volume_notes : CharField
width
}
class IssFlightPlan {
datedim : DateField
eva_accuracy : CharField
eva_name : CharField
eva_type : CharField
event : CharField
port_name : CharField
readable_name : str
vehicle_name : CharField
vehicle_type : CharField
}
class IssFlightPlanCrew {
crew_count : IntegerField
datedim : DateField
nationality_category : CharField
readable_name : str
}
class IssFlightPlanCrewNationalityLookup {
is_rsa_crew : BooleanField
is_usos_crew : BooleanField
nationality : CharField
readable_name : str
}
class Meta {
fields : tuple
model
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
abstract : bool
}
class Meta {
abstract : bool
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Meta {
db_table : str
}
class Migration {
dependencies : list
initial : bool
operations : list
}
class RatesDefinition {
affected_consumable : CharField
category : OneToOneField
efficiency : CharField
rate : FloatField
rate_category : CharField
readable_name : str
type : CharField
units : CharField
}
class RsaConsumableWaterSummary {
objects
readable_name : str
remain_potable_liters : FloatField
remain_rodnik_liters : FloatField
remain_technical_liters : FloatField
report_date : DateField
}
class RsaConsumablesManager {
create()
}
class TankCapacityDefinition {
readable_name : str
tank_capacity : FloatField
tank_category : CharField
units : CharField
}
class TestDataViews {
test_csv : SimpleUploadedFile
test_nocol_csv : SimpleUploadedFile
user
setUp()
test_file_upload_rejects_unauthed_user()
test_file_upload_works_for_authed_user()
test_file_upload_works_for_non_header_csv()
test_get_request_to_upload_not_allowed()
test_upload_post_not_authenticated()
test_user_authenticated_base_route()
test_user_not_authenticated_base_route()
}
class ThresholdsLimitsDefinition {
category : ForeignKey
readable_name : str
threshold_category : CharField
threshold_owner : CharField
threshold_value : FloatField
units : CharField
}
class Upload {
file : FileField
upload_date : DateTimeField
}
class UploadForm {
}
class UploadManager {
get_queryset()
}
class UsRsWeeklyConsumableGasSummary {
adjusted_n2_kg
adjusted_o2_kg
date : DateField
objects
readable_name : str
resupply_air_kg
resupply_n2_kg
resupply_o2_kg
rs_n2_kg
rs_o2_kg
us_n2_kg
usos_o2_kg
}
class UsRsWeeklyConsumableManager {
create()
}
class UsWeeklyConsumableManager {
create()
}
class UsWeeklyConsumableWaterSummary {
corrected_potable_l
corrected_predicted_l
corrected_technical_l
corrected_total_l
date : DateField
objects
readable_name : str
resupply_potable_l
resupply_technical_l
}
class VehicleCapacityDef {
ascent_capacity_ctbe : IntegerField
descent_capacity_ctbe : IntegerField
objects
total_capacity_ctbe : FloatField
trash_capacity_ctbe : IntegerField
vehicle : CharField
}
FlightPlanManager --|> EmptyKeywordManager
FlightPlanManager --|> EmptyKeywordManager
RsaConsumablesManager --|> EmptyKeywordManager
UsRsWeeklyConsumableManager --|> EmptyKeywordManager
UsWeeklyConsumableManager --|> EmptyKeywordManager
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : width
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : height
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : length
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : diameter
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : calculated_volume
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : stwg_ovrrd_vol
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : children_volume
EmptyStringToNoneFloatField --* InventoryMgmtSystemConsumables : stwg_ovrrd_chldrn_vol
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : usos_o2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : rs_o2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : us_n2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : rs_n2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : adjusted_o2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : adjusted_n2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : resupply_o2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : resupply_n2_kg
EmptyStringToNoneFloatField --* UsRsWeeklyConsumableGasSummary : resupply_air_kg
EmptyStringToNoneFloatField --* UsWeeklyConsumableWaterSummary : corrected_potable_l
EmptyStringToNoneFloatField --* UsWeeklyConsumableWaterSummary : corrected_technical_l
EmptyStringToNoneFloatField --* UsWeeklyConsumableWaterSummary : corrected_total_l
EmptyStringToNoneFloatField --* UsWeeklyConsumableWaterSummary : resupply_potable_l
EmptyStringToNoneFloatField --* UsWeeklyConsumableWaterSummary : resupply_technical_l
EmptyStringToNoneFloatField --* UsWeeklyConsumableWaterSummary : corrected_predicted_l
EmptyStringToNoneIntegerField --* InventoryMgmtSystemConsumables : ims_id
EmptyStringToNoneIntegerField --* InventoryMgmtSystemConsumables : id_parent
EmptyStringToNoneIntegerField --* InventoryMgmtSystemConsumables : tree_depth
EmptyStringToNoneIntegerField --* InventoryMgmtSystemConsumables : quantity
ImsManager --* InventoryMgmtSystemConsumables : objects
RsaConsumablesManager --* RsaConsumableWaterSummary : objects
UsRsWeeklyConsumableManager --* UsRsWeeklyConsumableGasSummary : objects
UsWeeklyConsumableManager --* UsWeeklyConsumableWaterSummary : objects
Domain classes are the base components of the system. Most of them, for example, User
and File
, represent application data and have no methods. Some, such as the Analyzer
classes, only exist to run analyses of a specific type and generate various Analysis
classes. The Result
class represents an operation's outcome and will assist in consistent error handling across the application.
Both Analysis
and Analyzer
classes are interfaces to be realized by the implementations shown in the diagram.
Service classes, such as controllers, services, and repositories, will be implemented using basic dependency injection. As such, their relationships are modeled as dependencies.