Skip to content

User Service API

Current Endpoints

  • GET /healthz
  • GET /readyz
  • GET /v1
  • PUT /v1/users/{userId}/profile-snapshot
  • GET /v1/users/{userId}/profile
  • PATCH /v1/users/{userId}/profile
  • PATCH /v1/users/{userId}/teacher-profile
  • PATCH /v1/users/{userId}/student-profile
  • PATCH /v1/users/{userId}/parent-profile

Native Profile Foundation

Phase 8 user-service starts with profile read/update ownership. This is an internal /v1 foundation, not a public /api/auth/me* cutover.

Legacy evidence:

  • apps/api/src/modules/auth/auth.controller.ts:189-245 maps GET /api/auth/me, PATCH /api/auth/me/profile, and password update.
  • apps/api/src/modules/auth/auth.controller.ts:89-147 maps role-specific teacher/student/parent profile update routes.
  • apps/api/src/modules/auth/auth.service.ts:176-246 delegates current-user profile hydration and profile updates to identity data APIs.
  • apps/api/src/modules/app-data/app-data.identity-core.ts:209-258 returns full user profile with teacherProfile, studentProfile, parentProfile, safe teacherKyc, and membership summaries.
  • apps/api/src/modules/app-data/app-data.identity-core.ts:260-351 upserts teacher, student, and parent profile rows and records audit logs.
  • apps/api/src/modules/app-data/app-data.identity-core.ts:607-695 validates and updates base profile fields, with email/phone conflict checks.
  • packages/shared/src/index.ts:1027-1102 defines profileUpdateSchema, teacherProfileSchema, studentProfileSchema, and parentProfileSchema.
  • apps/api/prisma/schema.prisma:247-325 defines TeacherProfile, TeacherKyc, StudentProfile, and ParentProfile.
  • apps/web/components/account/profile-settings-client.tsx:255-556 shows current frontend loading /auth/me, then PATCHing base and role-specific profile routes.

Native contract:

  • PUT /v1/users/{userId}/profile-snapshot upserts the user-service-owned public user row from auth-service/backfill data. It stores no password hash or refresh token.
  • GET /v1/users/{userId}/profile returns a full profile view with base user fields and nullable teacherProfile, studentProfile, parentProfile, and teacherKyc.
  • PATCH /v1/users/{userId}/profile updates base profile fields with legacy-compatible validation:
    • fullName is required, trimmed, length 2-120.
    • email is optional, lowercased, max 160, unique when present.
    • empty phone becomes null; non-empty phone max 32 and unique.
    • empty avatarUrl becomes null; non-empty URL must start with http:// or https://.
  • PATCH /v1/users/{userId}/teacher-profile upserts teacher-specific profile fields.
  • PATCH /v1/users/{userId}/student-profile upserts student-specific profile fields.
  • PATCH /v1/users/{userId}/parent-profile upserts parent-specific profile fields.

Envelope:

json
{
  "success": true,
  "data": {
    "id": "usr_123",
    "accountCode": "HTA12345678",
    "email": "[email protected]",
    "fullName": "Teacher One",
    "role": "TEACHER",
    "status": "ACTIVE",
    "teacherProfile": {
      "schoolName": "THPT A",
      "subjects": ["Toán"]
    },
    "studentProfile": null,
    "parentProfile": null,
    "teacherKyc": null,
    "memberships": []
  },
  "message": "OK"
}

Database:

  • services/user-service/migrations/000002_user_profiles.sql creates users, teacher_profiles, student_profiles, parent_profiles, teacher_kyc, and parent_students.
  • users.legacy_id is nullable during native-only local creation and required for legacy backfill reports.
  • users.password_hash is intentionally not present; credentials remain in auth-service.
  • teacher_kyc.cccd_number_hash is present for migration/read redaction, but P8-002 does not implement submit/review APIs.

Validation queries:

sql
SELECT id, legacy_id, account_code, email, role, status
FROM users
ORDER BY created_at DESC
LIMIT 20;

SELECT user_id, school_name, subjects, updated_at
FROM teacher_profiles
ORDER BY updated_at DESC
LIMIT 20;

SELECT user_id, school_name, grade_level, updated_at
FROM student_profiles
ORDER BY updated_at DESC
LIMIT 20;

SELECT user_id, relation_to_student, updated_at
FROM parent_profiles
ORDER BY updated_at DESC
LIMIT 20;

Rollback for this native slice:

  • Keep /api/auth/me* routed to legacy.
  • Disable gateway/auth-service callers for /v1/users/*/profile*.
  • Drop user-service local profile tables with the migration down step if local test data must be reset.

Non-goals for P8-002:

  • Password changes and refresh-token rotation.
  • Teacher KYC submit/review.
  • Email change/verification.
  • Parent-student linking APIs.
  • School-service membership validation and organization management.
  • Public gateway adapter/cutover for /api/auth/me*.

Go-platform documentation is generated from repository Markdown.