Skip to content

organization-service Agent Tasks

Agent workflow: follow README.md for Audit -> Investigate -> Code -> Test -> Fix; keep this pack's writable scope and verification commands authoritative.

Dispatch type: per-service

Dispatch ID: SVC-005

Current implementation: services/school-service.

Owns: organizations, units, tenant metadata, academic-year calendar/configuration, tenant resolve/validate, and membership compatibility read models only.

Must read:

  • docs/agents/handoff-phase-8-school-organization-foundation.md
  • legacy organization modules and Prisma Organization* models.

Legacy source evidence:

  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/organizations/**
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/app-data.organizations.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/tenant/**
  • Organization, OrganizationUnit, and OrganizationMember Prisma models in /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma

Writable files:

  • services/school-service/**
  • contracts/openapi/services/school-service.yaml
  • docs/api/school-service.md
  • organization-specific route example/test files when assigned.

Orchestrator-owned files:

  • IAM membership canonicalization, default gateway route table, and shared deploy manifests unless explicitly delegated.

Delegated gateway verification scope:

  • Only when the orchestrator assigns an organization route/live/browser proof subtask, this service agent may update non-default deploy/gateway/routes.organizations-*.json examples, scripts/test/organization-*.sh, docs/qa/organization-*.md, and root Makefile test-organization-* targets.
  • Permission-bearing membership write route rehearsal remains coordinated with iam-service and api-gateway; the default gateway route table and IAM membership contracts remain orchestrator-owned. Public promotion still requires browser/runtime proof and rollback notes.

Initial tasks:

  • Use services/school-service as the current implementation alias. Alias rename/removal is orchestrator-owned and not a service-agent decision.
  • Tenant validation workflow coverage now includes admin bypass, owner and ORG_ADMIN manager checks, active teacher/student member checks, manager-required denial for teachers, suspended-member denial, and non-member denial.
  • Done: add a read-only admin roster summary owner API at GET /v1/admin/organizations/roster-summary. It reports organization/unit counts and IAM-synchronized membership read-model rows for admin dashboard/source-map adapters without adding any membership write authority to school-service.
  • Done: define the versioned student.roster.import.requested.v1 boundary in contracts/events/README.md. IAM owns account and organization-membership writes; profile-service owns student display fields; classroom-service owns local classroom membership; school-service remains a membership read model. The public student-import route stays legacy-backed until cross-service live/browser/rollback evidence exists.
  • Done: academic-year lifecycle is organization-owned in academic_years with DRAFT -> ACTIVE -> ARCHIVED transitions, one active year per organization, ISO calendar-date validation, and immutability after activation/archive. GET|POST /v1/organizations/{organizationId}/academic-years and PATCH /v1/organizations/{organizationId}/academic-years/{academicYearId} stay behind the ADMIN-only, non-default candidate table. The isolated PostgreSQL proof verifies persistence after restart, and the isolated Admin browser candidate verifies list/draft/activate through Gateway; no other service stores academic years.
  • Remove split-brain with IAM: keep schools/centers/campuses/org-unit metadata here, and make permission-bearing organization membership writes IAM-owned or explicitly read-only/deprecated compatibility.
  • Add a gateway target decision for /api/organizations/:id/members writes only after an IAM-owned adapter exists. School-service member writes stay internal IAM read-model sync routes; ordinary callers return 409 SCHOOL_MEMBERSHIP_NOT_AUTHORITATIVE.
  • Done: iam_membership_boundary_test.go explicitly proves ordinary member writes are rejected while IAM-marked sync writes return the iam-sync-read-model response marker; the existing ordering/tombstone tests remain the read-model replay contract.

Acceptance:

  • Permission-bearing organization membership writes are IAM-owned. Any school-service member write route is documented and tested as internal IAM read-model sync behavior; ordinary callers receive 409 SCHOOL_MEMBERSHIP_NOT_AUTHORITATIVE.
  • Organization membership remains outside profile-service.
  • Tenant validation never reads another service DB.
  • Gateway route rehearsals keep default routes legacy until parity evidence exists.
  • School/organization metadata APIs cannot mutate IAM roles/permissions by side effect; membership policy changes go through IAM-owned contracts.
  • Academic-year records, when implemented, are tenant-scoped organization metadata and must not be stored in classroom/course/exam databases.

Verification:

  • GOTOOLCHAIN=go1.25.11 go test ./services/school-service/...
  • make test-organization-routes
  • make test-academic-year-routes
  • make test-academic-year-route-runtime
  • make test-academic-year-postgres
  • make test-academic-year-browser

Go-platform documentation is generated from repository Markdown.