Comment all the things!

master
Garrett Mills 4 years ago
parent 72f3923866
commit 06515b0559
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246

@ -4,8 +4,11 @@ const path = require('path')
/** /**
* FrontendUnit * FrontendUnit
* @extends Unit
* ---------------------------------------------------------------------------------------- * ----------------------------------------------------------------------------------------
* A Flitter application unit which sets up routes for accessing the javascript front-end
* pages we created in Project 3.
*
* @extends Unit
*/ */
class FrontendUnit extends Unit { class FrontendUnit extends Unit {
static get services() { static get services() {
@ -23,9 +26,8 @@ class FrontendUnit extends Unit {
} }
/** /**
* * Initializes the unit. Creates the `/app` static endpoing and default settings.
* @param app * @param {FlitterApp} app
*
*/ */
async go(app) { async go(app) {
app.express.use('/app', [ app.express.use('/app', [

@ -18,7 +18,7 @@ class GenerateMatchupsForWeekPatch extends Injectable {
} }
/** /**
* * Run the patch.
*/ */
async run() { async run() {
const Team = this.models.get('Team') const Team = this.models.get('Team')
@ -116,9 +116,9 @@ class GenerateMatchupsForWeekPatch extends Injectable {
} }
/** /**
* * Get a list of all teams played by the given team.
* @param team * @param {Team} team
* @returns data to represent what teams have been played by the param team * @returns {Promise<Array<string>>}
*/ */
async get_teams_played_by_team(team) { async get_teams_played_by_team(team) {
const Matchup = this.models.get('Matchup') const Matchup = this.models.get('Matchup')

@ -2,8 +2,11 @@ const { Injectable } = require('flitter-di')
/** /**
* GenerateWeeklyResultsPatch * GenerateWeeklyResultsPatch
* @extends Injectable
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* A patch which generates the weekly team results using the player stat data
* for teh currently configured play week.
*
* @extends Injectable
*/ */
class GenerateWeeklyResultsPatch extends Injectable { class GenerateWeeklyResultsPatch extends Injectable {
static get services() { static get services() {

@ -1,8 +1,12 @@
const { Controller } = require('libflitter') const { Controller } = require('libflitter')
/** /**
* DraftBoard controller * DraftBoard controller
* @extends Controller
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* This controller contains logic for handling API requests related to fetching
* and drafting available players. Its methods should handle Express requests &
* responses.
*
* @extends Controller
*/ */
class DraftBoard extends Controller { class DraftBoard extends Controller {
static get services() { static get services() {
@ -42,6 +46,7 @@ class DraftBoard extends Controller {
.api() .api()
} }
// look up the player specified in the request
const Player = this.models.get('Player') const Player = this.models.get('Player')
const player = await Player.findById(req.body.player_id) const player = await Player.findById(req.body.player_id)
if ( !player ) { if ( !player ) {
@ -50,6 +55,7 @@ class DraftBoard extends Controller {
.api() .api()
} }
// Don't allow drafting already-drafted players
if ( await player.is_obligated() ) { if ( await player.is_obligated() ) {
return res.status(400) return res.status(400)
.message('This player has already been drafted.') .message('This player has already been drafted.')

@ -1,18 +1,22 @@
const { Controller } = require('libflitter') const { Controller } = require('libflitter')
/* /**
* Home Controller * Home Controller
* ------------------------------------------------------------- * -------------------------------------------------------------
* Controller for the main homepage of this Flitter app. Methods here * Controller for the main homepage of this Flitter app. Methods here
* are used as handlers for routes specified in the route files. * are used as handlers for routes specified in the route files.
*
* @extends Controller
*/ */
class Home extends Controller { class Home extends Controller {
static get services() { static get services() {
return [...super.services, 'sports_data'] return [...super.services, 'sports_data']
} }
/* /**
* Serve the main welcome page. * Serve the main welcome page.
* @param req
* @param res
*/ */
welcome(req, res){ welcome(req, res){
if ( req.user ) { if ( req.user ) {
@ -22,6 +26,14 @@ class Home extends Controller {
} }
} }
/**
* Return the current session's status (including team information and
* information about the current stage of gameplay).
* @param req
* @param res
* @param next
* @return {Promise<*>}
*/
async get_status(req, res, next) { async get_status(req, res, next) {
return res.api({ return res.api({
team_id: req.user_team.id, team_id: req.user_team.id,

@ -1,8 +1,12 @@
const { Controller } = require('libflitter') const { Controller } = require('libflitter')
/** /**
* ScoresController * ScoresController
* @extends Controller
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* This controller contains logic for handling API requests related to the
* weekly scores and matchups endpoints.
*
* @extends Controller
*/ */
class ScoresController extends Controller { class ScoresController extends Controller {
static get services() { static get services() {
@ -22,6 +26,7 @@ class ScoresController extends Controller {
const current_week = await this.sports_data.current_play_week() const current_week = await this.sports_data.current_play_week()
const weekly_data = [] const weekly_data = []
// Convert all of the matchup instances to API format for each week
for ( let i = 1; i <= current_week; i += 1 ) { for ( let i = 1; i <= current_week; i += 1 ) {
const matchups = await Matchup.find({ week_num: i }) const matchups = await Matchup.find({ week_num: i })
const api_data = await Promise.all(matchups.map(x => x.to_api())) const api_data = await Promise.all(matchups.map(x => x.to_api()))
@ -43,12 +48,14 @@ class ScoresController extends Controller {
const all_teams = await Team.find() const all_teams = await Team.find()
const stat_records = [] const stat_records = []
// Generate the cumulative team data for all teams
for ( const team of all_teams ) { for ( const team of all_teams ) {
const rec = await team.cumulative_data() const rec = await team.cumulative_data()
rec.team_name = team.team_name rec.team_name = team.team_name
stat_records.push(rec) stat_records.push(rec)
} }
// Sort the teams by number of wins, then number of points scored
stat_records.sort((a, b) => { stat_records.sort((a, b) => {
if ( a.wins === b.wins ) { if ( a.wins === b.wins ) {
return a.points_scored - b.points_scored return a.points_scored - b.points_scored
@ -57,6 +64,7 @@ class ScoresController extends Controller {
return a.wins > b.wins ? 1 : -1 return a.wins > b.wins ? 1 : -1
}) })
// Return the records in a format compatible with the front-end
return res.api(stat_records.map((x, i) => { return res.api(stat_records.map((x, i) => {
return { return {
standing: { standing: {

@ -1,8 +1,12 @@
const { Controller } = require('libflitter') const { Controller } = require('libflitter')
/* /**
* Teams Controller * Teams Controller
* ------------------------------------------------------------- * -------------------------------------------------------------
* This controller contains logic related to viewing and managing
* the user's team, team lineups, and team players.
*
* @extends Controller
*/ */
class Teams extends Controller { class Teams extends Controller {
static get services() { static get services() {
@ -78,10 +82,12 @@ class Teams extends Controller {
.api() .api()
} }
// fetch the team players & the current lineup
const player_ids = (await req.user_team.players()).map(x => x.id) const player_ids = (await req.user_team.players()).map(x => x.id)
const lineup = await req.user_team.lineup() const lineup = await req.user_team.lineup()
lineup.clear_lineup() lineup.clear_lineup()
// Add all the starting players to the lineup
for ( const player of req.body.starting_players ) { for ( const player of req.body.starting_players ) {
if ( !player.id || !player.position ) continue; if ( !player.id || !player.position ) continue;
@ -90,6 +96,7 @@ class Teams extends Controller {
position: player.position, position: player.position,
} }
// Don't allow adding other teams' players to the lineup
if ( !player_ids.includes(lineup_record.player_id) ) { if ( !player_ids.includes(lineup_record.player_id) ) {
return res.status(400) return res.status(400)
.message(`Sorry, the player ${lineup_record.player_id} is not on your team.`) .message(`Sorry, the player ${lineup_record.player_id} is not on your team.`)
@ -99,6 +106,7 @@ class Teams extends Controller {
lineup.start_player(lineup_record) lineup.start_player(lineup_record)
} }
// Bench all the other players
for ( const player of req.body.benched_players ) { for ( const player of req.body.benched_players ) {
if ( !player.id ) continue; if ( !player.id ) continue;
@ -111,18 +119,12 @@ class Teams extends Controller {
lineup.bench_player(player) lineup.bench_player(player)
} }
console.log('pre save', lineup)
// Save the partial lineup // Save the partial lineup
await lineup.save() await lineup.save()
console.log('post save', lineup)
// Fetch a fresh version to fill in any missing players // Fetch a fresh version to fill in any missing players
const corrected_lineup = await req.user_team.lineup() const corrected_lineup = await req.user_team.lineup()
console.log('corrected', corrected_lineup)
return res.api(await corrected_lineup.to_api()) return res.api(await corrected_lineup.to_api())
} }

@ -4,6 +4,8 @@ const FormController = require('flitter-auth/controllers/Forms')
* Handles views and processing for auth registration/login/logout/etc. * Handles views and processing for auth registration/login/logout/etc.
* Most handlers are inherited from the default flitter-auth/controllers/Forms * Most handlers are inherited from the default flitter-auth/controllers/Forms
* controller, however you can override them here as you need. * controller, however you can override them here as you need.
*
* This file was auto-generated by the Flitter framework.
*/ */
class Forms extends FormController { class Forms extends FormController {

@ -8,6 +8,8 @@ const Controller = require('flitter-auth/controllers/KeyAction')
* one-time links that call methods on controllers and (optionally) * one-time links that call methods on controllers and (optionally)
* can even automatically sign in a user for the request, then log * can even automatically sign in a user for the request, then log
* them out. e.g. a password reset link could use a key action. * them out. e.g. a password reset link could use a key action.
*
* This file was auto-generated by the Flitter framework.
*/ */
class KeyAction extends Controller { class KeyAction extends Controller {

@ -5,6 +5,8 @@ const Oauth2Controller = require('flitter-auth/controllers/Oauth2')
* built-in OAuth2 server, if it is enabled. Most handlers are inherited * built-in OAuth2 server, if it is enabled. Most handlers are inherited
* from flitter-auth/controllers/Oauth2, but you can override them here * from flitter-auth/controllers/Oauth2, but you can override them here
* as you need. * as you need.
*
* This file was auto-generated by the Flitter framework.
*/ */
class Oauth2 extends Oauth2Controller { class Oauth2 extends Oauth2Controller {

@ -1,30 +0,0 @@
const { Model } = require('flitter-orm')
/*
* Example Model
* -------------------------------------------------------------
* This is a sample model. The schema or structure of the model should
* be specified here. It is then passed to flitter-orm and can be accessed
* globally using the canonical models service.
*/
class Example extends Model {
static get services() {
return [...super.services, 'output']
}
/*
* Define the flitter-orm schema of the model.
*/
static get schema() {
return {
name: String,
create_date: {type: Date, default: () => new Date},
}
}
log_name() {
this.output.info(`[Example Model] ${this.name}`)
}
}
module.exports = exports = Example

@ -32,6 +32,10 @@ class Lineup extends Model {
} }
} }
/**
* Calculate the fantasy points scored by the starting players on this lineup.
* @return {Promise<number>}
*/
async calculate_fantasy_points() { async calculate_fantasy_points() {
const starting_players = await this.players_in_starting() const starting_players = await this.players_in_starting()
let points = 0 let points = 0

@ -1,8 +1,10 @@
const { Model } = require('flitter-orm') const { Model } = require('flitter-orm')
/** /**
* Matchup * Matchup
* @extends Model
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
* A model representing a single scheduled match-up between two teams.
*
* @extends Model
*/ */
class Matchup extends Model { class Matchup extends Model {
static get services() { static get services() {
@ -40,7 +42,8 @@ class Matchup extends Model {
} }
/** /**
* updates the API's data * Format this matchup to be compatible with the API output.
* @returns Promise<object>
*/ */
async to_api() { async to_api() {
const home_team = await this.home_team() const home_team = await this.home_team()

@ -1,22 +1,27 @@
const { Model } = require('flitter-orm') const { Model } = require('flitter-orm')
const ActiveScope = require('./scopes/Active.scope') const ActiveScope = require('./scopes/Active.scope')
/* /**
* Player Model * Player Model
* ------------------------------------------------------------- * -------------------------------------------------------------
* A model representing a single player in the game.
*
* @extends Model
*/ */
class Player extends Model { class Player extends Model {
static get services() { static get services() {
return [...super.services, 'output', 'models', 'sports_data'] return [...super.services, 'output', 'models', 'sports_data']
} }
// Enable soft-deletes using the active scope
static scopes = [new ActiveScope()] static scopes = [new ActiveScope()]
/* /**
* Define the flitter-orm schema of the model. * Define the flitter-orm schema of the model.
*/ */
static get schema() { static get schema() {
return { return {
// Data used by the patches internally, but not exposed to the API
patch_data: { patch_data: {
patch_team_id: Number, patch_team_id: Number,
patch_team_name: String, patch_team_name: String,
@ -24,6 +29,7 @@ class Player extends Model {
player_id: Number, player_id: Number,
draft_position: Number, draft_position: Number,
}, },
player_number: Number, player_number: Number,
first_name: String, first_name: String,
last_name: String, last_name: String,
@ -38,6 +44,7 @@ class Player extends Model {
age: Number, age: Number,
photo_url: String, photo_url: String,
// Statistics pre-generated for the player to optimize performance
seed_stats: Object, seed_stats: Object,
// False if the player doesn't have any week-1 stats. // False if the player doesn't have any week-1 stats.
@ -74,7 +81,8 @@ class Player extends Model {
} }
/** /**
* returns the id's of the unobligated players * returns all of the unobligated players across all teams
* @return Promise<Array<Player>>
*/ */
static async get_unobligated_players() { static async get_unobligated_players() {
const Team = this.prototype.models.get('Team') const Team = this.prototype.models.get('Team')
@ -93,9 +101,9 @@ class Player extends Model {
} }
/** /**
* * Returns the stats for the player for the given week.
* @param week_num * @param {number} week_num
* @returns the points scored of that week * @returns Promise<WeeklyPlayerStat>
*/ */
async points_for_week(week_num) { async points_for_week(week_num) {
const WeeklyPlayerStat = this.models.get('WeeklyPlayerStat') const WeeklyPlayerStat = this.models.get('WeeklyPlayerStat')
@ -103,8 +111,8 @@ class Player extends Model {
} }
/** /**
* @returns true if the player is obligated * Determine whether the player belongs to a team or not.
* @returns false if the player is not obligates * @returns {Promise<boolean>} - true if the player is obligated
*/ */
async is_obligated() { async is_obligated() {
const Team = this.models.get('Team') const Team = this.models.get('Team')
@ -117,12 +125,13 @@ class Player extends Model {
} }
/** /**
* * Cast the player to a format compatible with the API.
* @param with_stats * @param {boolean} [with_stats = false] - if true, look up the player's weekly stats
* @returns updates the API's data * @returns Promise<object>
*/ */
async to_api(with_stats = false) { async to_api(with_stats = false) {
const stat = with_stats ? await this.points_for_week() : undefined const current_week = await this.sports_data.current_play_week()
const stat = with_stats ? await this.points_for_week(current_week) : undefined
return { return {
id: this.id, id: this.id,

@ -1,15 +1,18 @@
const { Model } = require('flitter-orm') const { Model } = require('flitter-orm')
/* /**
* Team Model * Team Model
* ------------------------------------------------------------- * -------------------------------------------------------------
* A model representing a single team in the game.
*
* @extends Model
*/ */
class Team extends Model { class Team extends Model {
static get services() { static get services() {
return [...super.services, 'output', 'models'] return [...super.services, 'output', 'models']
} }
/* /**
* Define the flitter-orm schema of the model. * Define the flitter-orm schema of the model.
*/ */
static get schema() { static get schema() {
@ -52,6 +55,7 @@ class Team extends Model {
/** /**
* returns the lineup * returns the lineup
* @return Promise<Lineup>
*/ */
async lineup() { async lineup() {
const Lineup = this.models.get('Lineup') const Lineup = this.models.get('Lineup')
@ -60,6 +64,7 @@ class Team extends Model {
/** /**
* Returns the players associated with the team. * Returns the players associated with the team.
* @return Promise<Array<Player>>
*/ */
async players() { async players() {
const Player = this.models.get('Player') const Player = this.models.get('Player')
@ -116,7 +121,8 @@ class Team extends Model {
} }
/** /**
* updates the API's data * Cast the team to the format expected for the API.
* @return Promise<object>
*/ */
async to_api() { async to_api() {
let user let user

@ -1,8 +1,10 @@
const { Model } = require('flitter-orm') const { Model } = require('flitter-orm')
/** /**
* WeeklyPlayerStat model * WeeklyPlayerStat model
* @extends Model
* ----------------------------------------------------------------------- * -----------------------------------------------------------------------
* A record containing the statistics for a single player for a single week.
*
* @extends Model
*/ */
class WeeklyPlayerStat extends Model { class WeeklyPlayerStat extends Model {
static get services() { static get services() {
@ -29,7 +31,8 @@ class WeeklyPlayerStat extends Model {
} }
/** /**
* updates the API's data * Cast the stats to a format expected by the API.
* @return Promise<object>
*/ */
async to_api() { async to_api() {
return { return {

@ -1,8 +1,10 @@
const { Model } = require('flitter-orm') const { Model } = require('flitter-orm')
/** /**
* Weekly Team Stat model * Weekly Team Stat model
* @extends Model
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
* A record containing the stats for a single team for a single lineup for a single week.
*
* @extends Model
*/ */
class WeeklyTeamStat extends Model { class WeeklyTeamStat extends Model {
static get services() { static get services() {

@ -17,6 +17,8 @@ const Model = require('flitter-auth/model/KeyAction')
* *
* See: module:flitter-auth/SecurityContext~SecurityContext#keyaction * See: module:flitter-auth/SecurityContext~SecurityContext#keyaction
* See: module:flitter-auth/model/KeyAction~KeyAction * See: module:flitter-auth/model/KeyAction~KeyAction
*
* This file was automatically generated by the Flitter Framework.
*/ */
class KeyAction extends Model { class KeyAction extends Model {

@ -1,9 +1,13 @@
const AuthUser = require('flitter-auth/model/User') const AuthUser = require('flitter-auth/model/User')
/* /**
* Auth user model. This inherits fields and methods from the default * Auth user model. This inherits fields and methods from the default
* flitter-auth/model/User model, however you can override methods and * flitter-auth/model/User model, however you can override methods and
* properties here as you need. * properties here as you need.
*
* This file was automatically generated by the Flitter Framework.
*
* @extends AuthUser
*/ */
class User extends AuthUser { class User extends AuthUser {
static get services() { static get services() {
@ -17,6 +21,11 @@ class User extends AuthUser {
} }
// Other members and methods here // Other members and methods here
/**
* Get the team associated with this user.
* @return {Promise<Team>}
*/
async team() { async team() {
const Team = this.models.get('Team') const Team = this.models.get('Team')
return Team.getForUser(this) return Team.getForUser(this)

@ -1,6 +1,17 @@
const Scope = require('flitter-orm/src/model/Scope') const Scope = require('flitter-orm/src/model/Scope')
/**
* This is a model scope which excludes any models without is_active = true.
* In effect, this provides a mechanism for soft-deletes.
*
* @extends Scope
*/
class ActiveScope extends Scope { class ActiveScope extends Scope {
/**
* Apply this scope's conditions to a model filter.
* @param to_filter
* @return {Promise<*>}
*/
async filter(to_filter) { async filter(to_filter) {
return to_filter.equal('is_active', true) return to_filter.equal('is_active', true)
} }

@ -7,6 +7,8 @@
* *
* Route-specific middleware should be specified in the corresponding * Route-specific middleware should be specified in the corresponding
* routes file. * routes file.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = [ const Middleware = [
"auth:Utility", "auth:Utility",

@ -1,18 +1,24 @@
const { Middleware } = require('libflitter') const { Middleware } = require('libflitter')
/* /**
* InjectUserTeam Middleware * InjectUserTeam Middleware
* ------------------------------------------------------------- * -------------------------------------------------------------
* For the authenticated user, looks up the associated Team instance * For the authenticated user, looks up the associated Team instance
* and injects it as request.team. * and injects it as request.user_team.
*
* @extends Middleware
*/ */
class InjectUserTeam extends Middleware { class InjectUserTeam extends Middleware {
static get services() { static get services() {
return [...super.services, 'models'] return [...super.services, 'models']
} }
/* /**
* Run the middleware test. * Inject the user's team into the request, or redirect to a login page.
* @param req
* @param res
* @param next
* @param [args = {}]
*/ */
async test(req, res, next, args = {}){ async test(req, res, next, args = {}){
if ( !req.user ) return res.redirect('/auth/login') if ( !req.user ) return res.redirect('/auth/login')

@ -4,6 +4,8 @@
* Allows the request to proceed unless there's an authenticated user * Allows the request to proceed unless there's an authenticated user
* in the session. If so, redirect to the auth flow destination if one * in the session. If so, redirect to the auth flow destination if one
* exists. If not, redirect to the default login route. * exists. If not, redirect to the default login route.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = require('flitter-auth/middleware/GuestOnly') const Middleware = require('flitter-auth/middleware/GuestOnly')
class GuestOnly extends Middleware { class GuestOnly extends Middleware {

@ -4,6 +4,8 @@ const Middleware = require('flitter-auth/middleware/KeyAction')
* KeyAction Middleware * KeyAction Middleware
* ------------------------------------------------------------- * -------------------------------------------------------------
* Middleware for processing key actions. * Middleware for processing key actions.
*
* This file was automatically generated by the Flitter framework.
*/ */
class KeyAction extends Middleware { class KeyAction extends Middleware {

@ -3,6 +3,8 @@
* ------------------------------------------------------------- * -------------------------------------------------------------
* Allows the request to proceed if a valid OAuth2 bearer token was * Allows the request to proceed if a valid OAuth2 bearer token was
* provided. If not, return a JSON-encoded error message. * provided. If not, return a JSON-encoded error message.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = require('flitter-auth/middleware/Oauth2TokenOnly') const Middleware = require('flitter-auth/middleware/Oauth2TokenOnly')
class Oauth2TokenOnly extends Middleware { class Oauth2TokenOnly extends Middleware {

@ -3,6 +3,8 @@
* ------------------------------------------------------------- * -------------------------------------------------------------
* Redirects the user to the login page if the registration page for * Redirects the user to the login page if the registration page for
* a particular auth provider is not enabled. * a particular auth provider is not enabled.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = require('flitter-auth/middleware/ProviderRegistrationEnabled') const Middleware = require('flitter-auth/middleware/ProviderRegistrationEnabled')
class ProviderRegistrationEnabled extends Middleware { class ProviderRegistrationEnabled extends Middleware {

@ -4,6 +4,8 @@
* Many auth routes specify the name of a particular auth provider to * Many auth routes specify the name of a particular auth provider to
* use. This middleware looks up the provider by that name and injects * use. This middleware looks up the provider by that name and injects
* it into the request. * it into the request.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = require('flitter-auth/middleware/ProviderRoute') const Middleware = require('flitter-auth/middleware/ProviderRoute')
class ProviderRoute extends Middleware { class ProviderRoute extends Middleware {

@ -4,6 +4,8 @@
* Allows the request to proceed if there's an authenticated user * Allows the request to proceed if there's an authenticated user
* in the session. Otherwise, redirects the user to the login page * in the session. Otherwise, redirects the user to the login page
* of the default provider. * of the default provider.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = require('flitter-auth/middleware/UserOnly') const Middleware = require('flitter-auth/middleware/UserOnly')
class UserOnly extends Middleware { class UserOnly extends Middleware {

@ -4,6 +4,8 @@
* This should be applied globally. Ensures basic things about the * This should be applied globally. Ensures basic things about the
* request are true. For example, it provides the auth session data * request are true. For example, it provides the auth session data
* and handles auth flow. * and handles auth flow.
*
* This file was automatically generated by the Flitter framework.
*/ */
const Middleware = require('flitter-auth/middleware/Utility') const Middleware = require('flitter-auth/middleware/Utility')
class Utility extends Middleware { class Utility extends Middleware {

@ -1,5 +1,7 @@
const Middleware = require('flitter-i18n/src/middleware/Localize') const Middleware = require('flitter-i18n/src/middleware/Localize')
/*
* This file was automatically generated by the Flitter framework.
*/
class LocalizeMiddleware extends Middleware { class LocalizeMiddleware extends Middleware {
} }

@ -1,5 +1,8 @@
const Middleware = require('flitter-i18n/src/middleware/Scope') const Middleware = require('flitter-i18n/src/middleware/Scope')
/*
* This file was automatically generated by the Flitter framework.
*/
class ScopeMiddleware extends Middleware { class ScopeMiddleware extends Middleware {
} }

@ -16,6 +16,8 @@ const { Middleware } = require('libflitter')
* *
* The 'value' attribute is optional. If none is provided, the request * The 'value' attribute is optional. If none is provided, the request
* can proceed if the config value is truthy. * can proceed if the config value is truthy.
*
* This file was automatically generated by the Flitter framework.
*/ */
class Config extends Middleware { class Config extends Middleware {
static get services() { static get services() {

@ -47,15 +47,25 @@ const index = {
'controller::Home.welcome' 'controller::Home.welcome'
], ],
// Get information about the user's team
'/my-team': ['controller::Teams.get_my_team'], '/my-team': ['controller::Teams.get_my_team'],
// Get a list of the user's team's players
'/my-team/players': ['controller::Teams.get_my_team_players'], '/my-team/players': ['controller::Teams.get_my_team_players'],
// Get the uesr's team's current lineup
'/my-team/lineup': ['controller::Teams.get_my_team_current_lineup'], '/my-team/lineup': ['controller::Teams.get_my_team_current_lineup'],
// Get a list of players available to be drafted
'/draft-board/available': ['controller::DraftBoard.get_available_players'], '/draft-board/available': ['controller::DraftBoard.get_available_players'],
// Get a list of matchup, grouped by week number
'/matchups': ['controller::Scores.get_weekly_scores'], '/matchups': ['controller::Scores.get_weekly_scores'],
// Get the current league standings
'/league-standings': ['controller::Scores.get_league_standings'], '/league-standings': ['controller::Scores.get_league_standings'],
// Get the status of the current user's session, and game play
'/status': ['controller::Home.get_status'], '/status': ['controller::Home.get_status'],
}, },
@ -67,9 +77,13 @@ const index = {
* or middleware that are applied in order. * or middleware that are applied in order.
*/ */
post: { post: {
// Save changes to the current user's team
'/my-team': ['controller::Teams.save_my_team'], '/my-team': ['controller::Teams.save_my_team'],
// Save the current user's team's lineup
'/my-team/lineup': ['controller::Teams.save_my_team_lineup'], '/my-team/lineup': ['controller::Teams.save_my_team_lineup'],
// Draft the given player to the current user's team
'/draft-board/draft-player': ['controller::DraftBoard.draft_player_to_team'], '/draft-board/draft-player': ['controller::DraftBoard.draft_player_to_team'],
}, },

@ -13,6 +13,8 @@
* You can omit the provider name to use the default provider: * You can omit the provider name to use the default provider:
* *
* /auth/register * /auth/register
*
* This file was automatically generated by the Flitter framework.
*/ */
const index = { const index = {

@ -1,3 +1,7 @@
/*
* This file was automatically generated by the Flitter framework.
*/
module.exports = exports = { module.exports = exports = {
prefix: '/auth/action', // This is assumed by flitter-auth. Don't change it. prefix: '/auth/action', // This is assumed by flitter-auth. Don't change it.
middleware: [], middleware: [],

@ -2,6 +2,8 @@
* oauth2 Routes * oauth2 Routes
* ------------------------------------------------------------- * -------------------------------------------------------------
* Routes pertaining to the flitter-auth OAuth2 server implementation. * Routes pertaining to the flitter-auth OAuth2 server implementation.
*
* This file was automatically generated by the Flitter framework.
*/ */
const oauth2 = { const oauth2 = {

@ -3,6 +3,8 @@
* ------------------------------------------------------------- * -------------------------------------------------------------
* This is a sample routes file. Routes and their handlers should be * This is a sample routes file. Routes and their handlers should be
* defined here, but no logic should occur. * defined here, but no logic should occur.
*
* This file was automatically generated by the Flitter framework.
*/ */
const index = { const index = {
@ -47,24 +49,7 @@ const index = {
// Placeholder for auth dashboard. You'd replace this with // Placeholder for auth dashboard. You'd replace this with
// your own route protected by 'middleware::auth:UserOnly' // your own route protected by 'middleware::auth:UserOnly'
'/dash': [ 'controller::Home.welcome' ], '/dash': ['controller::Home.welcome'],
'/api/list-all-teams': [
'controller::Teams.list_all_teams'
],
},
/*
* Define POST routes.
* These routes are registered as POST methods.
* Handlers for these routes should be specified as
* an array of canonical references to controller methods
* or middleware that are applied in order.
*/
post: {
'/api/create-team': [
'controller::Teams.create_team'
],
}, },
// You can include other HTTP verbs here. // You can include other HTTP verbs here.

@ -3,39 +3,74 @@ const axios = require('axios').default;
/** /**
* A service class for interacting with data from the SportsDataIO API. * A service class for interacting with data from the SportsDataIO API.
* @extends Service
*/ */
class SportsDataService extends Service { class SportsDataService extends Service {
static get services() { static get services() {
return [...super.services, 'configs', 'models', 'utility'] return [...super.services, 'configs', 'models', 'utility']
} }
/**
* Resolves true if the game is currently in the draft stage.
* @return {Promise<boolean>}
*/
async is_draft_stage() { async is_draft_stage() {
const Setting = this.models.get('models::setting') const Setting = this.models.get('models::setting')
return this.utility.infer(await Setting.get('in_draft_stage')) return this.utility.infer(await Setting.get('in_draft_stage'))
} }
/**
* Resolves to the current week number of gameplay.
* @return {Promise<number>}
*/
async current_play_week() { async current_play_week() {
const Setting = this.models.get('models::setting') const Setting = this.models.get('models::setting')
return this.utility.infer(await Setting.get('current_week')) return this.utility.infer(await Setting.get('current_week'))
} }
/**
* Fetches a list of all players on the given team from the sports data API.
* @param {string} team_key
* @return {Promise<Array<any>>}
*/
async get_team_players(team_key) { async get_team_players(team_key) {
return this.get_request(`Players/${team_key}`) return this.get_request(`Players/${team_key}`)
} }
/**
* Fetches a list of all active teams from the sports data API.
* @return {Promise<Array<any>>}
*/
async get_active_teams() { async get_active_teams() {
return this.get_request('Teams') return this.get_request('Teams')
} }
/**
* Make a get request to the sports data API.
* @param {string} path
* @param {string} [base = 'scores'] - the API domain (scores, projections, &c.)
* @return {Promise<any>}
*/
async get_request(path, base = 'scores') { async get_request(path, base = 'scores') {
const response = await axios.get(this.url(path, base)) const response = await axios.get(this.url(path, base))
return response.data return response.data
} }
/**
* Fetches a list of player stats for all players in the league for the given week.
* @param {number} week_num
* @return {Promise<Array<any>>>}
*/
async get_week_player_stats(week_num) { async get_week_player_stats(week_num) {
return this.get_request(`PlayerGameProjectionStatsByWeek/${this.configs.get('server.sports_data.season')}/${week_num}`, 'projections') return this.get_request(`PlayerGameProjectionStatsByWeek/${this.configs.get('server.sports_data.season')}/${week_num}`, 'projections')
} }
/**
* Resolve an endpoint and an API domain to a fully-qualified URL to the sports data API.
* @param {string} path
* @param {string} [base = 'scores'] - the API domain (scores, projections, &c.)
* @return {string}
*/
url(path, base = 'scores') { url(path, base = 'scores') {
if ( path.startsWith('/') ) path = path.slice(1) if ( path.startsWith('/') ) path = path.slice(1)
return `https://api.sportsdata.io/v3/nfl/${base}/json/${path}?key=${this.configs.get('server.sports_data.api_key')}` return `https://api.sportsdata.io/v3/nfl/${base}/json/${path}?key=${this.configs.get('server.sports_data.api_key')}`

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
html html
head head
title #{title} | #{_app.name} title #{title} | #{_app.name}

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends ./auth_page extends ./auth_page
block content block content

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends ./auth_page extends ./auth_page
block content block content

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends ./form extends ./form
block form block form

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends ./auth_page extends ./auth_page
block content block content

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends ./form extends ./form
block form block form

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends error extends error
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends error extends error
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends error extends error
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends error extends error
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends error extends error
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
extends error extends error
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
html html
head head
title Uh-Oh! | #{_app ? _app.name : 'Flitter'} title Uh-Oh! | #{_app ? _app.name : 'Flitter'}

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
html html
head head
block head block head

@ -1,3 +1,4 @@
// this file was automatically generated by the Flitter framework
html html
head head
title #{T('welcome')} | #{_app.name} title #{T('welcome')} | #{_app.name}

@ -1,3 +1,6 @@
/*
* This file was automatically generated by the Flitter framework.
*/
const app_config = { const app_config = {
/* /*

@ -1,3 +1,6 @@
/*
* This file was automatically generated by the Flitter framework.
*/
const auth_config = { const auth_config = {
default_provider: env('AUTH_DEFAULT_PROVIDER', 'flitter'), default_provider: env('AUTH_DEFAULT_PROVIDER', 'flitter'),

@ -1,3 +1,6 @@
/*
* This file was automatically generated by the Flitter framework.
*/
const database_config = { const database_config = {
/* /*

@ -1,3 +1,6 @@
/*
* This file was automatically generated by the Flitter framework.
*/
const server_config = { const server_config = {
/* /*
@ -20,8 +23,14 @@ const server_config = {
*/ */
frontend_path: env('FRONT_END_PATH', 'frontend'), frontend_path: env('FRONT_END_PATH', 'frontend'),
/*
* Configuration for interacting with the SportsData.io API.
*/
sports_data: { sports_data: {
// The API key which can access the NFL API.
api_key: env('SPORTSDATA_API_KEY'), api_key: env('SPORTSDATA_API_KEY'),
// The default season to make requests for.
season: env('SPORTSDATA_SEASON', '2020REG'), season: env('SPORTSDATA_SEASON', '2020REG'),
}, },

@ -1,11 +1,16 @@
/*
* Configuration specifying the default values for database-driven
* game play settings.
*/
const settings_config = { const settings_config = {
default_settings: [ default_settings: [
{ {
// True if the game is in the draft stage.
key: 'in_draft_stage', key: 'in_draft_stage',
value: true, value: true,
}, },
{ {
// The current week in the fantasy season
key: 'current_week', key: 'current_week',
value: 1, value: 1,
}, },

@ -1,7 +0,0 @@
Flitter-Flap is an experimental code migration tool. It's goal is to write migrations for your codebase itself. That way, when core libraries like Flitter are updated, breaking changes can be accounted for in the migrations.
It's still a work in progress, so use it with caution. Try `node flitter flap` to get started. Migrations are provided by library packages. Each library package gets its own `.json` file in this directory to keep track of the migrations that have been applied.
Unless you really know what you're doing, you shouldn't modify these files. Otherwise, Flap might try to migrate something twice, or skip a migration.
https://flitter.garrettmills.dev/tutorial-getting-started-6.html

@ -1,12 +0,0 @@
[
{
"id": 1566420176,
"name": "add_ssl_to_server_config",
"migratedOn": "2019-09-01T23:27:50.764Z"
},
{
"id": 1567371806,
"name": "use_new_env_fetch_function",
"migratedOn": "2019-09-01T23:55:55.366Z"
}
]

@ -1,12 +0,0 @@
[
{
"id": 1565741502,
"name": "convert_to_new_model_schema_definitions",
"migratedOn": "2019-09-01T23:27:50.802Z"
},
{
"id": 1567373786,
"name": "add_graphql_unit_to_units_file",
"migratedOn": "2019-09-01T23:56:19.038Z"
}
]

@ -1,7 +0,0 @@
[
{
"id": 1560988609,
"name": "move_database_unit_before_express_unit",
"migratedOn": "2019-09-01T23:27:50.805Z"
}
]

@ -1,7 +0,0 @@
[
{
"id": 1555000000,
"name": "create_flaps_json_file",
"migratedOn": "2019-09-01T23:27:50.820Z"
}
]

@ -1,7 +0,0 @@
[
{
"id": 1565925593,
"name": "make_existing_middleware_extend_base_class",
"migratedOn": "2019-09-01T23:27:50.814Z"
}
]

@ -1,7 +0,0 @@
[
{
"id": 1556469759,
"name": "create_docker_env_file",
"migratedOn": "2019-09-01T23:27:50.785Z"
}
]

@ -1,7 +0,0 @@
[
{
"id": 1555611659,
"name": "move_views_dir_inside_app_dir",
"migratedOn": "2019-09-01T23:27:50.811Z"
}
]

@ -1,5 +1,6 @@
/* /*
* Translation phrases common among all locales. * Translation phrases common among all locales.
* This page was automatically generated by the Flitter framework.
*/ */
module.exports = exports = { module.exports = exports = {
flitter: 'Flitter', flitter: 'Flitter',

@ -1,5 +1,6 @@
/* /*
* Common phrases. Used by the welcome page. * Common phrases. Used by the welcome page.
* This page was automatically generated by the Flitter framework.
*/ */
module.exports = exports = { module.exports = exports = {
welcome: 'Welcome', welcome: 'Welcome',

@ -1,5 +1,6 @@
/* /*
* Common phrases. Used by the welcome page. * Common phrases. Used by the welcome page.
* This page was automatically generated by the Flitter framework.
*/ */
module.exports = exports = { module.exports = exports = {
welcome: 'Bienvenido', welcome: 'Bienvenido',

@ -1,6 +1,10 @@
const SeedAPIData = require('./app/SeedAPIData.patch') const SeedAPIData = require('./app/SeedAPIData.patch')
const SeedWeeklyPlayerData = require('./app/SeedWeeklyPlayerData.patch') const SeedWeeklyPlayerData = require('./app/SeedWeeklyPlayerData.patch')
/**
* Helper function for seeding the initial database data.
* @type {exports}
*/
module.exports = exports = async function(di) { module.exports = exports = async function(di) {
const api_patch = di.make(SeedAPIData) const api_patch = di.make(SeedAPIData)
await api_patch.run() await api_patch.run()

Loading…
Cancel
Save