More refactoring and integration of standards dataset database

This commit is contained in:
Dominic Ferrando
2026-07-04 14:11:13 -04:00
parent 9e1025e119
commit 01878a8e03
7 changed files with 93 additions and 57 deletions
+33 -27
View File
@@ -5,15 +5,15 @@ import {
kgToLb,
lbToKg,
range,
MetricsSchema,
type Metrics,
type ActivityPerformance,
type Player,
type StandardUnit,
} from "@blade-and-brawn/domain";
import { levenbergMarquardt as LM } from "ml-levenberg-marquardt";
import { Type, type Static } from "@sinclair/typebox";
import defaultConfig from "./default-config.json" with { type: "json" };
import defaultStandardsData from "./data/default-standards.json" with { type: "json" };
import defaultStandardsDataset from "./data/default-standards.json" with { type: "json" };
import { getAvgWeight } from "./avg-weights";
import { Value } from "@sinclair/typebox/value";
@@ -32,31 +32,37 @@ export type LevelCalculatorOutput = {
attributes: Record<Attribute, number>;
};
export type Levels = Record<string, number>;
export const LevelsSchema = Type.Record(Type.String(), Type.Number());
export type Levels = Static<typeof LevelsSchema>;
type NumberMetric = Extract<keyof Metrics, "age" | "weight">;
export interface Standard {
metrics: Metrics;
levels: Levels;
}
export const StandardSchema = Type.Object({
metrics: MetricsSchema,
levels: LevelsSchema,
});
export type Standard = Static<typeof StandardSchema>;
type Generator = {
metric: NumberMetric;
};
const GeneratorSchema = Type.Object({
metric: Type.Union([Type.Literal("age"), Type.Literal("weight")]),
});
type Generator = Static<typeof GeneratorSchema>;
export type StandardsData = Record<
Activity,
{
metadata: {
attribute: Attribute;
generators: Generator[];
unit: StandardUnit;
name: string;
};
standards: Standard[];
}
>;
const StandardUnitSchema = Type.Union([Type.Literal("ms"), Type.Literal("cm"), Type.Literal("kg")]);
export const StandardsDatasetSchema = Type.Record(
Type.Enum(Activity),
Type.Object({
metadata: Type.Object({
attribute: Type.Enum(Attribute),
generators: Type.Array(GeneratorSchema),
unit: StandardUnitSchema,
name: Type.String(),
}),
standards: Type.Array(StandardSchema),
}),
);
export type StandardsDataset = Static<typeof StandardsDatasetSchema>;
const metricPriority = (m: NumberMetric) => {
if (m === "age") return 0;
@@ -64,7 +70,7 @@ const metricPriority = (m: NumberMetric) => {
return 2;
};
export const DEFAULT_STANDARDS_DATA = defaultStandardsData as StandardsData;
export const DEFAULT_STANDARDS_DATASET = defaultStandardsDataset as StandardsDataset;
export class LevelCalculator {
readonly standards: Standards;
@@ -237,14 +243,14 @@ export type StandardsParameters = Static<typeof StandardsParametersSchema>;
export class Standards {
readonly params: StandardsParameters;
private standardsData: StandardsData;
private standardsData: StandardsDataset;
constructor(standardsData: StandardsData, params?: Partial<StandardsParameters>) {
constructor(dataset: StandardsDataset, params?: Partial<StandardsParameters>) {
Value.Assert(StandardsParametersSchema, defaultConfig);
this.params = Object.assign({}, defaultConfig, params);
// prepare data
this.standardsData = structuredClone(standardsData);
this.standardsData = structuredClone(dataset);
// STRETCH
for (const activity of Object.values(Activity)) {
@@ -765,7 +771,7 @@ export class Standards {
for (const activity of Object.keys(this.standardsData) as Activity[]) {
const standardData = this.standardsData[
activity
] as StandardsData[Activity];
] as StandardsDataset[Activity];
if (standardData.metadata.attribute === attribute) {
activities.push(activity as Activity);
}