# SMEDS UI - Project Summary

## Overview
This repository is a Flask web application that consolidates the team’s key data science tools into a single internal website.

## Key Components
- `app.py`
  - Flask application entrypoint.
  - Loads configuration from `utils/config.py`.
  - Initializes OAuth authentication and JWT support.
  - Registers two blueprints: `auth` and `main`.
  - Enforces login for all non-static routes via `@app.before_request`.
  - Clears the session on first app launch with `@app.before_first_request`.

- `blueprints/auth`
  - Handles login, callback, and logout flows.
  - Uses `authlib` and internal USM OAuth settings.
  - Supports stateless JWT-based auth and sets session/cookies.
  - Logs successful logins in the database.

- `blueprints/main`
  - Defines the main user-facing functionality.
  - `TrackReviewView` for Track Review and feedback workflows.
  - `CardInfoView` for track details in a card that pops up within Track Review.
  - `First35StandardView`, `First35ProView`, `First35BenchmarkView`, `First35AlbumsView` for "First 35" tools.
  - Additional routes for curated track lists, signup, and action recording.

- `utils/config.py`
  - Contains environment-specific settings for local/dev/uat.
  - Defines OAuth URIs, database source selection, session lifetime, and secrets.

- `utils/sme_ds_utilities.py`
  - Provides database query/update helpers and likely core data access behavior.

## Features and Flows
- Authentication
  - Redirects unauthenticated users to `/auth/login`.
  - Uses OAuth callback to create/check users in `tadas_sandbox.tadas_users`.
  - Supports bearer tokens in `Authorization` headers.

- Track Review Tool
  - Loads recommended tracks from `iago.historical` and related tables.
  - Filters out removed artists and joins news/holiday metadata.
  - Renders `track_review_v4.html`.
  - Handles POST requests for timeseries and segment data.

- Card Info Tool
  - Fetches card-level metadata from daily source tables.
  - Renders content via `card_info.html`.

- First 35 Anomaly Tools
  - Builds anomaly detection result sets from `first_35.current_events`.
  - Supports multiple views for standard, pro, benchmark, and album experiences.
  - Includes route `/first_35_curated` for a curated set of songs.
  - Includes a suggestions endpoint used by benchmark workflows.

- Signup / User Preferences
  - Captures notification preferences and saved filters.
  - Renders `signup.html` for a registration/preferences flow.

## Templates and Static Content
- Templates are stored in `templates/` and include a mix of dashboards and utility pages such as:
  - `track_review_v4.html`, `track_review.html`, `first_35.html`, `first_35_pro.html`, `benchmark_assignment.html`, `card_info.html`, `signup.html`, `albums.html`, and more.
- Static assets live under `static/css/` and `static/js/`.
- There are multiple base templates (`base.html`, `base_v2.html`, `base_v3.html`, `base_v4.html`, `base_roas.html`) suggesting older versions or unused layout variants.

## Current Cleanup Signals
- There are explicit `TODO` comments in `blueprints/main/routes.py` and `blueprints/main/views.py` indicating work remaining.
- The project appears to have legacy or commented-out routes for `glossary`, `tutorial`, and `usage_report`.
- The blueprint import path for `utils` is manually appended in several files, which is a likely cleanup target.
- `README.md` is minimal and marked for overhaul.

## Summary
This is an internal analytics dashboard for music operations, built on Flask with OAuth/JWT authentication and a data-driven frontend. The main tools are:
- track review
- first 35 streaming insight tools,
- roas

The current repo structure is functional, but it still contains stale templates, static assets, and TODO notes that make it a good candidate for cleanup and reorganization.


## Running the application locally
To run the  application locally, run the following command: 

```bash
python -m flask run --port 5003
```

Note that it is necessary to include the --port 5003 command line argument since by default the run() command in main will not be invoked when called like this.
