Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jeffn/cohort plans #26

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions .github/workflows/supabase-pull-request.yml

This file was deleted.

17 changes: 9 additions & 8 deletions src/api/ceCohortService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ class CECohortService extends EntityService<Cohort> {
async create(): Promise<Cohort> {
return studentService.findUnenrolled()
.then(students => {
return cohortService.insert(
{
id: uuidv4(),
name: `(New) Cohort`,
} as Cohort
)
return cohortService
.insert(
{
id: uuidv4(),
name: `(New) Cohort`,
} as Cohort
)
.then(cohort => {
const enrollments = students.map(student => {
return {
Expand All @@ -38,9 +39,9 @@ class CECohortService extends EntityService<Cohort> {

async getById(entityId: string | number, select?: string): Promise<Cohort | null> {
try {
const cohort = await super.getById(entityId, select ?? '*, plan(*)')
const cohort = await super.getById(entityId, select ?? '*, enrollment(*), plan(*)');
console.log(cohort);
if (cohort) {
console.log(cohort)
return {
...cohort,
plans: [] // TODO join into plans
Expand Down
8 changes: 6 additions & 2 deletions src/api/ceEnrollmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ class CEEnrollmentService extends EntityService<Enrollment> {

async getStudents(cohort: Cohort): Promise<Student[]> {
return await supabaseClient
.from('enrollment')
.from(this.tableName)
.select('student(*)')
.eq('cohort_id', cohort.id)
.then(resp => resp.data as unknown as Student[]);
.then(resp => {
const objects = resp.data as unknown as any[];
return objects.map(ss => ss.student) as Student[];
});
}

}

const enrollmentService = new CEEnrollmentService('enrollment')
Expand Down
26 changes: 26 additions & 0 deletions src/api/cePlacementService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* ceCohortService.ts
*
* @copyright 2025 Digital Aid Seattle
*
*/

import { supabaseClient } from "@digitalaidseattle/supabase";
import { EntityService } from "./entityService";
import { Identifier, Placement } from "./types";


class CEPlacementService extends EntityService<Placement> {

async findByPlanId(planId: Identifier): Promise<Placement[]> {
return await supabaseClient
.from(this.tableName)
.select('*, student(*)')
.eq('plan_id', planId)
.then(resp => resp.data as Placement[]);
}
}

const placementService = new CEPlacementService('placement')
export { placementService };

145 changes: 55 additions & 90 deletions src/api/cePlanService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,104 +5,69 @@
*
*/

import { Placement, Plan } from "./types";
import { supabaseClient } from "@digitalaidseattle/supabase";
import { v4 as uuidv4 } from 'uuid';
import { placementService } from "./cePlacementService";
import { EntityService } from "./entityService";
import { Cohort, Identifier, Placement, Plan } from "./types";
import { enrollmentService } from "./ceEnrollmentService";

const TEST_PLAN = {
id: '1',
name: 'Plan1',
rating: 0,
notes: '',
cohort_id: "sess1",
placements: [
{
id: '1',
cohort_id: '1',
student_id: 's1',
student: {
id: '',
name: 'Student 1',
age: null,
email: '',
city: '',
state: '',
country: '',
availabilities: []
},
anchor: true,
availabilities: []
} ,
{
id: '2',
cohort_id: '1',
student_id: 's2',
student: {
id: '',
name: 'Student 2',
age: null,
email: '',
city: '',
state: '',
country: '',
availabilities: []
},
anchor: false,
availabilities: []
},
{
id: '3',
cohort_id: '1',
student_id: 's3',
student: {
id: '',
name: 'Student 3',
age: null,
email: '',
city: '',
state: '',
country: '',
availabilities: []
},
anchor: false,
availabilities: []
}
] as Placement[],
groups: [
{
id: undefined,
groupNo: 'Group 1',
studentIds: ['s1']
},
{
id: undefined,
groupNo: 'Group 2',
studentIds: ['s2', 's3']
},
{
id: undefined,
groupNo: 'Group 3',
studentIds: []
}
],
} as Plan;

class CEPlanService {
async getById(id: string): Promise<Plan> {
console.log("get plan", id);
return TEST_PLAN;
class CEPlanService extends EntityService<Plan> {
async create(cohort: Cohort): Promise<Plan> {
const proposed: Plan = {
id: uuidv4(),
name: 'New Plan',
note: '',
cohort_id: cohort.id
} as Plan
//
return enrollmentService.getStudents(cohort)
.then(students => {
return this.insert(proposed)
.then(plan => {
const placements = students.map(student => {
return {
plan_id: plan.id,
student_id: student.id,
anchor: false,
priority: 0
} as Placement
})
return placementService
.batchInsert(placements)
.then(createdPlacements => {
plan.placements = createdPlacements;
return plan;
})
})
});
}

async findByCohortId(cohortId: string): Promise<Plan[]> {
console.log("get plans for cohort ", cohortId);
return [TEST_PLAN]
async duplicate(plan: Plan): Promise<Plan> {
const proposed: Plan = {
id: uuidv4(),
name: plan.name + ' (copy)',
note: '',
cohort_id: plan.cohort_id
} as Plan
return this.insert(proposed)
.then(plan => {
// TODO copy placements
// TODO copy groups?
return plan;
})
}

async duplicate(plan: Plan): Promise<Plan[]> {
alert(` '${plan.name}' would be duplicated ${plan.name}`)
return [{ ...TEST_PLAN }]
async findByCohortId(cohort_id: Identifier): Promise<Plan[]> {
return await supabaseClient
.from(this.tableName)
.select('*')
.eq('cohort_id', cohort_id)
.then(resp => resp.data as Plan[]);
}

}

const planService = new CEPlanService()
const planService = new CEPlanService('plan')
export { planService };

8 changes: 4 additions & 4 deletions src/api/entityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { PageInfo, QueryModel, supabaseClient } from "@digitalaidseattle/supabase";
import { Entity } from "./types";
import { Entity, Identifier } from "./types";

abstract class EntityService<T extends Entity> {

Expand Down Expand Up @@ -88,7 +88,7 @@ abstract class EntityService<T extends Entity> {
}
}

async batchInsert(entities: T[], select?: string): Promise<T> {
async batchInsert(entities: T[], select?: string): Promise<T[]> {
try {
const { data, error } = await supabaseClient
.from(this.tableName)
Expand All @@ -98,7 +98,7 @@ abstract class EntityService<T extends Entity> {
console.error('Error inserting entity:', error.message);
throw new Error('Failed to insert entity');
}
return data as unknown as T;
return data as unknown as T[];
} catch (err) {
console.error('Unexpected error during insertion:', err);
throw err;
Expand Down Expand Up @@ -141,7 +141,7 @@ abstract class EntityService<T extends Entity> {
}
}

async delete(entityId: string): Promise<void> {
async delete(entityId: Identifier): Promise<void> {
try {
const { error } = await supabaseClient
.from(this.tableName)
Expand Down
23 changes: 14 additions & 9 deletions src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
* @copyright 2025 Digital Aid Seattle
*
*/
type Identifier = string | number;

type Entity = {
id: string | number;
id: Identifier;
}

type Availability = {
Expand Down Expand Up @@ -54,32 +56,35 @@ type Group = {
}

type Enrollment = Entity & {
cohort_id: string | number;
student_id: string | number;
cohort_id: Identifier;
student_id: Identifier;
}

type Placement = Entity & {
cohort_id: string;
student_id: string;
type Placement = Entity & {
plan_id: Identifier;
student_id: Identifier;
student: Student;
anchor: boolean;
priority: number;
availabilities: Availability[];
}

type Plan = Entity & {
name: string;
cohort_id: string;
placements: Placement[]
cohort_id: Identifier;
numberOfGroups: number;
placements: Placement[];
groups: Group[];
rating: number;
notes: string;
note: string;
}

export type {
Availability,
Enrollment,
Entity,
FailedStudent,
Identifier,
Student,
StudentField,
SelectAvailability,
Expand Down
Loading