@cyc-seattle/platform 1.31.0 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -107,9 +107,11 @@ GitHub environment that holds its identity and state bucket:
107
107
  | Run by hand, from a branch | `ci`, then `dev` |
108
108
  | Run by hand, from `main` | `prod-preview`, then `prod` |
109
109
 
110
- Dev is shared, so only the merge queue deploys to it, one PR at a time (#69, #80). The queue
111
- requires `dev-passed`, so a PR merges only once its dev deploy and the integration tests pass, and
112
- `main` gets the exact commit the queue tested. A queued PR of only docs or CI skips `dev`. To try a
110
+ Dev is shared, so only the merge queue deploys to it (#69, #80). PRs queued together deploy and
111
+ test as one batch: each queued PR's run skips dev when a newer PR is queued behind it, and the newest
112
+ tests them all. The queue requires `dev-passed`, so a batch merges only once its dev deploy and the
113
+ integration tests pass, and `main` gets the exact commit the queue tested, in one push. If the
114
+ newest PR fails, the queue drops it and the rest of the batch deploys without it. A queued PR of only docs or CI skips `dev`. To try a
113
115
  branch on dev before queueing it, run `gh workflow run pull-request.yml --ref <branch>`.
114
116
 
115
117
  `prod-preview` runs `mise run preview` as `deploy-runner` and writes the diff to the job summary.
@@ -7,7 +7,7 @@ export function scheduleActivities(ctx) {
7
7
  const trips = new Map(ctx.data.plan_trips.map((t) => [t.id, t]));
8
8
  const closed = new Map();
9
9
  for (const c of ctx.data.plan_closed_dates ?? []) {
10
- // The club's closed days are the Operations Plan's, not an area's.
10
+ // The closed days are the Operations Plan's, not an area's.
11
11
  if (ctx.planOfVersion.get(c.version_id)?.kind === "program_area") {
12
12
  ctx.warn("closed_date_in_area_plan", `${c.name} is a closed day in a program area's plan, so it's ignored`, c.key);
13
13
  continue;
@@ -32,7 +32,7 @@ export function scheduleActivities(ctx) {
32
32
  const span = start !== null && end !== null ? end - start : 0;
33
33
  const closedFor = closed.get(activity.date);
34
34
  if (closedFor !== undefined && activity.kind !== "travel") {
35
- ctx.warn("closed_date", `${offering.name} has an activity on ${activity.date}, when the club is closed for ${closedFor}`, activity.key);
35
+ ctx.warn("closed_date", `${offering.name} has an activity on ${activity.date}, a closed day: ${closedFor}`, activity.key);
36
36
  }
37
37
  const usesBoats = activity.kind !== "travel" && activity.uses_boats;
38
38
  result.push({
@@ -66,14 +66,6 @@ function checkAreas(ctx) {
66
66
  ctx.warn("offering_in_wrong_plan", `Offering ${offering.name} of ${product.name} is in ${where}`, offering.key);
67
67
  }
68
68
  }
69
- const operations = new Set(ctx.data.plan_versions.filter((v) => ctx.planOfVersion.get(v.id)?.kind === "operations").map((v) => v.id));
70
- for (const version of ctx.data.plan_versions) {
71
- const pinned = version.operations_version_id;
72
- if (pinned == null || operations.size === 0 || operations.has(pinned))
73
- continue;
74
- const area = ctx.areas.get(ctx.planOfVersion.get(version.id)?.program_area_id ?? "");
75
- ctx.warn("other_operations_version", `${area?.name ?? "A program area"}'s plan was saved with a different Operations Plan version from the one it's calculated with`, version.id);
76
- }
77
69
  }
78
70
  /** Each salaried position's year: its salary, where its hours went, and its hourly wages and bonus. */
79
71
  function summarizePositions(ctx, coaching, charged, bonuses, doubleBooked) {
@@ -23,7 +23,7 @@ export interface Product {
23
23
  /** Every program has one; merchandise, storage and charters have none. */
24
24
  program_area_id: Id | null;
25
25
  }
26
- /** A part of the club's programs, such as Summer, with its revenue account. */
26
+ /** A part of the organization's programs, such as Summer, with its revenue account. */
27
27
  export interface ProgramArea {
28
28
  id: Id;
29
29
  name: string;
@@ -83,8 +83,6 @@ export interface Plan {
83
83
  export interface PlanVersion {
84
84
  id: Id;
85
85
  plan_id: Id;
86
- /** A saved area plan's: the Operations Plan version it was saved with. */
87
- operations_version_id?: Id | null;
88
86
  }
89
87
  export type ActivityKind = "practice" | "regatta" | "clinic" | "travel";
90
88
  export interface PlanOffering extends Versioned {
@@ -265,7 +263,7 @@ export interface PlanRevenueCharge extends Versioned {
265
263
  excluded_from_mtdc: boolean;
266
264
  note: string | null;
267
265
  }
268
- /** A day the club is closed, such as Labor Day. */
266
+ /** A day the organization is closed, such as Labor Day. */
269
267
  export interface PlanClosedDate extends Versioned {
270
268
  date: DateString;
271
269
  name: string;
@@ -3,6 +3,7 @@ export interface Schema {
3
3
  accounts: Accounts[];
4
4
  audit_findings: AuditFindings[];
5
5
  boat_classes: BoatClasses[];
6
+ catalog_offerings: CatalogOfferings[];
6
7
  clubspot_camps: ClubspotCamps[];
7
8
  clubspot_classes: ClubspotClasses[];
8
9
  clubspot_custom_field_definitions: ClubspotCustomFieldDefinitions[];
@@ -27,7 +28,6 @@ export interface Schema {
27
28
  organization_cost_accounts: OrganizationCostAccounts[];
28
29
  organizations: Organizations[];
29
30
  people: People[];
30
- plan_activations: PlanActivations[];
31
31
  plan_activities: PlanActivities[];
32
32
  plan_activity_block_rules: PlanActivityBlockRules[];
33
33
  plan_activity_resources: PlanActivityResources[];
@@ -45,7 +45,6 @@ export interface Schema {
45
45
  plan_result_lines: PlanResultLines[];
46
46
  plan_result_pnl: PlanResultPnl[];
47
47
  plan_result_positions: PlanResultPositions[];
48
- plan_result_versions: PlanResultVersions[];
49
48
  plan_result_warnings: PlanResultWarnings[];
50
49
  plan_results: PlanResults[];
51
50
  plan_revenue_charges: PlanRevenueCharges[];
@@ -67,6 +66,7 @@ export interface Schema {
67
66
  resource_kinds: ResourceKinds[];
68
67
  sync_runs: SyncRuns[];
69
68
  sync_tasks: SyncTasks[];
69
+ version_set_activations: VersionSetActivations[];
70
70
  version_set_members: VersionSetMembers[];
71
71
  version_sets: VersionSets[];
72
72
  }
@@ -109,6 +109,14 @@ export interface BoatClasses {
109
109
  /** Dry-storage area one boat takes. */
110
110
  footprint_sq_ft: string | null;
111
111
  }
112
+ /** An offering of a program that plans and Clubspot both point to, such as "J-Pod · fall practices" or "Summer camp · week 3". Each Financial Plan sets its own price, schedule, and size for it, and Clubspot's offerings are linked to it. */
113
+ export interface CatalogOfferings {
114
+ id: string;
115
+ /** The program it's an offering of. */
116
+ program_id: string | Programs;
117
+ /** Which offering of the program, such as "fall practices" or "week 3". */
118
+ name: string;
119
+ }
112
120
  /** A dated event, such as a season's race team. Copied from Clubspot, so edit it there. */
113
121
  export interface ClubspotCamps {
114
122
  /** Clubspot's own ID for this row. */
@@ -435,18 +443,6 @@ export interface People {
435
443
  /** The person's own Directus login, if they have one. Usually empty. */
436
444
  directus_user_id: string | null;
437
445
  }
438
- /** Each time a saved version was made active. A plan's newest activation is its active version. */
439
- export interface PlanActivations {
440
- id: string;
441
- plan_id: string | Plans;
442
- /** A saved version of the plan. */
443
- version_id: string | PlanVersions;
444
- /** Set when the version is made active. */
445
- activated_at: string;
446
- activated_by: string | null;
447
- /** Set when the version is made active. The plan's active version is the one with the highest. */
448
- sequence: number;
449
- }
450
446
  /** One dated activity, such as a practice, a regatta day, or a travel day. */
451
447
  export interface PlanActivities {
452
448
  id: string;
@@ -551,7 +547,7 @@ export interface PlanBudgetLines {
551
547
  account_id: string | Accounts;
552
548
  function: "program" | "management" | "fundraising" | null;
553
549
  cost_center_type: "offering" | "product" | "program_area" | "pool" | "org";
554
- /** Who the cost is charged to: copy the Key from an offering or a pool, or a product's ID from the end of its page's web address. Leave empty for the whole club. */
550
+ /** Who the cost is charged to: copy the Key from an offering or a pool, or a product's ID from the end of its page's web address. Leave empty for the whole organization. */
555
551
  cost_center_key: string | null;
556
552
  /** In cents: 12500 is $125.00. */
557
553
  amount_cents: number;
@@ -560,7 +556,7 @@ export interface PlanBudgetLines {
560
556
  excluded_from_mtdc: boolean;
561
557
  note: string | null;
562
558
  }
563
- /** A day the club is closed, such as Labor Day. The P&L warns about an activity on one. */
559
+ /** A day the organization is closed, such as Labor Day. The P&L warns about an activity on one. */
564
560
  export interface PlanClosedDates {
565
561
  id: string;
566
562
  /** The version this row belongs to. */
@@ -580,7 +576,7 @@ export interface PlanLaborLines {
580
576
  key: string;
581
577
  name: string;
582
578
  cost_center_type: "offering" | "product" | "program_area" | "pool" | "org";
583
- /** Who the cost is charged to: copy the Key from an offering or a pool, or a product's ID from the end of its page's web address. Leave empty for the whole club. */
579
+ /** Who the cost is charged to: copy the Key from an offering or a pool, or a product's ID from the end of its page's web address. Leave empty for the whole organization. */
584
580
  cost_center_key: string | null;
585
581
  /** Who does the work: copy the Key from a staff level in the Operations Plan. */
586
582
  staff_level_key: string;
@@ -609,6 +605,8 @@ export interface PlanOfferings {
609
605
  /** Stays the same across versions. Copy it where another row asks for this one's Key. */
610
606
  key: string;
611
607
  product_id: string | Products;
608
+ /** Which of the program's catalog offerings this is, such as "J-Pod · fall practices". It's how Clubspot's sign-ups find it, in every Financial Plan. */
609
+ catalog_offering_id: string | CatalogOfferings | null;
612
610
  name: string;
613
611
  season_term: string | null;
614
612
  starts_on: string;
@@ -651,7 +649,7 @@ export interface PlanPools {
651
649
  key: string;
652
650
  name: string;
653
651
  }
654
- /** The year's rates. One row at most in each version. */
652
+ /** The year's rates. One row at most in each copy. */
655
653
  export interface PlanRates {
656
654
  id: string;
657
655
  /** The version this row belongs to. */
@@ -688,11 +686,9 @@ export interface PlanResources {
688
686
  /** Set for a rental, whose cost is left out of modified total direct costs (MTDC). */
689
687
  excluded_from_mtdc: boolean;
690
688
  }
691
- /** Each cost and revenue line in a saved version's P&L. Worked out when the version was saved, and never changed. */
689
+ /** Each cost and revenue line in a saved Financial Plan's P&L. Worked out when it was saved, and never changed. */
692
690
  export interface PlanResultLines {
693
691
  id: string;
694
- /** The saved version these results are for, if they aren't a club plan's. */
695
- version_id: string | PlanVersions | null;
696
692
  cost_center_type: "offering" | "product" | "program_area" | "pool" | "org";
697
693
  cost_center_key: string | null;
698
694
  cost_center_name: string;
@@ -703,18 +699,16 @@ export interface PlanResultLines {
703
699
  /** The engine's key for the line. */
704
700
  line: string;
705
701
  explanation: string | null;
706
- /** The club plan these results are for, if they aren't a version's. */
707
- version_set_id: string | VersionSets | null;
708
- /** In a club plan's results, the plan that holds what it's charged to. */
702
+ /** The Financial Plan these results are for. */
703
+ version_set_id: string | VersionSets;
704
+ /** The plan in the Financial Plan that holds what it's charged to. */
709
705
  version_set_member_id: string | VersionSetMembers | null;
710
706
  /** What the line is, in plain words, such as G&A share: Payroll tax. */
711
707
  line_name: string | null;
712
708
  }
713
- /** A saved version's P&L for each offering, product, and program area. Worked out when the version was saved, and never changed. */
709
+ /** A saved Financial Plan's P&L for each offering, product, and program area. Worked out when it was saved, and never changed. */
714
710
  export interface PlanResultPnl {
715
711
  id: string;
716
- /** The saved version these results are for, if they aren't a club plan's. */
717
- version_id: string | PlanVersions | null;
718
712
  level: "offering" | "product" | "program_area";
719
713
  subject_key: string;
720
714
  name: string;
@@ -729,16 +723,14 @@ export interface PlanResultPnl {
729
723
  enrollment: number;
730
724
  days: number;
731
725
  sailor_days: number;
732
- /** The club plan these results are for, if they aren't a version's. */
733
- version_set_id: string | VersionSets | null;
734
- /** In a club plan's results, the plan that holds what it's charged to. */
726
+ /** The Financial Plan these results are for. */
727
+ version_set_id: string | VersionSets;
728
+ /** The plan in the Financial Plan that holds what it's charged to. */
735
729
  version_set_member_id: string | VersionSetMembers | null;
736
730
  }
737
- /** Each salaried position's pay for the year, in a saved version. Worked out when the version was saved, and never changed. */
731
+ /** Each salaried position's pay for the year, in a saved Financial Plan. Worked out when it was saved, and never changed. */
738
732
  export interface PlanResultPositions {
739
733
  id: string;
740
- /** The saved version these results are for, if they aren't a club plan's. */
741
- version_id: string | PlanVersions | null;
742
734
  position_key: string;
743
735
  name: string;
744
736
  /** In cents: 12500 is $125.00. */
@@ -758,38 +750,26 @@ export interface PlanResultPositions {
758
750
  total_pay_cents: number;
759
751
  /** The year's payroll tax on the total pay. In cents: 12500 is $125.00. */
760
752
  payroll_tax_cents: number;
761
- /** The club plan these results are for, if they aren't a version's. */
762
- version_set_id: string | VersionSets | null;
753
+ /** The Financial Plan these results are for. */
754
+ version_set_id: string | VersionSets;
763
755
  /** Hours another coach would cover while this position coaches two or more groups at once: for three groups at once, two coaches. */
764
756
  double_booked_hours: string | null;
765
757
  /** Dates this position coaches two or more groups at once. */
766
758
  double_booked_dates: number | null;
767
759
  }
768
- /** The other saved versions a version's results were worked out with. Worked out when the version was saved, and never changed. */
769
- export interface PlanResultVersions {
770
- id: string;
771
- /** The saved version these results are for. */
772
- version_id: string | PlanVersions;
773
- /** Another saved version in the club's plan when this one was saved. */
774
- calculated_with_id: string | PlanVersions;
775
- }
776
- /** What the P&L warned about when a version was saved. Worked out when the version was saved, and never changed. */
760
+ /** What the P&L warned about when a Financial Plan was saved. Worked out when it was saved, and never changed. */
777
761
  export interface PlanResultWarnings {
778
762
  id: string;
779
- /** The saved version these results are for, if they aren't a club plan's. */
780
- version_id: string | PlanVersions | null;
781
763
  /** The kind of warning. */
782
764
  code: string;
783
765
  message: string;
784
766
  subject_key: string | null;
785
- /** The club plan these results are for, if they aren't a version's. */
786
- version_set_id: string | VersionSets | null;
767
+ /** The Financial Plan these results are for. */
768
+ version_set_id: string | VersionSets;
787
769
  }
788
- /** A saved version's club-wide totals. Worked out when the version was saved, and never changed. */
770
+ /** A saved Financial Plan's totals for the organization. Worked out when it was saved, and never changed. */
789
771
  export interface PlanResults {
790
772
  id: string;
791
- /** The saved version these results are for, if they aren't a club plan's. */
792
- version_id: string | PlanVersions | null;
793
773
  calculated_at: string;
794
774
  /** In cents: 12500 is $125.00. */
795
775
  operating_revenue_cents: number;
@@ -807,8 +787,8 @@ export interface PlanResults {
807
787
  capital_cents: number;
808
788
  /** Operating net, plus fundraising net, less capital. In cents: 12500 is $125.00. */
809
789
  total_cents: number;
810
- /** The club plan these results are for, if they aren't a version's. */
811
- version_set_id: string | VersionSets | null;
790
+ /** The Financial Plan these results are for. */
791
+ version_set_id: string | VersionSets;
812
792
  }
813
793
  /** A charge set as a share of each offering's revenue, such as scholarships or card fees. Operations Plan only. */
814
794
  export interface PlanRevenueCharges {
@@ -892,43 +872,39 @@ export interface PlanTrips {
892
872
  airfare_cents: number | null;
893
873
  miles: number | null;
894
874
  }
895
- /** A plan's draft, or a version saved from it, which never changes. */
875
+ /** One plan's copy in one Financial Plan, with every row it holds. It's saved with its Financial Plan, and then never changes. */
896
876
  export interface PlanVersions {
897
877
  id: string;
898
878
  plan_id: string | Plans;
899
- /** The saved version this draft started from. */
879
+ /** The copy this one was made from, in the Financial Plan this one's started from. */
900
880
  parent_version_id: string | PlanVersions | null;
901
- /** Saving a draft sets this to saved. A saved version never changes, even for an admin. */
881
+ /** Saved with its Financial Plan. A saved copy never changes, even for an admin. */
902
882
  status: "draft" | "saved";
903
883
  /** What changed in this version. */
904
884
  message: string | null;
905
- /** Set when the version is saved. */
885
+ /** Set when its Financial Plan is saved. */
906
886
  saved_by: string | null;
907
- /** Set when the version is saved. */
887
+ /** Set when its Financial Plan is saved. */
908
888
  saved_at: string | null;
909
889
  /** The version of the planning engine that calculated its numbers. Required to save. */
910
890
  platform_version: string | null;
911
- /** For a program area's plan: the saved Operations Plan version its numbers were calculated with, for the same organization and year. Required to save. Empty for the Operations Plan. */
912
- operations_version_id: string | PlanVersions | null;
913
891
  /** What you want that the plan's numbers don't capture, for your AI to fill in. For example: every Monday, Wednesday and Friday, except on SPS school holidays, from 4pm until dusk. */
914
892
  rules: string | null;
915
- /** What the P&L showed when this version was saved, worked out a moment after it's saved. A saved version with none means working them out failed, and an admin can fill them in. */
916
- results: (string | PlanResults)[];
917
893
  }
918
- /** One part of the club's plan: a program area's plan, or the Operations Plan. */
894
+ /** One part of a Financial Plan: a program area's Program Plan, or the Operations Plan. */
919
895
  export interface Plans {
920
896
  id: string;
921
897
  kind: "program_area" | "operations";
922
898
  /** The program area the plan is for. Empty for the Operations Plan. */
923
899
  program_area_id: string | ProgramAreas | null;
924
- /** The organization the plan is for. Can't change once the plan has a saved version. */
900
+ /** The organization the plan is for. Can't change once the plan has a saved copy. */
925
901
  organization_id: string | Organizations;
926
- /** The plan year. Fiscal year N ends in calendar year N. Can't change once the plan has a saved version. */
902
+ /** The plan year. Fiscal year N ends in calendar year N. Can't change once the plan has a saved copy. */
927
903
  fiscal_year: number;
928
904
  name: string;
929
- /** A plan with a saved version can't be deleted, so archive it instead. */
905
+ /** A plan with a saved copy can't be deleted, so archive it instead. */
930
906
  archived: boolean;
931
- /** The plan's draft and saved versions. */
907
+ /** The plan's copy in each Financial Plan. */
932
908
  versions: (string | PlanVersions)[];
933
909
  }
934
910
  /** A lasting thing the club sells. A program also has a row in Programs. */
@@ -1054,33 +1030,49 @@ export interface SyncTasks {
1054
1030
  /** Set once the task has failed too many times. It keeps retrying; this flags it for staff. */
1055
1031
  needs_attention: boolean;
1056
1032
  }
1057
- /** One plan's version in a club plan. Set when the club plan is saved, and never changed. */
1033
+ /** Each time a saved Financial Plan was marked active. The newest one for an organization and year is the active one. */
1034
+ export interface VersionSetActivations {
1035
+ id: string;
1036
+ /** A saved Financial Plan. */
1037
+ version_set_id: string | VersionSets;
1038
+ /** Set when it's marked active. */
1039
+ activated_at: string | null;
1040
+ activated_by: string | null;
1041
+ /** Set when it's marked active. The active Financial Plan for a year is the one with the highest. */
1042
+ sequence: number;
1043
+ }
1044
+ /** One plan in a Financial Plan: the copy of the plan it holds. Add or remove one only while the Financial Plan is a draft. */
1058
1045
  export interface VersionSetMembers {
1059
1046
  id: string;
1060
1047
  version_set_id: string | VersionSets;
1061
- plan_id: string | Plans;
1062
- /** The plan's active version when the club plan was saved. */
1048
+ /** Filled in from the plan copy. */
1049
+ plan_id: string | Plans | null;
1050
+ /** The plan's copy in this Financial Plan. It's in no other Financial Plan. */
1063
1051
  version_id: string | PlanVersions;
1064
1052
  }
1065
- /** The club's plan for a year, saved: the active Operations Plan version and each program area's, with the P&L they make together. Saved when it's added, and never changed. */
1053
+ /** The organization's plan for a year: one Operations Plan, and a Program Plan for any of the program areas, with the P&L they make together. Change its plans while it's a draft. Saving it saves them all, and then it never changes, apart from its note. Pick a parent when you add one, and its plans are copied in. */
1066
1054
  export interface VersionSets {
1067
1055
  id: string;
1068
- /** The organization the club plan is for. */
1056
+ /** The organization the Financial Plan is for. */
1069
1057
  organization_id: string | Organizations;
1070
- /** The year the club plan is for. */
1058
+ /** The year the Financial Plan is for. */
1071
1059
  fiscal_year: number;
1072
1060
  /** Such as 2027 budget as adopted. */
1073
1061
  name: string;
1074
- /** Why it was saved. */
1062
+ /** What it was for, such as "Reviewed with the board". You can change it after it's saved. */
1075
1063
  message: string | null;
1076
- /** Set when the club plan is saved. */
1064
+ /** Set it to saved to save the Financial Plan and all its plans. A saved Financial Plan never changes, apart from its note. */
1065
+ status: "draft" | "saved";
1066
+ /** The Financial Plan this one started as a copy of. Pick it when you add this one, and its plans are copied in. */
1067
+ parent_id: string | VersionSets | null;
1068
+ /** Set when the Financial Plan is saved. */
1077
1069
  saved_by: string | null;
1078
- /** Set when the club plan is saved. */
1070
+ /** Set when the Financial Plan is saved. */
1079
1071
  saved_at: string | null;
1080
1072
  /** The version of the planning engine that calculated its numbers. */
1081
1073
  platform_version: string | null;
1082
- /** The active version of each plan when the club plan was saved. */
1074
+ /** Each plan in the Financial Plan. Add or remove one only while it's a draft. */
1083
1075
  members: (string | VersionSetMembers)[];
1084
- /** What the club's P&L showed when it was saved, worked out a moment after. A club plan with none means working them out failed, and an admin can fill them in. */
1076
+ /** What the organization's P&L showed when it was saved, worked out a moment after. A Financial Plan with none means working them out failed, and an admin can fill them in. */
1085
1077
  results: (string | PlanResults)[];
1086
1078
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyc-seattle/platform",
3
- "version": "1.31.0",
3
+ "version": "1.32.0",
4
4
  "description": "Pulumi components for CYC's shared Google Cloud platform: WebService, the platform outputs reader, and the stacks that build the platform",
5
5
  "author": "CYC Community Sailing Center",
6
6
  "license": "Apache-2.0",