mattrguerra/meridian-ops-boardmainPrivate on GitHub, published here in full

teams.ts

Language TypeScript1.5 KB42 lines

packages/ninety-client/src/resources/teams.ts

  1. /**
  2. * Teams. GET /teams, confirmed against the live API.
  3. *
  4. * Returns a bare array of { _id, name, companyId, project, deleted }.
  5. *
  6. * No membership: there is no users, members, or userIds field, which is why
  7. * the harvest path in roster.ts is required, not a fallback. Re-check the live
  8. * response before assuming otherwise; it is cheap to check and expensive to
  9. * assume.
  10. *
  11. * Meridian has three: Leadership Team, Operations Team, All Hands.
  12. */
  13. import type { HttpClient } from './../http.js'
  14. import { RawTeamSchema, normalizeTeam, type Team } from './../types.js'
  15. export interface TeamQuery {
  16. /** Ninety models projects as teams. Excluded by default. */
  17. includeProjects?: boolean
  18. includeDeleted?: boolean
  19. }
  20. export class TeamsResource {
  21. constructor(private readonly http: HttpClient) {}
  22. async list(q: TeamQuery = {}): Promise<Team[]> {
  23. const raw = await this.http.get('/teams')
  24. if (!Array.isArray(raw)) {
  25. throw new Error(`GET /teams did not return an array (got ${typeof raw}). Shape changed; update teams.ts.`)
  26. }
  27. const teams = raw.map((t) => normalizeTeam(RawTeamSchema.parse(t)))
  28. return teams.filter(
  29. (t) => (q.includeDeleted || !t.deleted) && (q.includeProjects || !t.isProject),
  30. )
  31. }
  32. /** Name lookup for rendering, though to-dos already carry `teamName`. */
  33. async byId(): Promise<Map<string, Team>> {
  34. const teams = await this.list({ includeProjects: true, includeDeleted: true })
  35. return new Map(teams.map((t) => [t.id, t]))
  36. }
  37. }