Skip to content

Handoff: SVC-005-student-roster-import-boundary organization-service student roster import boundary

Scope

  • Service/area: organization-service implemented by services/school-service
  • Task pack: docs/agents/service-tasks/organization-service.md
  • Goal: accept the bounded SVC-005 student roster import boundary slice, keeping school-service ownership to organization/unit metadata and IAM-synchronized membership read models while student roster import remains a cross-service IAM/profile/classroom handoff.
  • Non-goals: default /api/organizations* route promotion, live/browser proof, IAM membership write implementation inside school-service, student-import public cutover, data migration/backfill, or changes to legacy source under /Users/velikho/Desktop/WORKING/HOCTAPAZ/.

Docs Read

  • go-platform/docs/architecture/service-responsibility-matrix.md
  • go-platform/docs/architecture/legacy-api-map.md
  • go-platform/docs/agents/service-agent-execution-queue.json
  • go-platform/docs/agents/service-agent-closeout-ledger.json
  • go-platform/docs/agents/service-tasks/organization-service.md
  • go-platform/docs/agents/agent-handoff-format.md
  • go-platform/docs/api/school-service.md
  • go-platform/docs/qa/service-agent-goal-completion-audit.md
  • go-platform/docs/qa/service-agent-readiness-smoke.md

Legacy Evidence Read

  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/organizations/organizations.controller.ts
  • /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/app-data/app-data.student-imports.ts
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/tenant/**
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma
  • Legacy source was read-only evidence only; no student-import or organization-member public route parity is claimed.

Files Changed

  • go-platform/docs/agents/handoffs/SVC-005-student-roster-import-boundary.md
  • go-platform/docs/agents/service-agent-closeout-ledger.json
  • go-platform/docs/agents/service-agent-closeout-ledger.md
  • go-platform/contracts/events/README.md
  • go-platform/docs/qa/organization-iam-membership-school-sync-proof.md
  • go-platform/services/school-service/internal/http/server.go
  • go-platform/services/school-service/internal/http/server_test.go
  • go-platform/services/school-service/internal/http/iam_membership_boundary_test.go
  • go-platform/services/iam-service/internal/http/server.go
  • go-platform/services/iam-service/internal/schoolsync/client.go
  • go-platform/services/iam-service/internal/schoolsync/client_test.go
  • go-platform/contracts/openapi/services/school-service.yaml
  • go-platform/services/school-service/api/openapi.yaml

Behavior Implemented

  • student.roster.import.requested.v1 now defines the cross-service handoff keys and owner sequence without adding a public route or changing school-service write authority.
  • IAM resolves/creates the account and canonical organization membership; profile-service owns student display fields; classroom-service owns local classroom membership; school-service remains an IAM membership read model.
  • Stable importJobId, rowId, and sourceEventId values provide replay protection, while accepted/rejected row reporting keeps partial retries from duplicating owner mutations.
  • School-service membership sync now requires the IAM marker plus trusted X-Internal-Service: iam-service and X-Internal-Token; marker-only and spoofed-token requests are rejected.
  • IAM school-sync publisher forwards the trusted internal headers and uses the shared token configured for the runtime.
  • Configured school-service database failures no longer silently fall back to memory outside local/test environments; readiness checks the live pool.
  • Existing audited school-service code returns SCHOOL_MEMBERSHIP_NOT_AUTHORITATIVE for ordinary member writes and supports IAM sync ordering/tombstone replay behavior for read-model updates.
  • Existing audited organization route tables keep read rehearsals non-default and route membership write rehearsals to IAM, not school-service.

Tests And Verification

  • Command: GOTOOLCHAIN=go1.25.11 go test ./services/school-service/... -count=1
  • Result: passed.
  • Evidence: school-service packages passed, including HTTP/usecase tests for ordinary member write rejection, IAM sync writes, stale replay/tombstone handling, and last-owner IAM removal.
  • Command: make test-organization-routes
  • Result: passed.
  • Evidence: default route table kept broad /api/organizations legacy; non-default read routes target school-service; non-default membership write routes target IAM.
  • Contract verification: contracts/events/README.md contains the required roster event name, owner sequence, stable replay keys, and legacy-route boundary.
  • Command: GOTOOLCHAIN=go1.25.11 go test ./services/school-service/... ./services/iam-service/internal/schoolsync -count=1
  • Result: passed, including spoofed sync-marker rejection and IAM publisher internal-header forwarding.

Route State

  • Legacy route: default /api/organizations* remains legacy-proxied, and student roster import remains legacy-proxied.
  • Native route: non-default read examples route exact organization list/detail/units/members reads to school-service; membership write examples route member POST/DELETE operations to IAM.
  • Gateway state: make test-organization-routes verifies default legacy state, route order, auth/organization guards, and IAM target for membership writes.
  • Rollback: keep deploy/gateway/routes.json as the active route table; do not promote organization member writes or student roster imports until IAM-owned account/membership writes, profile hydration, classroom membership handoff, browser/runtime proof, and rollback evidence are attached.

Data Notes

  • Tables touched: none in this handoff run; verification used package tests and route-table guards.
  • Migration run: none.
  • Validation report: not applicable because no live data was migrated or backfilled.

Risks / Blockers

  • SVC-003 IAM dependency remains open, so SVC-005 cannot be complete.
  • Student roster import crosses IAM account/membership writes, profile hydration, and classroom membership; those owner contracts are not implemented by this handoff.
  • The boundary contract is defined, but the native coordinator/owner adapters and their live/browser/rollback evidence are still not implemented.
  • No default route promotion, live/browser proof, rollback proof, or data validation exists for organization member writes or student roster imports.
  • School-service must not become the permission-bearing organization membership owner.

Next Step

  • Implement the coordinator and owner adapters behind a non-default rehearsal, then add live/browser/rollback proof before considering student-import route promotion.

Go-platform documentation is generated from repository Markdown.