policy->view($request->user()), 403); $request->validate([ 'mappableType' => ['required', Rule::enum(MappableType::class)], 'mappableId' => ['required', 'string'], ]); $mappings = ContentTaxonomyMapping::query() ->with('taxonomyNode.type') ->where('organization_id', $this->tenant->id()) ->where('mappable_type', $request->string('mappableType')) ->where('mappable_id', $request->string('mappableId')) ->get() ->map(fn (ContentTaxonomyMapping $mapping) => $this->payload($mapping)); return response()->json(['data' => $mappings]); } public function store(StoreContentMappingRequest $request): JsonResponse { abort_unless($this->policy->manage($request->user()), 403); $data = $request->validated(); $mapping = $this->service->create( $this->tenant->id(), $data['courseVersionId'], MappableType::from($data['mappableType']), $data['mappableId'], $data['taxonomyNodeId'], MappingType::from($data['mappingType']), $data['masteryLevel'] ?? null, (float) $data['weight'], MappingSource::from($data['source']), isset($data['confidence']) ? (float) $data['confidence'] : null, $request->user(), ); return response()->json(['data' => $this->payload($mapping->load('taxonomyNode.type'))], 201); } public function destroy(Request $request, string $mapping): JsonResponse { abort_unless($this->policy->manage($request->user()), 403); $model = ContentTaxonomyMapping::query() ->where('organization_id', $this->tenant->id()) ->findOrFail($mapping); if ($model->courseVersion->status->value === 'published') { throw ValidationException::withMessages(['courseVersionId' => ['Published course version mappings are immutable.']]); } $model->delete(); return response()->json(status: 204); } private function payload(ContentTaxonomyMapping $mapping): array { return [ 'id' => $mapping->getKey(), 'courseVersionId' => $mapping->course_version_id, 'entityType' => $mapping->mappable_type->value, 'entityId' => $mapping->mappable_id, 'mappingType' => $mapping->mapping_type->value, 'masteryLevel' => $mapping->mastery_level, 'weight' => (float) $mapping->weight, 'source' => $mapping->source->value, 'confidence' => $mapping->confidence === null ? null : (float) $mapping->confidence, 'confirmationStatus' => $mapping->confirmation_status->value, 'direct' => true, 'inheritedFrom' => null, 'taxonomyNode' => [ 'id' => $mapping->taxonomyNode->getKey(), 'name' => $mapping->taxonomyNode->name, 'code' => $mapping->taxonomyNode->code, 'type' => $mapping->taxonomyNode->type->key, ], ]; } }