@lernapps/app-templates 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +195 -2
- package/dist/appname-Bh23cUuz.mjs +12 -0
- package/dist/assessment-By2GGTJC.mjs +1696 -0
- package/dist/block-BK_ohsH1.mjs +82 -0
- package/dist/blocks-BmRrD7UY.mjs +149 -0
- package/dist/blocks.mjs +4 -0
- package/dist/check-BkEl-m-F.mjs +254 -0
- package/dist/content-cYBPYg_J.mjs +140 -0
- package/dist/contract-PONpxJtd.mjs +52 -0
- package/dist/e2e-BiMI-pCL.mjs +89 -0
- package/dist/engine-BqF2Vffn.mjs +136 -0
- package/dist/explainer-e2e.mjs +1297 -0
- package/dist/explainer-islands.mjs +197 -0
- package/dist/explainer-plugin.mjs +2131 -0
- package/dist/explainer.mjs +1246 -0
- package/dist/html-mffkHGHh.mjs +89 -0
- package/dist/image-CspJVfyQ.mjs +21 -0
- package/dist/interactive-e2e.mjs +140 -0
- package/dist/interactive-plugin.mjs +242 -0
- package/dist/interactive.mjs +75 -0
- package/dist/load-C-0hUaSC.mjs +16947 -0
- package/dist/needs-BzEahJ6X.mjs +97 -0
- package/dist/pages-9RaaomoO.mjs +81 -0
- package/dist/questions-e2e.mjs +1 -0
- package/dist/questions-engine.mjs +3 -0
- package/dist/questions.mjs +6 -0
- package/dist/quiz-BKc8JYtC.mjs +70 -0
- package/dist/quiz-e2e.mjs +174 -0
- package/dist/quiz-plugin.mjs +266 -0
- package/dist/quiz.mjs +246 -0
- package/dist/render-BJey0bwl.mjs +540 -0
- package/dist/render-BL6fV_NI.mjs +507 -0
- package/dist/render-DpRO_RKm.mjs +146 -0
- package/dist/result-_eQcamoz.mjs +180 -0
- package/dist/tasks-DADUYy52.mjs +74 -0
- package/dist/validate-COaZso7u.mjs +1072 -0
- package/dist/validate-CxtdeQ5S.mjs +146 -0
- package/dist/vue-DO1m6q1R.mjs +40 -0
- package/dist/vue-code-BkJjW_I_.mjs +320 -0
- package/docs/arc42/01-introduction-and-goals.arc42.md +82 -0
- package/docs/arc42/02-constraints.arc42.md +228 -0
- package/docs/arc42/03-system-context.arc42.md +118 -0
- package/docs/arc42/04-solution-strategy.arc42.md +47 -0
- package/docs/arc42/05-building-blocks.arc42.md +307 -0
- package/docs/arc42/06-runtime-view.arc42.md +98 -0
- package/docs/arc42/07-deployment-view.arc42.md +160 -0
- package/docs/arc42/08-concepts.arc42.md +123 -0
- package/docs/arc42/09-decisions.arc42.md +246 -0
- package/docs/arc42/10-quality-requirements.arc42.md +155 -0
- package/docs/arc42/11-risks.arc42.md +113 -0
- package/docs/arc42/12-glossary.arc42.md +162 -0
- package/docs/arc42/architecture-evidence.md +395 -0
- package/explainer/.arc42ignore +3 -0
- package/explainer/README.md +54 -0
- package/explainer/_gitignore +5 -0
- package/explainer/docs/arc42/03-explainer-system-context.arc42.md +35 -0
- package/explainer/docs/arc42/05-explainer-building-blocks.arc42.md +659 -0
- package/explainer/docs/arc42/06-explainer-runtime-view.arc42.md +105 -0
- package/explainer/docs/arc42/07-explainer-deployment-view.arc42.md +34 -0
- package/explainer/docs/arc42/08-explainer-concepts.arc42.md +17 -0
- package/explainer/docs/arc42/09-explainer-decisions.arc42.md +443 -0
- package/explainer/docs/arc42/10-explainer-quality-requirements.arc42.md +54 -0
- package/explainer/docs/arc42/11-explainer-risks.arc42.md +17 -0
- package/explainer/docs/arc42/12-explainer-glossary.arc42.md +185 -0
- package/explainer/e2e/explainer.e2e.ts +3 -0
- package/explainer/index.html +11 -0
- package/explainer/package.json +18 -0
- package/explainer/playwright.config.ts +1 -0
- package/explainer/src/app.yaml +20 -0
- package/explainer/src/components/ProzentFeld.test.ts +30 -0
- package/explainer/src/components/ProzentFeld.ts +121 -0
- package/explainer/src/components/ProzentFeld.vue +84 -0
- package/explainer/src/images/hunderterfeld-klammern.svg +105 -0
- package/explainer/src/main.ts +4 -0
- package/explainer/src/prozent/chapter.yaml +18 -0
- package/explainer/src/prozent/grundwert.yaml +115 -0
- package/explainer/src/prozent/prozentsatz.yaml +99 -0
- package/explainer/src/prozent/prozentwert.yaml +119 -0
- package/explainer/tsconfig.json +1 -0
- package/explainer/vite.config.ts +4 -0
- package/interactive/.arc42ignore +5 -0
- package/interactive/README.md +28 -0
- package/interactive/_gitignore +4 -0
- package/interactive/docs/arc42/05-interactive-building-blocks.arc42.md +518 -0
- package/interactive/docs/arc42/06-interactive-runtime-view.arc42.md +58 -0
- package/interactive/docs/arc42/07-interactive-deployment-view.arc42.md +35 -0
- package/interactive/docs/arc42/08-interactive-concepts.arc42.md +52 -0
- package/interactive/docs/arc42/09-interactive-decisions.arc42.md +130 -0
- package/interactive/docs/arc42/10-interactive-quality-requirements.arc42.md +45 -0
- package/interactive/docs/arc42/11-interactive-risks.arc42.md +20 -0
- package/interactive/docs/arc42/12-interactive-glossary.arc42.md +80 -0
- package/interactive/e2e/interactive.e2e.ts +3 -0
- package/interactive/index.html +11 -0
- package/interactive/package.json +18 -0
- package/interactive/playwright.config.ts +1 -0
- package/interactive/src/app.yaml +28 -0
- package/interactive/src/core/index.ts +101 -0
- package/interactive/src/data/lessons.json +4 -0
- package/interactive/src/env.d.ts +6 -0
- package/interactive/src/main.ts +6 -0
- package/interactive/src/messages/de.json +12 -0
- package/interactive/src/playthroughs/grundreihe.yaml +33 -0
- package/interactive/src/playthroughs/obere-reihe.yaml +14 -0
- package/interactive/src/ui/App.vue +85 -0
- package/interactive/tsconfig.json +1 -0
- package/interactive/vite.config.ts +4 -0
- package/package.json +144 -4
- package/quiz/README.md +31 -0
- package/quiz/_gitignore +5 -0
- package/quiz/docs/arc42/05-quiz-building-blocks.arc42.md +283 -0
- package/quiz/docs/arc42/06-quiz-runtime-view.arc42.md +21 -0
- package/quiz/docs/arc42/07-quiz-deployment-view.arc42.md +33 -0
- package/quiz/docs/arc42/09-quiz-decisions.arc42.md +36 -0
- package/quiz/docs/arc42/10-quiz-quality-requirements.arc42.md +53 -0
- package/quiz/docs/arc42/11-quiz-risks.arc42.md +19 -0
- package/quiz/docs/arc42/12-quiz-glossary.arc42.md +27 -0
- package/quiz/e2e/quiz.e2e.ts +3 -0
- package/quiz/index.html +11 -0
- package/quiz/package.json +18 -0
- package/quiz/playwright.config.ts +1 -0
- package/quiz/src/images/berge-ordnen.jpg +0 -0
- package/quiz/src/images/everest-hoehe.jpg +0 -0
- package/quiz/src/images/galapagos.jpg +0 -0
- package/quiz/src/images/grand-canyon.jpg +0 -0
- package/quiz/src/images/totes-meer.jpg +0 -0
- package/quiz/src/images/uluru.jpg +0 -0
- package/quiz/src/images/wasserfaelle-laender.jpg +0 -0
- package/quiz/src/main.ts +4 -0
- package/quiz/src/quiz.json +312 -0
- package/quiz/tsconfig.json +1 -0
- package/quiz/vite.config.ts +4 -0
- package/runtime/explainer/assessment-client.ts +478 -0
- package/runtime/explainer/assessment-page.ts +446 -0
- package/runtime/explainer/assessment.ts +393 -0
- package/runtime/explainer/check-page.ts +520 -0
- package/runtime/explainer/components/exercise.ts +409 -0
- package/runtime/explainer/components/props.ts +230 -0
- package/runtime/explainer/components/read.ts +428 -0
- package/runtime/explainer/content.ts +277 -0
- package/runtime/explainer/e2e.ts +1474 -0
- package/runtime/explainer/exercises.ts +324 -0
- package/runtime/explainer/explainer.css +1283 -0
- package/runtime/explainer/explainer.ts +838 -0
- package/runtime/explainer/explainer.v1.schema.json +1165 -0
- package/runtime/explainer/expression.ts +407 -0
- package/runtime/explainer/fraction.ts +107 -0
- package/runtime/explainer/generated/comparator.ts +31 -0
- package/runtime/explainer/generated/question.ts +165 -0
- package/runtime/explainer/generated/soundness.ts +280 -0
- package/runtime/explainer/generated/texts.ts +257 -0
- package/runtime/explainer/generated/types.ts +103 -0
- package/runtime/explainer/generated/values.ts +136 -0
- package/runtime/explainer/islands.ts +281 -0
- package/runtime/explainer/load.ts +457 -0
- package/runtime/explainer/messages/de.json +200 -0
- package/runtime/explainer/messages/en.json +200 -0
- package/runtime/explainer/messages.ts +13 -0
- package/runtime/explainer/needs.ts +122 -0
- package/runtime/explainer/open-task.ts +235 -0
- package/runtime/explainer/outline.ts +299 -0
- package/runtime/explainer/plugin.ts +488 -0
- package/runtime/explainer/position.ts +62 -0
- package/runtime/explainer/prompt.ts +75 -0
- package/runtime/explainer/render.ts +686 -0
- package/runtime/explainer/result.ts +238 -0
- package/runtime/explainer/routes.ts +119 -0
- package/runtime/explainer/schema.ts +140 -0
- package/runtime/explainer/scope.ts +87 -0
- package/runtime/explainer/stuck.ts +57 -0
- package/runtime/explainer/tasks.ts +109 -0
- package/runtime/explainer/tutor.ts +469 -0
- package/runtime/explainer/tutorpage.ts +669 -0
- package/runtime/explainer/video.ts +123 -0
- package/runtime/interactive/contract.ts +121 -0
- package/runtime/interactive/e2e.ts +190 -0
- package/runtime/interactive/interactive.css +82 -0
- package/runtime/interactive/interactive.ts +115 -0
- package/runtime/interactive/interactive.v1.schema.json +146 -0
- package/runtime/interactive/load.ts +188 -0
- package/runtime/interactive/messages/de.json +14 -0
- package/runtime/interactive/messages/en.json +14 -0
- package/runtime/interactive/messages.ts +11 -0
- package/runtime/interactive/playthrough.v1.schema.json +143 -0
- package/runtime/interactive/plugin.ts +266 -0
- package/runtime/interactive/render.ts +126 -0
- package/runtime/quiz/e2e.ts +233 -0
- package/runtime/quiz/engine.ts +242 -0
- package/runtime/quiz/messages/de.json +23 -0
- package/runtime/quiz/messages/en.json +23 -0
- package/runtime/quiz/plugin.ts +150 -0
- package/runtime/quiz/quiz.css +154 -0
- package/runtime/quiz/quiz.ts +56 -0
- package/runtime/quiz/quiz.v1.schema.json +72 -0
- package/runtime/quiz/render.ts +173 -0
- package/runtime/quiz/validate.ts +108 -0
- package/runtime/shared/appname.ts +16 -0
- package/runtime/shared/blocks/block.ts +162 -0
- package/runtime/shared/blocks/blocks.css +190 -0
- package/runtime/shared/blocks/blocks.v1.schema.json +432 -0
- package/runtime/shared/blocks/code.ts +26 -0
- package/runtime/shared/blocks/figures.ts +49 -0
- package/runtime/shared/blocks/image.ts +25 -0
- package/runtime/shared/blocks/index.ts +13 -0
- package/runtime/shared/blocks/messages/de.json +4 -0
- package/runtime/shared/blocks/messages/en.json +4 -0
- package/runtime/shared/blocks/render.ts +134 -0
- package/runtime/shared/blocks/validate.ts +165 -0
- package/runtime/shared/content.ts +197 -0
- package/runtime/shared/examples.ts +20 -0
- package/runtime/shared/html.ts +10 -0
- package/runtime/shared/languages.ts +94 -0
- package/runtime/shared/page.css +101 -0
- package/runtime/shared/pages.ts +114 -0
- package/runtime/shared/questions/e2e.ts +115 -0
- package/runtime/shared/questions/engine.ts +209 -0
- package/runtime/shared/questions/index.ts +39 -0
- package/runtime/shared/questions/messages/de.json +26 -0
- package/runtime/shared/questions/messages/en.json +26 -0
- package/runtime/shared/questions/question.ts +430 -0
- package/runtime/shared/questions/question.v1.schema.json +342 -0
- package/runtime/shared/questions/questions.css +192 -0
- package/runtime/shared/questions/render.ts +247 -0
- package/runtime/shared/questions/validate.ts +518 -0
- package/runtime/shared/schema.ts +44 -0
- package/runtime/shared/text/check.ts +68 -0
- package/runtime/shared/text/formula.ts +69 -0
- package/runtime/shared/text/markdown.ts +185 -0
- package/runtime/shared/text/text.v1.schema.json +34 -0
- package/runtime/shared/vue-code.ts +395 -0
- package/runtime/shared/vue.ts +38 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Architecture Decisions
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
Arc42 chapter 9. Document the significant architecture decisions as Architecture Decision
|
|
5
|
+
Records (ADRs). Capture any choice that was expensive, risky, or that future maintainers
|
|
6
|
+
will wonder about.
|
|
7
|
+
|
|
8
|
+
Avoid redundancy with section 4 (solution strategy) — refer to it for the highest-level
|
|
9
|
+
choices and use this chapter for detail and rationale.
|
|
10
|
+
|
|
11
|
+
For each decision, write a ## section with a prose paragraph explaining the context,
|
|
12
|
+
the alternatives considered, and the rationale for the chosen option, followed by a DSL block.
|
|
13
|
+
Document rejected alternatives so future readers understand what was considered.
|
|
14
|
+
|
|
15
|
+
Status values:
|
|
16
|
+
proposed — under discussion, not yet in force
|
|
17
|
+
accepted — in force
|
|
18
|
+
deprecated — no longer recommended but not yet replaced
|
|
19
|
+
superseded — replaced by another decision
|
|
20
|
+
|
|
21
|
+
When a new decision replaces an old one, set status: superseded on the old decision
|
|
22
|
+
and add supersedes: <old-id> on the new decision.
|
|
23
|
+
|
|
24
|
+
The `date` field should be ISO 8601 (YYYY-MM-DD).
|
|
25
|
+
The `addresses` field links to quality goals and constraints this decision responds to.
|
|
26
|
+
|
|
27
|
+
See https://docs.arc42.org/section-9/ for further guidance.
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
|
|
31
|
+
## Stateless Token Authentication
|
|
32
|
+
|
|
33
|
+
The team evaluated session-based (server-side store) and token-based (stateless) authentication.
|
|
34
|
+
Stateless tokens were chosen to avoid a shared session store that would introduce a single point
|
|
35
|
+
of failure and complicate horizontal scaling.
|
|
36
|
+
|
|
37
|
+
```arc42
|
|
38
|
+
:::decision
|
|
39
|
+
id: dec-auth-stateless
|
|
40
|
+
title: Stateless Token Authentication
|
|
41
|
+
status: accepted
|
|
42
|
+
date: 2025-07-01
|
|
43
|
+
addresses: qg-security, qg-performance
|
|
44
|
+
:::
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
To supersede a decision, mark the old one and point to it from the new one:
|
|
48
|
+
|
|
49
|
+
```arc42
|
|
50
|
+
:::decision
|
|
51
|
+
id: dec-auth-old
|
|
52
|
+
title: Session-based Authentication
|
|
53
|
+
status: superseded
|
|
54
|
+
date: 2024-01-15
|
|
55
|
+
:::
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```arc42
|
|
59
|
+
:::decision
|
|
60
|
+
id: dec-auth-new
|
|
61
|
+
title: OAuth2 Token Authentication
|
|
62
|
+
status: accepted
|
|
63
|
+
date: 2025-09-01
|
|
64
|
+
supersedes: dec-auth-old
|
|
65
|
+
:::
|
|
66
|
+
```
|
|
67
|
+
-->
|
|
68
|
+
|
|
69
|
+
The decisions every lernapps app shares. Owner decisions are accepted with their date; decisions the runtime made
|
|
70
|
+
when it was built are accepted because they are in force. Each extension adds its archetype's decisions, and an
|
|
71
|
+
interactive app adds its own below these.
|
|
72
|
+
|
|
73
|
+
## Generic Architecture with One Extension per Archetype
|
|
74
|
+
|
|
75
|
+
Quiz, explainer and interactive app stay separate archetypes, but they share their quality goals, so they follow one
|
|
76
|
+
architecture: this generic part with the frame and an abstract archetype part, and one extension per archetype in its
|
|
77
|
+
template folder that adds only its own blocks and decisions and references the generic ids. An app's architecture is
|
|
78
|
+
both together. Rejected: one architecture per archetype, which would repeat the frame three times; one architecture
|
|
79
|
+
with every archetype's detail in it, which no app could take as its own.
|
|
80
|
+
|
|
81
|
+
```arc42
|
|
82
|
+
:::decision
|
|
83
|
+
id: dec-generic-plus-extensions
|
|
84
|
+
title: A generic architecture plus one extension per archetype
|
|
85
|
+
status: accepted
|
|
86
|
+
date: 2026-10-16
|
|
87
|
+
addresses: qg-understandable, con-architecture-current
|
|
88
|
+
:::
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## What Archetypes Share Lives in the Shared Runtime
|
|
92
|
+
|
|
93
|
+
Quiz, explainer and interactive app use some things alike, the questions first of all: the quiz asks them, the
|
|
94
|
+
explainer's exercises are the same six types; the explainer and the interactive archetype read YAML content, check
|
|
95
|
+
texts and formulas and check the code of Vue components alike. Such a thing lives in `runtime/shared` (the questions in
|
|
96
|
+
`runtime/shared/questions`), and the archetypes build on it: no archetype imports another, and the shared runtime
|
|
97
|
+
imports none. The public paths of the package (`quiz/question`, `quiz/e2e`, ...) stay as thin re-exports, so that an
|
|
98
|
+
app generated from a template keeps building when a module moves. A test (`test/architecture.test.ts`) fails on an
|
|
99
|
+
import against this direction and on a public path without a file or a build entry. Rejected: the explainer importing
|
|
100
|
+
the quiz and the quiz the explainer's figures, which makes two archetypes one; copying the questions into each.
|
|
101
|
+
|
|
102
|
+
```arc42
|
|
103
|
+
:::decision
|
|
104
|
+
id: dec-shared-runtime-direction
|
|
105
|
+
title: Archetypes build on the shared runtime and never on each other
|
|
106
|
+
status: accepted
|
|
107
|
+
date: 2026-10-20
|
|
108
|
+
addresses: qg-understandable, con-runtime-unchanged
|
|
109
|
+
:::
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Vue Is Fixed for Components
|
|
113
|
+
|
|
114
|
+
Where an app has components of its own (an explainer's components, an interactive app's UI), they are Vue with
|
|
115
|
+
TypeScript, so that one set of component rules, their build checks on the SFC compiler's output, the lint rules and
|
|
116
|
+
`vue-tsc` hold for every app, with no rules per framework; what a component draws and how stays free. Rejected: a free
|
|
117
|
+
choice of framework.
|
|
118
|
+
|
|
119
|
+
```arc42
|
|
120
|
+
:::decision
|
|
121
|
+
id: dec-vue-fixed
|
|
122
|
+
title: Vue with TypeScript is fixed for an app's components
|
|
123
|
+
status: accepted
|
|
124
|
+
date: 2026-10-16
|
|
125
|
+
addresses: con-vue-typescript, con-component-rules, qg-checkable
|
|
126
|
+
:::
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Small Storage with a Quota
|
|
130
|
+
|
|
131
|
+
All apps share the origin's 5 MiB of `localStorage`. The only storage is the tooling's `localStorage` wrapper under the
|
|
132
|
+
app's prefix with a quota of 100 kB per app, and `save` refuses beyond it; the shared origin is accepted as a risk. The
|
|
133
|
+
quota is decided, not built. A second storage (IndexedDB) is left out.
|
|
134
|
+
|
|
135
|
+
```arc42
|
|
136
|
+
:::decision
|
|
137
|
+
id: dec-small-storage
|
|
138
|
+
title: localStorage through the wrapper with a 100 kB quota
|
|
139
|
+
status: accepted
|
|
140
|
+
date: 2026-10-16
|
|
141
|
+
addresses: con-state-on-device, con-storage-quota, con-frontend-only, qg-privacy, risk-shared-origin-storage, risk-storage-quota-not-built
|
|
142
|
+
:::
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## No Size Limit, the Size in the Entry
|
|
146
|
+
|
|
147
|
+
The app's size is not limited by the frame; it is stated in the app's catalog entry (its fact sheet), and a page may
|
|
148
|
+
show an optional loading indicator while it loads (not built). An archetype may still fix the size of its own parts,
|
|
149
|
+
as the explainer does for each component. Rejected: a size budget for every app, which would keep large interactive
|
|
150
|
+
apps out.
|
|
151
|
+
|
|
152
|
+
```arc42
|
|
153
|
+
:::decision
|
|
154
|
+
id: dec-no-size-limit
|
|
155
|
+
title: No size limit; the size in the entry, an optional loading indicator
|
|
156
|
+
status: accepted
|
|
157
|
+
date: 2026-10-16
|
|
158
|
+
addresses: qg-accessibility
|
|
159
|
+
:::
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Accessibility by Default, Limits Declared
|
|
163
|
+
|
|
164
|
+
WCAG 2.1 AA and 360 px are platform rules; an app follows them by default and may deviate where its idea needs it (a
|
|
165
|
+
game against the clock), saying in its entry what it does not offer; then `accessible` and `usable-at-360px`
|
|
166
|
+
become warnings for it. Pages the runtime renders from the creator's data meet both in any case. Low stimulation is
|
|
167
|
+
advice in a skill, not a check. Rejected: the rules as errors for every app, which would exclude real-time games.
|
|
168
|
+
|
|
169
|
+
```arc42
|
|
170
|
+
:::decision
|
|
171
|
+
id: dec-accessibility-default
|
|
172
|
+
title: Accessibility as default with declared limits
|
|
173
|
+
status: accepted
|
|
174
|
+
date: 2026-10-16
|
|
175
|
+
addresses: con-accessibility-default, qg-accessibility, risk-accessibility-limits-not-built
|
|
176
|
+
:::
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## No Settings Now
|
|
180
|
+
|
|
181
|
+
A settings dialog (time limit off, less motion, sound, pause) is not in scope now; an app that needs one later adds it
|
|
182
|
+
to the frame rather than on its own.
|
|
183
|
+
|
|
184
|
+
```arc42
|
|
185
|
+
:::ignore H001 a scoping decision of the owner (2026-10-16): it leaves something out and serves no quality goal of its own
|
|
186
|
+
:::
|
|
187
|
+
:::decision
|
|
188
|
+
id: dec-no-settings
|
|
189
|
+
title: No settings dialog for now
|
|
190
|
+
status: accepted
|
|
191
|
+
date: 2026-10-16
|
|
192
|
+
:::
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## arc42 in the App, Only for Interactive Apps
|
|
196
|
+
|
|
197
|
+
Every app gets the generic architecture and its archetype's extension. Only an interactive app, whose code is free,
|
|
198
|
+
writes an architecture part of its own, below its extension's blocks, English and minimal; a quiz or explainer app
|
|
199
|
+
writes none, because its archetype's notation (the question bank, the content schema) fixes its structure. Checked
|
|
200
|
+
is only what arc42 checks itself (`arc42 diff --staged --strict` before a commit, `arc42 validate` in
|
|
201
|
+
`lernapps check`); whether the code keeps to the responsibilities is not checked. Rejected: framework-specific
|
|
202
|
+
conformance checks. Both checks are not wired into an app yet; `lernapps/app-templates` validates each combination of
|
|
203
|
+
the generic part and one extension strictly in its pre-commit hook and in CI (`scripts/arc42.ts`).
|
|
204
|
+
|
|
205
|
+
```arc42
|
|
206
|
+
:::decision
|
|
207
|
+
id: dec-arc42-in-app
|
|
208
|
+
title: arc42 in the app; only interactive apps add their own part
|
|
209
|
+
status: accepted
|
|
210
|
+
date: 2026-10-16
|
|
211
|
+
addresses: con-architecture-current, con-language, qg-understandable, risk-arc42-checks-not-wired
|
|
212
|
+
:::
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## The Skill as the Interface to the Creator's Assistant
|
|
216
|
+
|
|
217
|
+
The guidance for the creator's assistant is a skill per archetype plus `lernapps-app` for every app: Markdown the
|
|
218
|
+
assistant loads and follows, modelled as the interface `if-skills` of the skills block `bb-skills`. Advice that no check can make (how to write
|
|
219
|
+
a good question, low stimulation) lives there, not in the runtime.
|
|
220
|
+
|
|
221
|
+
```arc42
|
|
222
|
+
:::decision
|
|
223
|
+
id: dec-skill-interface
|
|
224
|
+
title: Skills as the interface used by the creator's assistant
|
|
225
|
+
status: accepted
|
|
226
|
+
date: 2026-10-16
|
|
227
|
+
addresses: qg-understandable
|
|
228
|
+
:::
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Tutor Variant
|
|
232
|
+
|
|
233
|
+
The optional tutor is a handoff to the learner's own assistant: after a click, a prompt (copied or passed to a chosen
|
|
234
|
+
provider) and a static tutor page per content page give it the task on the learner's screen. Rejected: a model
|
|
235
|
+
running in the browser. Built for the explainer (its extension models it); not built for the quiz and interactive
|
|
236
|
+
apps.
|
|
237
|
+
|
|
238
|
+
```arc42
|
|
239
|
+
:::decision
|
|
240
|
+
id: dec-tutor-variant
|
|
241
|
+
title: Tutor as a handoff to the learner's own assistant
|
|
242
|
+
status: accepted
|
|
243
|
+
date: 2026-10-16
|
|
244
|
+
addresses: risk-tutor-not-built, con-no-request-before-click, qg-privacy
|
|
245
|
+
:::
|
|
246
|
+
```
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Quality Requirements
|
|
2
|
+
|
|
3
|
+
The four quality goals every lernapps app shares, in the order of chapter 1, each made testable by scenarios. The
|
|
4
|
+
set and the priorities are the owner's (2026-10-16). Each extension adds its archetype's scenarios; the quiz and the
|
|
5
|
+
explainer add readability without JavaScript as a goal of their own. Scenarios marked "not built yet" describe a
|
|
6
|
+
decided check that does not exist today.
|
|
7
|
+
|
|
8
|
+
## 10.1 Quality Goals
|
|
9
|
+
|
|
10
|
+
## Privacy
|
|
11
|
+
|
|
12
|
+
The app sends nothing anywhere and requests nothing from another server before a click; what it remembers stays on the
|
|
13
|
+
learner's device. The privacy notice of lernapps.net promises this for every app.
|
|
14
|
+
|
|
15
|
+
```arc42
|
|
16
|
+
:::quality-goal
|
|
17
|
+
id: qg-privacy
|
|
18
|
+
title: Privacy
|
|
19
|
+
priority: high
|
|
20
|
+
:::
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Checkable
|
|
24
|
+
|
|
25
|
+
The rules an app keeps are verified by machine, at build and in the browser, so that an assistant can change content
|
|
26
|
+
or code and still learn at once when it breaks the frame.
|
|
27
|
+
|
|
28
|
+
```arc42
|
|
29
|
+
:::quality-goal
|
|
30
|
+
id: qg-checkable
|
|
31
|
+
title: Checkable by machine
|
|
32
|
+
priority: high
|
|
33
|
+
:::
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Accessibility
|
|
37
|
+
|
|
38
|
+
A default with declared limits: the pages meet WCAG 2.1 AA and work at 360 px, and an app that cannot declares its
|
|
39
|
+
limits in its entry.
|
|
40
|
+
|
|
41
|
+
```arc42
|
|
42
|
+
:::quality-goal
|
|
43
|
+
id: qg-accessibility
|
|
44
|
+
title: Accessibility by default
|
|
45
|
+
priority: medium
|
|
46
|
+
:::
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Understandable
|
|
50
|
+
|
|
51
|
+
A reviewer or the creator's agent understands an app's structure from its architecture, the generic part plus its
|
|
52
|
+
archetype's extension, written in English and minimal and kept current with the code.
|
|
53
|
+
|
|
54
|
+
```arc42
|
|
55
|
+
:::quality-goal
|
|
56
|
+
id: qg-understandable
|
|
57
|
+
title: Understandable from its architecture
|
|
58
|
+
priority: medium
|
|
59
|
+
:::
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 10.2 Quality Scenarios
|
|
63
|
+
|
|
64
|
+
## No request before a click
|
|
65
|
+
|
|
66
|
+
`lernapps check` visits every page of the built app, blocks and records requests to other hosts while it loads.
|
|
67
|
+
|
|
68
|
+
```arc42
|
|
69
|
+
:::quality-scenario
|
|
70
|
+
id: qs-no-request-before-click
|
|
71
|
+
title: No request to another host before a click
|
|
72
|
+
quality: qg-privacy
|
|
73
|
+
stimulus: lernapps check loads every page of the built app without clicking
|
|
74
|
+
response: Requests to other hosts are recorded; each one is an error of no-request-before-click
|
|
75
|
+
metric: 0 requests to another origin on every page before a click
|
|
76
|
+
:::
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## State stays on the device
|
|
80
|
+
|
|
81
|
+
An app's code that uses the browser's storage directly, sets a cookie or calls a network API is reported by the lint
|
|
82
|
+
rules on commit and by the component rules at build.
|
|
83
|
+
|
|
84
|
+
```arc42
|
|
85
|
+
:::quality-scenario
|
|
86
|
+
id: qs-state-on-device
|
|
87
|
+
title: Remembered state stays on the device
|
|
88
|
+
quality: qg-privacy
|
|
89
|
+
stimulus: A component stores progress with localStorage directly or sends it with fetch
|
|
90
|
+
response: storage-through-wrapper or vue-component-no-network reports it; the build's component rules fail on the network call
|
|
91
|
+
metric: 0 findings; all storage goes through createStorage under the prefix lernapps:<app>:
|
|
92
|
+
:::
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Broken content fails the build
|
|
96
|
+
|
|
97
|
+
What the creator wrote is validated against the archetype's schema or contract before any page is written.
|
|
98
|
+
|
|
99
|
+
```arc42
|
|
100
|
+
:::quality-scenario
|
|
101
|
+
id: qs-build-fails-per-line
|
|
102
|
+
title: A broken question bank, content or description fails the build
|
|
103
|
+
quality: qg-checkable
|
|
104
|
+
stimulus: The creator's assistant writes data that breaks the archetype's schema or a rule the schema cannot say
|
|
105
|
+
response: The build fails with one line per problem naming the file, the place and what to change
|
|
106
|
+
metric: 0 pages written from invalid data; every problem named in one line
|
|
107
|
+
:::
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## No WCAG violation found by axe
|
|
111
|
+
|
|
112
|
+
`lernapps check` runs axe-core for WCAG 2.1 A and AA on each page it visits. For an app whose entry declares its limits
|
|
113
|
+
the finding should become a warning; that is not built yet, so it is an error for every app today.
|
|
114
|
+
|
|
115
|
+
```arc42
|
|
116
|
+
:::quality-scenario
|
|
117
|
+
id: qs-axe-clean
|
|
118
|
+
title: axe finds no WCAG 2.1 A or AA violation
|
|
119
|
+
quality: qg-accessibility
|
|
120
|
+
stimulus: lernapps check visits the pages of the built app
|
|
121
|
+
response: Each axe violation is reported as an error of accessible, naming the page and element
|
|
122
|
+
metric: 0 axe violations of WCAG 2.1 A or AA on every page
|
|
123
|
+
:::
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Usable at 360 px
|
|
127
|
+
|
|
128
|
+
`lernapps check` measures each page in a 360 px wide window.
|
|
129
|
+
|
|
130
|
+
```arc42
|
|
131
|
+
:::quality-scenario
|
|
132
|
+
id: qs-usable-at-360px
|
|
133
|
+
title: No page wider than 360 px
|
|
134
|
+
quality: qg-accessibility
|
|
135
|
+
stimulus: lernapps check opens every page of the built app in a 360 px wide window
|
|
136
|
+
response: A wider page is an error of usable-at-360px, naming the elements that are too wide
|
|
137
|
+
metric: Page width at most 360 px on every page
|
|
138
|
+
:::
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Code no block claims
|
|
142
|
+
|
|
143
|
+
Not built yet (decided sketch, step 12, section 4): before a commit, `arc42 diff --staged --strict` compares the staged
|
|
144
|
+
code with the architecture; it matters for interactive apps, whose code is free.
|
|
145
|
+
|
|
146
|
+
```arc42
|
|
147
|
+
:::quality-scenario
|
|
148
|
+
id: qs-architecture-current
|
|
149
|
+
title: New code without a building block fails the commit
|
|
150
|
+
quality: qg-understandable
|
|
151
|
+
stimulus: An assistant stages new code under src/ that no building block claims, or a block changed without its prose
|
|
152
|
+
response: arc42 diff --staged --strict fails the commit and names the unclaimed path or the block
|
|
153
|
+
metric: 0 unclaimed paths under src/ at every commit, in about 0.2 s
|
|
154
|
+
:::
|
|
155
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Risks and Technical Debt
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
Arc42 chapter 11. Document known risks and areas of technical debt ordered by priority.
|
|
5
|
+
Risk management is about making technical risks visible to the people who need to act on them.
|
|
6
|
+
|
|
7
|
+
A risk is a known threat whose severity has not yet been fully mitigated.
|
|
8
|
+
Technical debt is a shortcut taken consciously or accidentally whose cost will have to be
|
|
9
|
+
paid later. Both belong here.
|
|
10
|
+
|
|
11
|
+
For each risk or debt item, write a ## section with a prose paragraph describing the risk,
|
|
12
|
+
its cause, its potential impact, and the current situation, followed by a DSL block.
|
|
13
|
+
|
|
14
|
+
The `mitigation` field describes the planned or accepted response. Even "accepted without
|
|
15
|
+
action until X" is a valid mitigation — it shows the team made a conscious choice.
|
|
16
|
+
|
|
17
|
+
Order entries by priority — highest risk first.
|
|
18
|
+
|
|
19
|
+
See https://docs.arc42.org/section-11/ for further guidance.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
|
|
23
|
+
## No Automated Performance Regression Tests
|
|
24
|
+
|
|
25
|
+
The performance quality goal has no automated gate in CI. Performance regressions can be
|
|
26
|
+
introduced without detection until a production incident occurs.
|
|
27
|
+
|
|
28
|
+
```arc42
|
|
29
|
+
:::risk
|
|
30
|
+
id: risk-no-perf-tests
|
|
31
|
+
title: No Automated Performance Regression Tests
|
|
32
|
+
severity: high
|
|
33
|
+
mitigation: Add k6 load test suite as a nightly CI job with a p95 threshold gate.
|
|
34
|
+
:::
|
|
35
|
+
```
|
|
36
|
+
-->
|
|
37
|
+
|
|
38
|
+
Risks and debt of the frame every lernapps app shares, highest first. Each extension adds its archetype's, and an
|
|
39
|
+
interactive app its own.
|
|
40
|
+
|
|
41
|
+
## Declared Accessibility Limits Not Built
|
|
42
|
+
|
|
43
|
+
An app may declare its limits in its entry and then get warnings instead of errors from `accessible` and
|
|
44
|
+
`usable-at-360px`; neither the entry field nor the warnings exist yet, so an app that deviates (a game against the
|
|
45
|
+
clock) fails `lernapps check` today.
|
|
46
|
+
|
|
47
|
+
```arc42
|
|
48
|
+
:::risk
|
|
49
|
+
id: risk-accessibility-limits-not-built
|
|
50
|
+
title: Declared accessibility limits not built
|
|
51
|
+
severity: medium
|
|
52
|
+
mitigation: Planned in the sketch (tooling step 2, lernapps/apps step 3); until then an app keeps both rules or cannot be listed.
|
|
53
|
+
:::
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Storage Quota Not Built
|
|
57
|
+
|
|
58
|
+
The quota of 100 kB per app is decided, but the storage wrapper has no limit: `save` succeeds until the browser
|
|
59
|
+
refuses, so one app can fill the origin's shared 5 MiB.
|
|
60
|
+
|
|
61
|
+
```arc42
|
|
62
|
+
:::risk
|
|
63
|
+
id: risk-storage-quota-not-built
|
|
64
|
+
title: Storage quota of 100 kB not built
|
|
65
|
+
severity: medium
|
|
66
|
+
mitigation: Build the quota into the tooling's storage wrapper, so that save refuses beyond 100 kB per app; until then apps keep only small values (the quiz's last result, the explainer's chosen way to the tutor).
|
|
67
|
+
:::
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Shared Origin Storage
|
|
71
|
+
|
|
72
|
+
Every app on lernapps.net shares one origin and so one `localStorage`. A learner who clears the site's data, or a
|
|
73
|
+
browser that evicts it, loses what every app remembered, and an app that picks another app's storage name reads and
|
|
74
|
+
overwrites its values.
|
|
75
|
+
|
|
76
|
+
```arc42
|
|
77
|
+
:::risk
|
|
78
|
+
id: risk-shared-origin-storage
|
|
79
|
+
title: Storage shared by every app of the origin
|
|
80
|
+
severity: medium
|
|
81
|
+
mitigation: Accepted (owner): apps keep only small data that may be lost, under their own prefix, and keep working with nothing remembered; the quota limits what one app takes.
|
|
82
|
+
:::
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Tutor Not Built for Quiz and Interactive Apps
|
|
86
|
+
|
|
87
|
+
The tutor is decided as a handoff to the learner's own assistant (`dec-tutor-variant`), but it is built only for the
|
|
88
|
+
explainer, so a quiz or an interactive app has no tutor yet.
|
|
89
|
+
|
|
90
|
+
```arc42
|
|
91
|
+
:::risk
|
|
92
|
+
id: risk-tutor-not-built
|
|
93
|
+
title: Tutor handoff not built for quiz and interactive apps
|
|
94
|
+
severity: medium
|
|
95
|
+
mitigation: Build the handoff with the exercise contract and task numbers from the explainer's parts; until then apps add no tutor of their own.
|
|
96
|
+
:::
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## arc42 Checks Not Wired
|
|
100
|
+
|
|
101
|
+
The architecture is meant to be kept current by `arc42 diff --staged --strict` before a commit and `arc42 validate` in
|
|
102
|
+
`lernapps check`; neither is wired into an app yet, so architecture and code can drift unnoticed. In
|
|
103
|
+
`lernapps/app-templates` the generic part and its extensions are validated in the pre-commit hook and in CI.
|
|
104
|
+
|
|
105
|
+
```arc42
|
|
106
|
+
:::risk
|
|
107
|
+
id: risk-arc42-checks-not-wired
|
|
108
|
+
title: arc42 checks not wired into the app
|
|
109
|
+
severity: medium
|
|
110
|
+
mitigation: Planned in the sketch (tooling step 2); until then the review reads the architecture against the code.
|
|
111
|
+
:::
|
|
112
|
+
```
|
|
113
|
+
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
Arc42 chapter 12. Define the domain and technical terms used in the architecture documentation.
|
|
5
|
+
A shared glossary reduces misunderstanding by ensuring all stakeholders use the same language.
|
|
6
|
+
If you work in multi-language teams, it also serves as a translation reference.
|
|
7
|
+
|
|
8
|
+
For each term, write a ## section with a prose paragraph providing context, etymology, or
|
|
9
|
+
extended explanation where useful, followed by a DSL block with a concise definition.
|
|
10
|
+
|
|
11
|
+
Keep the `definition` field to one or two sentences that unambiguously identify the concept.
|
|
12
|
+
Extended explanation belongs in the prose above the block.
|
|
13
|
+
|
|
14
|
+
If a short form is important, include it in the prose; the typed glossary block has no
|
|
15
|
+
`abbreviation` field.
|
|
16
|
+
|
|
17
|
+
Note synonyms the team has agreed NOT to use, and why, in the prose paragraph.
|
|
18
|
+
|
|
19
|
+
See https://docs.arc42.org/section-12/ for further guidance.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
|
|
23
|
+
## Bounded Context
|
|
24
|
+
|
|
25
|
+
A bounded context is a logical boundary within which a domain model is consistent and
|
|
26
|
+
unambiguous. Inside a bounded context, terms have precise, agreed meanings. The same word
|
|
27
|
+
may mean something different in another bounded context.
|
|
28
|
+
|
|
29
|
+
```arc42
|
|
30
|
+
:::glossary-term
|
|
31
|
+
id: term-bounded-context
|
|
32
|
+
title: Bounded Context
|
|
33
|
+
definition: A logical boundary within which a domain model, its language, and its rules are internally consistent. Defined in Domain-Driven Design (Evans, 2003).
|
|
34
|
+
:::
|
|
35
|
+
```
|
|
36
|
+
-->
|
|
37
|
+
|
|
38
|
+
Terms with a meaning specific to lernapps apps of every archetype. Learner-facing text is German; these terms are the
|
|
39
|
+
English names used in code, schemas and this architecture. Each extension adds its archetype's terms.
|
|
40
|
+
|
|
41
|
+
## Archetype
|
|
42
|
+
|
|
43
|
+
One of the kinds of app the generator can make, each a template folder of `lernapps/app-templates` with its runtime:
|
|
44
|
+
`quiz`, `explainer`, `interactive`.
|
|
45
|
+
|
|
46
|
+
```arc42
|
|
47
|
+
:::glossary-term
|
|
48
|
+
id: term-archetype
|
|
49
|
+
title: Archetype
|
|
50
|
+
definition: A kind of lernapps app (quiz, explainer, interactive) with its template and its runtime, which fixes what the creator writes.
|
|
51
|
+
:::
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Extension
|
|
55
|
+
|
|
56
|
+
Lives in the template folder's `docs/arc42/`; it references the generic ids and defines none of them again.
|
|
57
|
+
|
|
58
|
+
```arc42
|
|
59
|
+
:::glossary-term
|
|
60
|
+
id: term-extension
|
|
61
|
+
title: Extension
|
|
62
|
+
definition: The part of the architecture one archetype adds to the generic architecture, its blocks placed below the generic ones.
|
|
63
|
+
:::
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Runtime
|
|
67
|
+
|
|
68
|
+
The runtime of `@lernapps/app-templates`; together with the tooling helpers it forms the frame an app does not change.
|
|
69
|
+
|
|
70
|
+
```arc42
|
|
71
|
+
:::glossary-term
|
|
72
|
+
id: term-runtime
|
|
73
|
+
title: Runtime
|
|
74
|
+
definition: The shared code of every app of an archetype that builds its pages, checks it at build time and runs it in the browser; the app never edits it.
|
|
75
|
+
:::
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Shell
|
|
79
|
+
|
|
80
|
+
Started by the archetype's start function in `src/main.ts`: `startQuiz`, `startExplainer` or `startInteractive`.
|
|
81
|
+
|
|
82
|
+
```arc42
|
|
83
|
+
:::glossary-term
|
|
84
|
+
id: term-shell
|
|
85
|
+
title: Shell
|
|
86
|
+
definition: The runtime's code in the browser that turns the static pages into the live app.
|
|
87
|
+
:::
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Creator
|
|
91
|
+
|
|
92
|
+
The person who makes and lists an app on lernapps.net, usually working through an AI assistant.
|
|
93
|
+
|
|
94
|
+
```arc42
|
|
95
|
+
:::glossary-term
|
|
96
|
+
id: term-creator
|
|
97
|
+
title: Creator
|
|
98
|
+
definition: The person who builds an app and lists it in the app overview.
|
|
99
|
+
:::
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Start Page
|
|
103
|
+
|
|
104
|
+
`index.html` of each language. Not to be confused with the home page of lernapps.net.
|
|
105
|
+
|
|
106
|
+
```arc42
|
|
107
|
+
:::glossary-term
|
|
108
|
+
id: term-start-page
|
|
109
|
+
title: Start page
|
|
110
|
+
definition: The page at the app's address, rendered at build from what the creator wrote, from which every other page of the app is reached.
|
|
111
|
+
:::
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Seed
|
|
115
|
+
|
|
116
|
+
Taken from the address where the archetype uses one, else drawn at random.
|
|
117
|
+
|
|
118
|
+
```arc42
|
|
119
|
+
:::glossary-term
|
|
120
|
+
id: term-seed
|
|
121
|
+
title: Seed
|
|
122
|
+
definition: A positive integer from which the app draws everything random, so that the same address gives the same order, task or states.
|
|
123
|
+
:::
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Entry
|
|
127
|
+
|
|
128
|
+
The only way an app connects to the platform: its entry links to it. Its topics may point to the app's deep links, an
|
|
129
|
+
app that deviates from the accessibility default says so there, and its fact sheet states the app's size (not built
|
|
130
|
+
yet).
|
|
131
|
+
|
|
132
|
+
```arc42
|
|
133
|
+
:::glossary-term
|
|
134
|
+
id: term-entry
|
|
135
|
+
title: Entry
|
|
136
|
+
definition: The one YAML file per app in lernapps/apps entries/, checked against the entry schema, that lists the app in the app overview.
|
|
137
|
+
:::
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Catalog
|
|
141
|
+
|
|
142
|
+
Shown at lernapps.net/apps/; the owner decides whether an app is listed.
|
|
143
|
+
|
|
144
|
+
```arc42
|
|
145
|
+
:::glossary-term
|
|
146
|
+
id: term-catalog
|
|
147
|
+
title: Catalog
|
|
148
|
+
definition: The apps the app overview of lernapps.net provides, one entry per app.
|
|
149
|
+
:::
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Tutor
|
|
153
|
+
|
|
154
|
+
Optional; built for the explainer only; no model runs in the browser (see `dec-tutor-variant`).
|
|
155
|
+
|
|
156
|
+
```arc42
|
|
157
|
+
:::glossary-term
|
|
158
|
+
id: term-tutor
|
|
159
|
+
title: Tutor
|
|
160
|
+
definition: The learner's own AI assistant, to which the app hands the current task after a click, through a prompt and static tutor pages.
|
|
161
|
+
:::
|
|
162
|
+
```
|