feat(placements): v0.11 P5 learner placement visibility (REQ-11-005) [7/10] — wave 5-2: getMyApplication / getLearnerApplicationStatus / withdrawApplication clients (no new error classes)
CI / node (push) Has been cancelled
CI / python (push) Has been cancelled

This commit is contained in:
2026-10-21 04:41:15 +00:00
parent 809ce3bda8
commit a46ecf142a
+56
View File
@@ -51,6 +51,8 @@ import type {
ApplicationTransitionResponse,
HireTransitionRequest,
EmployerPlacementsResponse,
LearnerApplicationStatus,
MineApplication,
PlacementOverview,
} from '@nextcraft/types';
@@ -1270,6 +1272,60 @@ export async function listOwnEmployerPlacements(
});
}
// -- learner placement status (v0.11 P5, REQ-11-005, D-104/G-322) -------------------
/** GET /v1/marketplace/applications/mine?posting_id=&learner_id= —
* G-322 (binding) discovery: the status panel finds the application by
* the (posting, learner) pair — NEVER a client-persisted
* application_id. 404 = no application yet (the surface renders the
* apply CTA — honest absence). */
export async function getMyApplication(
postingId: string,
learnerId: string = MOCK_LEARNER_ID,
signal?: AbortSignal,
): Promise<MineApplication> {
return jsonFetch<MineApplication>(
`/v1/marketplace/applications/mine?posting_id=${encodeURIComponent(postingId)}&learner_id=${encodeURIComponent(learnerId)}`,
{ signal },
);
}
/** GET /v1/marketplace/applications/{application_id}?learner_id= —
* D-104: the learner's-own outcome read — current status + the full
* id-ordered timestamped history + the placement record when hired
* (one read, one truth source). 403 foreign → EngineError (the
* surface renders the honest "not your application" state from
* err.status — NO new error classes, D-110). */
export async function getLearnerApplicationStatus(
applicationId: string,
learnerId: string = MOCK_LEARNER_ID,
signal?: AbortSignal,
): Promise<LearnerApplicationStatus> {
return jsonFetch<LearnerApplicationStatus>(
`/v1/marketplace/applications/${encodeURIComponent(applicationId)}?learner_id=${encodeURIComponent(learnerId)}`,
{ signal },
);
}
/** POST /v1/marketplace/applications/{application_id}/withdraw — the
* learner's ONLY edit (D-099/D-104); terminal → 409 (the matrix
* surfaces as EngineError.status — the panel renders the honest
* terminal state, never a retry loop). */
export async function withdrawApplication(
applicationId: string,
learnerId: string = MOCK_LEARNER_ID,
signal?: AbortSignal,
): Promise<ApplicationConfirmation> {
return jsonFetch<ApplicationConfirmation>(
`/v1/marketplace/applications/${encodeURIComponent(applicationId)}/withdraw`,
{
method: 'POST',
body: JSON.stringify({ learner_id: learnerId }),
signal,
},
);
}
// -- admin placements (v0.11 P3/P4, REQ-11-003/004, D-107/D-108) --------------------
/** GET /v1/placements/admin/overview — the D-107 computation over the