Märk de ytor som inte gör något (QUALITY-AUDIT-2 · m-9)
Inloggningen autentiserar ingenting: vilken organisation och vilket användarnamn som helst släpps in, och lösenordet kontrolleras inte. Kontoansökan skickar ingenting, och referensen på kvittenssidan bildas i webbläsaren. Portalens siffror är fasta exempelvärden. Bägge ser ändå ut som att de gör något, och två personer i rad har försökt använda dem på riktigt innan de frågade. Det är precis vad fyndet förutsade: en yta som ser färdig ut planerar man efter. Integrationssidan tillämpar redan den här måttstocken på sig själv — en profil står `draft` tills den körts mot leverantören, med motiveringen att en lista där allt ser färdigt ut är den snabbaste vägen till ett misslyckat införande. Samma regel gäller nu resten av ytan. Rutan säger vad som INTE sker, inte vad som ska komma. Ett löfte om framtida funktion vore samma fel i ny form, och ett test avvisar formuleringar av den sorten. Det här stänger inte m-9 helt. Den ärliga slutfixen är att låsa portalrutten bakom den riktiga plattformssessionen, vilket är ett beslut om vad portalen ska vara — men tills dess vilseleder den inte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
This commit is contained in:
@@ -147,6 +147,31 @@ export function Block({ children, rubrik, beteckning }: { children: ReactNode; r
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrationsmärkning.
|
||||||
|
*
|
||||||
|
* QUALITY-AUDIT-2 · m-9. Inloggningen ser ut som en inloggning men
|
||||||
|
* autentiserar ingenting, och kontoansökan skickar ingenting. Två
|
||||||
|
* personer i rad har försökt använda dem på riktigt — vilket är precis
|
||||||
|
* vad fyndet förutsade: en yta som ser färdig ut planerar man efter.
|
||||||
|
*
|
||||||
|
* Integrationssidan märker redan en profil `draft` tills den körts mot
|
||||||
|
* leverantören, med motiveringen att en lista där allt ser färdigt ut är
|
||||||
|
* den snabbaste vägen till ett misslyckat införande. Samma måttstock
|
||||||
|
* gäller här. Rutan säger vad som INTE sker, inte vad som kommer att ske
|
||||||
|
* någon gång — ett löfte vore samma fel i ny form.
|
||||||
|
*/
|
||||||
|
export function Demonstration({ children }: { children: ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="mb-6 border-l-2 px-4 py-4" style={{ borderColor: FARG.graphite, background: FARG.white }}>
|
||||||
|
<Etikett ton="graphite">Demonstration</Etikett>
|
||||||
|
<p className="mt-2 max-w-[680px] text-[13px] leading-[20px]" style={{ color: FARG.graphite }}>
|
||||||
|
{children}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Fasindikator -----------------------------------------------------
|
// ---- Fasindikator -----------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -238,3 +238,41 @@ describe("ALVA:s snitt följer med i bygget", () => {
|
|||||||
expect(typsnitt).not.toMatch(/url\(\s*["']?https?:/);
|
expect(typsnitt).not.toMatch(/url\(\s*["']?https?:/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ---- Obackade ytor måste märkas ----------------------------------------
|
||||||
|
//
|
||||||
|
// QUALITY-AUDIT-2 · m-9. Inloggningen autentiserar ingenting och
|
||||||
|
// kontoansökan skickar ingenting, men bägge ser ut som att de gör det.
|
||||||
|
// Två personer i rad försökte använda dem på riktigt innan de frågade —
|
||||||
|
// vilket är precis vad fyndet förutsade: en yta som ser färdig ut
|
||||||
|
// planerar man efter.
|
||||||
|
//
|
||||||
|
// Integrationssidan märker redan en profil `draft` tills den körts mot
|
||||||
|
// leverantören, med motiveringen att en lista där allt ser färdigt ut är
|
||||||
|
// den snabbaste vägen till ett misslyckat införande. Testet håller
|
||||||
|
// samma måttstock mot resten av ytan.
|
||||||
|
describe("ytor utan verklig funktion är märkta som demonstration", () => {
|
||||||
|
const sida = (namn: string) => filer.find(([n]) => n.endsWith(`pages/alva/${namn}`))![1];
|
||||||
|
|
||||||
|
it.each(["LoggaIn.tsx", "Ansokan.tsx", "Portal.tsx"])("%s bär en demonstrationsruta", (namn) => {
|
||||||
|
expect(sida(namn)).toContain("<Demonstration>");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ansökans kvittens är märkt, inte bara formuläret", () => {
|
||||||
|
// Kvittenssidan med sin referens är det som mest liknar ett verkligt
|
||||||
|
// besked, och därför den som vilseleder mest om den står omärkt.
|
||||||
|
expect(sida("Ansokan.tsx").match(/<Demonstration>/g)).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rutan säger vad som inte sker, inte vad som ska komma", () => {
|
||||||
|
// Ett löfte om framtida funktion vore samma fel i ny form.
|
||||||
|
const komponenter = filer.find(([n]) => n.endsWith("alva/komponenter.tsx"))![1];
|
||||||
|
const ruta = komponenter.match(/export function Demonstration[\s\S]*?\n}/)?.[0] ?? "";
|
||||||
|
expect(ruta).toContain("Demonstration");
|
||||||
|
for (const löfte of ["coming soon", "snart", "will be available", "in a future"]) {
|
||||||
|
for (const namn of ["LoggaIn.tsx", "Ansokan.tsx", "Portal.tsx"]) {
|
||||||
|
expect(sida(namn).toLowerCase(), `${namn}: ${löfte}`).not.toContain(löfte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
// garantitvist kan inte dela ut konton automatiskt.
|
// garantitvist kan inte dela ut konton automatiskt.
|
||||||
|
|
||||||
import { type FormEvent, useState } from "react";
|
import { type FormEvent, useState } from "react";
|
||||||
import { Block, Etikett, FARG, Knapp, Rubrik, Statusmärke } from "@/alva/komponenter";
|
import { Demonstration, Block, Etikett, FARG, Knapp, Rubrik, Statusmärke } from "@/alva/komponenter";
|
||||||
import { Ram } from "./Ram";
|
import { Ram } from "./Ram";
|
||||||
|
|
||||||
interface Falt {
|
interface Falt {
|
||||||
@@ -51,6 +51,10 @@ export default function Ansokan() {
|
|||||||
<div className="mt-2 mb-8">
|
<div className="mt-2 mb-8">
|
||||||
<Rubrik niva={1}>Submitted</Rubrik>
|
<Rubrik niva={1}>Submitted</Rubrik>
|
||||||
</div>
|
</div>
|
||||||
|
<Demonstration>
|
||||||
|
Nothing was submitted. The reference below was generated in the browser and exists
|
||||||
|
nowhere else.
|
||||||
|
</Demonstration>
|
||||||
<Block rubrik="Registration" beteckning={referens}>
|
<Block rubrik="Registration" beteckning={referens}>
|
||||||
<dl className="text-[14px] leading-[24px]">
|
<dl className="text-[14px] leading-[24px]">
|
||||||
<div className="flex justify-between border-b py-2" style={{ borderColor: FARG.lightSteel }}>
|
<div className="flex justify-between border-b py-2" style={{ borderColor: FARG.lightSteel }}>
|
||||||
@@ -81,6 +85,10 @@ export default function Ansokan() {
|
|||||||
<div className="mt-2 mb-2">
|
<div className="mt-2 mb-2">
|
||||||
<Rubrik niva={1}>Request account</Rubrik>
|
<Rubrik niva={1}>Request account</Rubrik>
|
||||||
</div>
|
</div>
|
||||||
|
<Demonstration>
|
||||||
|
This form does not submit anything. The reference it returns is generated in the browser
|
||||||
|
and is not recorded. Applications are handled outside this demonstration.
|
||||||
|
</Demonstration>
|
||||||
<p className="mb-8 text-[14px] leading-[22px]" style={{ color: FARG.steel }}>
|
<p className="mb-8 text-[14px] leading-[22px]" style={{ color: FARG.steel }}>
|
||||||
Applications are reviewed manually. No payment is taken at this stage.
|
Applications are reviewed manually. No payment is taken at this stage.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
import { type FormEvent, useState } from "react";
|
import { type FormEvent, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { Block, Etikett, FARG, Knapp, Rubrik } from "@/alva/komponenter";
|
import { Demonstration, Block, Etikett, FARG, Knapp, Rubrik } from "@/alva/komponenter";
|
||||||
import { Ram } from "./Ram";
|
import { Ram } from "./Ram";
|
||||||
|
|
||||||
const FALT = [
|
const FALT = [
|
||||||
@@ -37,6 +37,11 @@ export default function LoggaIn() {
|
|||||||
<div className="mt-2 mb-8">
|
<div className="mt-2 mb-8">
|
||||||
<Rubrik niva={1}>Login</Rubrik>
|
<Rubrik niva={1}>Login</Rubrik>
|
||||||
</div>
|
</div>
|
||||||
|
<Demonstration>
|
||||||
|
This login authenticates nothing. Any organization and username signs in, and the password
|
||||||
|
is not checked. Real authentication exists in the platform service and is not part of this
|
||||||
|
demonstration.
|
||||||
|
</Demonstration>
|
||||||
|
|
||||||
<form onSubmit={skicka}>
|
<form onSubmit={skicka}>
|
||||||
<Block>
|
<Block>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { PLATTFORMSVERSION, arendebeteckning } from "@/alva/system";
|
import { PLATTFORMSVERSION, arendebeteckning } from "@/alva/system";
|
||||||
import { Block, Etikett, FARG, Falt, Knapp, Rubrik, Statusmärke, Tabell } from "@/alva/komponenter";
|
import { Demonstration, Block, Etikett, FARG, Falt, Knapp, Rubrik, Statusmärke, Tabell } from "@/alva/komponenter";
|
||||||
import { MEDDELANDE } from "@/alva/sprak";
|
import { MEDDELANDE } from "@/alva/sprak";
|
||||||
import { Ram } from "./Ram";
|
import { Ram } from "./Ram";
|
||||||
|
|
||||||
@@ -27,6 +27,11 @@ export default function Portal() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Demonstration>
|
||||||
|
The figures on this page are fixed example values, and the organization is not a real one.
|
||||||
|
Analysis is the exception: it is computed from the cases you create under Diagnostics.
|
||||||
|
</Demonstration>
|
||||||
|
|
||||||
<div className="grid gap-6 md:grid-cols-2">
|
<div className="grid gap-6 md:grid-cols-2">
|
||||||
<Block rubrik="Status" beteckning="ALVA-REP-0001">
|
<Block rubrik="Status" beteckning="ALVA-REP-0001">
|
||||||
<Falt etikett="Organization">
|
<Falt etikett="Organization">
|
||||||
|
|||||||
Reference in New Issue
Block a user