-
Notifications
You must be signed in to change notification settings - Fork 0
fix(answer): dedupe and compact Also in your library cross-mode links #417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import { NextResponse } from "next/server"; | ||
|
|
||
| import { isDemoMode, isLocalNoAuthMode } from "@/lib/env"; | ||
| import { jsonError } from "@/lib/http"; | ||
| import { getMedicationRecord } from "@/lib/medication-snapshot"; | ||
| import { deriveGovernanceFromSections, normalizeMedicationSlug } from "@/lib/medication-records"; | ||
|
|
||
| export const runtime = "nodejs"; | ||
|
|
||
| function medicationResponse(payload: Record<string, unknown>, init?: { status?: number }) { | ||
| return NextResponse.json(payload, { | ||
| status: init?.status ?? 200, | ||
| headers: { "Cache-Control": "private, no-store" }, | ||
| }); | ||
| } | ||
|
|
||
| function notFoundResponse(slug: string) { | ||
| return medicationResponse({ error: `No medication found for "${slug}".` }, { status: 404 }); | ||
| } | ||
|
|
||
| function publicMedicationDetailPayload(slug: string) { | ||
| const record = getMedicationRecord(slug); | ||
| if (!record) return null; | ||
| const governance = deriveGovernanceFromSections(record); | ||
| return { | ||
| record, | ||
| governance: { | ||
| sourceStatus: governance.source_status, | ||
| validationStatus: governance.validation_status, | ||
| }, | ||
| }; | ||
| } | ||
|
|
||
| export async function GET(_request: Request, context: { params: Promise<{ slug: string }> }) { | ||
| try { | ||
| const { slug } = await context.params; | ||
| const normalizedSlug = normalizeMedicationSlug(slug); | ||
| const payload = publicMedicationDetailPayload(normalizedSlug); | ||
| if (!payload) return notFoundResponse(normalizedSlug); | ||
|
|
||
| return medicationResponse({ | ||
| ...payload, | ||
| demoMode: isDemoMode() || isLocalNoAuthMode(), | ||
| publicAccess: true, | ||
| }); | ||
| } catch (error) { | ||
| return jsonError(error); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import { NextResponse } from "next/server"; | ||
| import { z } from "zod"; | ||
|
|
||
| import { isDemoMode, isLocalNoAuthMode } from "@/lib/env"; | ||
| import { jsonError } from "@/lib/http"; | ||
| import { defaultMedicationRecords } from "@/lib/medication-seed"; | ||
| import { medicationSourceStatus, medicationValidationStatus } from "@/lib/medication-records"; | ||
| import { | ||
| medicationToSearchResult, | ||
| rankMedicationRecords, | ||
| type MedicationRecord, | ||
| type MedicationSearchMatch, | ||
| } from "@/lib/medications"; | ||
| import { parseRequestQuery, queryInteger } from "@/lib/validation/query"; | ||
|
|
||
| export const runtime = "nodejs"; | ||
|
|
||
| const medicationListQuerySchema = z.object({ | ||
| q: z | ||
| .string() | ||
| .trim() | ||
| .max(200) | ||
| .optional() | ||
| .transform((value) => (value ? value : undefined)), | ||
| limit: queryInteger({ fallback: 50, min: 1, max: 100 }), | ||
| fields: z.enum(["index"]).optional(), | ||
| }); | ||
|
|
||
| function toIndexRecords(records: MedicationRecord[]): MedicationRecord[] { | ||
| return records.map((record) => ({ | ||
| slug: record.slug, | ||
| name: record.name, | ||
| class: record.class, | ||
| subclass: record.subclass, | ||
| category: record.category, | ||
| accent: record.accent, | ||
| tag: record.tag, | ||
| schedule: record.schedule, | ||
| stats: [], | ||
| sections: [], | ||
| quick: [], | ||
| })); | ||
| } | ||
|
|
||
| function medicationResponse(payload: Record<string, unknown>) { | ||
| return NextResponse.json(payload, { headers: { "Cache-Control": "private, no-store" } }); | ||
| } | ||
|
|
||
| function matchesPayload(matches: MedicationSearchMatch[]) { | ||
| return matches.map((match) => ({ | ||
| medication: match.medication, | ||
| result: medicationToSearchResult(match), | ||
| score: match.score, | ||
| reasons: match.reasons, | ||
| })); | ||
| } | ||
|
|
||
| function publicMedicationPayload(q: string | undefined, limit: number, fields?: "index") { | ||
| const records = fields === "index" ? toIndexRecords(defaultMedicationRecords()) : defaultMedicationRecords(); | ||
| const governance = Object.fromEntries( | ||
| records.map((record) => [ | ||
| record.slug, | ||
| { | ||
| sourceStatus: medicationSourceStatus("current"), | ||
| validationStatus: medicationValidationStatus("locally_reviewed"), | ||
| }, | ||
| ]), | ||
| ); | ||
| const matches = q ? rankMedicationRecords(records, q, limit) : undefined; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For natural-language requests such as Useful? React with 👍 / 👎. |
||
| return { | ||
| records, | ||
| matches: matches ? matchesPayload(matches) : undefined, | ||
| total: records.length, | ||
| governance, | ||
| }; | ||
| } | ||
|
|
||
| export async function GET(request: Request) { | ||
| try { | ||
| const { q, limit, fields } = parseRequestQuery(request, medicationListQuerySchema, "Invalid medication query."); | ||
|
|
||
| return medicationResponse({ | ||
| ...publicMedicationPayload(q, limit, fields), | ||
| demoMode: isDemoMode() || isLocalNoAuthMode(), | ||
| publicAccess: true, | ||
| }); | ||
| } catch (error) { | ||
| return jsonError(error); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list API hard-codes every record as
current, but the same snapshot contains medications with no source section (for example edoxaban, alimemazine, and levomepromazine) thatderiveGovernanceFromSectionsreports asunknownin the detail API. Any client using/api/medicationsgovernance will display these as reviewed/current even though the underlying record has no source review metadata; derive the status before stripping index fields instead of assigningcurrentuniversally.Useful? React with 👍 / 👎.