mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
Merge work/fhir-retire
This commit is contained in:
commit
f6bd8be6d5
5 files changed
+12
-71
No files matched your search
@@ -374,8 +374,6 @@ describe("DELETE /api/share-links/[id] — revoke", () => {
|
||||
* Mutation checks:
|
||||
* - drop the `SHARE_LINK_FORBIDDEN_LEAVES` check in the route → "refuses the
|
||||
* insurance leaf by name" goes red.
|
||||
* - drop `RETIRED_FHIR_SCOPE_FIELDS` from the create response → "keeps the
|
||||
* retired scope fields on the response" goes red.
|
||||
* - make `needsReselection` always false → "flags a link whose frozen scope
|
||||
* predates the selection model" goes red.
|
||||
*/
|
||||
@@ -433,21 +431,17 @@ describe("POST /api/share-links — the frozen scope", () => {
|
||||
expect(createArg.data.sectionsJson).toEqual({ v: 2, leaves: [] });
|
||||
});
|
||||
|
||||
it("keeps the retired scope fields on the response", async () => {
|
||||
// Response-only, serving constants. The request refuses them and the
|
||||
// columns are gone; they stay here until the native client confirms it
|
||||
// does not decode them.
|
||||
it("the retired FHIR scope fields are gone from the create response", async () => {
|
||||
// #70 — the native client confirmed removal breaks no shipped decoder.
|
||||
vi.mocked(prisma.clinicianShareLink.create).mockResolvedValue(
|
||||
storedRow() as never,
|
||||
);
|
||||
const res = await POST(
|
||||
postReq(validBody({ selection: { v: 2, leaves: ["WEIGHT"] } })),
|
||||
);
|
||||
const body = (await res.json()) as {
|
||||
data: { allowFhirApi: boolean; resourceTypes: string[] };
|
||||
};
|
||||
expect(body.data.allowFhirApi).toBe(false);
|
||||
expect(body.data.resourceTypes).toEqual([]);
|
||||
const body = (await res.json()) as { data: Record<string, unknown> };
|
||||
expect(body.data).not.toHaveProperty("allowFhirApi");
|
||||
expect(body.data).not.toHaveProperty("resourceTypes");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -465,12 +459,9 @@ describe("GET /api/share-links — the pick-again state", () => {
|
||||
const res = await GET();
|
||||
const body = (await res.json()) as {
|
||||
data: {
|
||||
shareLinks: Array<{
|
||||
id: string;
|
||||
needsReselection: boolean;
|
||||
allowFhirApi: boolean;
|
||||
resourceTypes: string[];
|
||||
}>;
|
||||
shareLinks: Array<
|
||||
{ id: string; needsReselection: boolean } & Record<string, unknown>
|
||||
>;
|
||||
};
|
||||
};
|
||||
const byId = new Map(body.data.shareLinks.map((l) => [l.id, l]));
|
||||
@@ -479,8 +470,8 @@ describe("GET /api/share-links — the pick-again state", () => {
|
||||
// A documents-only link carried no report scope to begin with, so it was
|
||||
// never revoked and is not asked to pick again.
|
||||
expect(byId.get("docs")!.needsReselection).toBe(false);
|
||||
// The retired fields ride the list response too.
|
||||
expect(byId.get("current")!.allowFhirApi).toBe(false);
|
||||
expect(byId.get("current")!.resourceTypes).toEqual([]);
|
||||
// The retired FHIR scope fields are gone from the list response too.
|
||||
expect(byId.get("current")).not.toHaveProperty("allowFhirApi");
|
||||
expect(byId.get("current")).not.toHaveProperty("resourceTypes");
|
||||
});
|
||||
});
|
||||
@@ -87,22 +87,6 @@ const shareLinkSummarySelect = {
|
||||
_count: { select: { documents: true } },
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* RETIRED, kept on the response only.
|
||||
*
|
||||
* These two fields described a scoped FHIR face for a share link that was
|
||||
* never built. The request schema refuses them — sending either is a 422 —
|
||||
* their columns are dropped, and nothing reads or honours them. They stay in
|
||||
* the create and list responses, serving the constant `false` and `[]`,
|
||||
* because the native client was given this response shape and a missing
|
||||
* non-optional key fails a whole Swift decode. They come out once #70 in the
|
||||
* native repository confirms the client does not decode them.
|
||||
*/
|
||||
const RETIRED_FHIR_SCOPE_FIELDS = {
|
||||
allowFhirApi: false,
|
||||
resourceTypes: [] as string[],
|
||||
} as const;
|
||||
|
||||
/** Project a stored row to the safe owner-facing shape (never the token). */
|
||||
function toSummary(row: {
|
||||
id: string;
|
||||
@@ -279,7 +263,6 @@ export const POST = apiHandler(async (request: NextRequest) => {
|
||||
return apiSuccess(
|
||||
{
|
||||
...toSummary(created),
|
||||
...RETIRED_FHIR_SCOPE_FIELDS,
|
||||
token: rawToken,
|
||||
passphrase: rawPassphrase,
|
||||
shareUrl,
|
||||
@@ -300,9 +283,6 @@ export const GET = apiHandler(async () => {
|
||||
});
|
||||
|
||||
return apiSuccess({
|
||||
shareLinks: rows.map((row) => ({
|
||||
...toSummary(row),
|
||||
...RETIRED_FHIR_SCOPE_FIELDS,
|
||||
})),
|
||||
shareLinks: rows.map((row) => toSummary(row)),
|
||||
});
|
||||
});
|
||||
@@ -83,14 +83,6 @@ export interface ShareLinkSummary {
|
||||
* hashes). `qrUrl` carries the passphrase in the URL fragment (`#k=`).
|
||||
*/
|
||||
export interface ShareLinkCreated extends ShareLinkSummary {
|
||||
/**
|
||||
* RETIRED, response-only. They configured a FHIR face that was never built;
|
||||
* the request refuses them and the columns are gone. They stay here because
|
||||
* the native client was given this shape and a missing non-optional key
|
||||
* fails a whole Swift decode — see #70 in the native repository.
|
||||
*/
|
||||
allowFhirApi: boolean;
|
||||
resourceTypes: string[];
|
||||
token: string;
|
||||
passphrase: string;
|
||||
shareUrl: string;
|
||||
|
||||
@@ -36,12 +36,6 @@ const shareLinkSummary = z.object({
|
||||
// link was revoked on upgrade; the sharing list surfaces this so the owner
|
||||
// knows to re-mint rather than wondering why a working link stopped.
|
||||
needsReselection: z.boolean(),
|
||||
// RETIRED, response-only, serving the constants `false` and `[]`. They
|
||||
// configured a FHIR face that was never built; the request refuses them and
|
||||
// their columns are gone. They stay on the response until the native client
|
||||
// confirms it does not decode them.
|
||||
allowFhirApi: z.boolean(),
|
||||
resourceTypes: z.array(z.string()),
|
||||
expiresAt: z.string(),
|
||||
createdAt: z.string(),
|
||||
revokedAt: z.string().nullable(),
|
||||
|
||||
Reference in new issue
Block a user