@lernapps/app-templates 0.0.1 → 0.1.1

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.
Files changed (232) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +195 -2
  3. package/dist/appname-Bh23cUuz.mjs +12 -0
  4. package/dist/assessment-Dy359O1O.mjs +1696 -0
  5. package/dist/block-BK_ohsH1.mjs +82 -0
  6. package/dist/blocks-CxtCPAa5.mjs +149 -0
  7. package/dist/blocks.mjs +4 -0
  8. package/dist/check-CteIFN96.mjs +254 -0
  9. package/dist/content-DO6oEJxj.mjs +140 -0
  10. package/dist/contract-PONpxJtd.mjs +52 -0
  11. package/dist/e2e-CU0n_unV.mjs +89 -0
  12. package/dist/engine-CArxqizW.mjs +136 -0
  13. package/dist/explainer-e2e.mjs +1311 -0
  14. package/dist/explainer-islands.mjs +197 -0
  15. package/dist/explainer-plugin.mjs +2132 -0
  16. package/dist/explainer.mjs +1246 -0
  17. package/dist/html-mffkHGHh.mjs +89 -0
  18. package/dist/image-CspJVfyQ.mjs +21 -0
  19. package/dist/interactive-e2e.mjs +140 -0
  20. package/dist/interactive-plugin.mjs +242 -0
  21. package/dist/interactive.mjs +75 -0
  22. package/dist/load-RosvaPZf.mjs +16976 -0
  23. package/dist/needs-BzEahJ6X.mjs +97 -0
  24. package/dist/pages-9RaaomoO.mjs +81 -0
  25. package/dist/questions-e2e.mjs +1 -0
  26. package/dist/questions-engine.mjs +3 -0
  27. package/dist/questions.mjs +6 -0
  28. package/dist/quiz-DnW-xtCh.mjs +70 -0
  29. package/dist/quiz-e2e.mjs +174 -0
  30. package/dist/quiz-plugin.mjs +266 -0
  31. package/dist/quiz.mjs +246 -0
  32. package/dist/render-D5kwkNt1.mjs +507 -0
  33. package/dist/render-DqHOJyHK.mjs +146 -0
  34. package/dist/render-GS1Htlu8.mjs +545 -0
  35. package/dist/result-D_mmCVwN.mjs +180 -0
  36. package/dist/tasks-DADUYy52.mjs +74 -0
  37. package/dist/validate-BDwL7Su3.mjs +1076 -0
  38. package/dist/validate-Bxy9NfB8.mjs +146 -0
  39. package/dist/vue-DO1m6q1R.mjs +40 -0
  40. package/dist/vue-code-BkJjW_I_.mjs +320 -0
  41. package/docs/arc42/01-introduction-and-goals.arc42.md +82 -0
  42. package/docs/arc42/02-constraints.arc42.md +228 -0
  43. package/docs/arc42/03-system-context.arc42.md +118 -0
  44. package/docs/arc42/04-solution-strategy.arc42.md +47 -0
  45. package/docs/arc42/05-building-blocks.arc42.md +307 -0
  46. package/docs/arc42/06-runtime-view.arc42.md +98 -0
  47. package/docs/arc42/07-deployment-view.arc42.md +160 -0
  48. package/docs/arc42/08-concepts.arc42.md +123 -0
  49. package/docs/arc42/09-decisions.arc42.md +246 -0
  50. package/docs/arc42/10-quality-requirements.arc42.md +155 -0
  51. package/docs/arc42/11-risks.arc42.md +113 -0
  52. package/docs/arc42/12-glossary.arc42.md +162 -0
  53. package/docs/arc42/architecture-evidence.md +395 -0
  54. package/explainer/.arc42ignore +3 -0
  55. package/explainer/README.md +54 -0
  56. package/explainer/_gitignore +5 -0
  57. package/explainer/docs/arc42/03-explainer-system-context.arc42.md +35 -0
  58. package/explainer/docs/arc42/05-explainer-building-blocks.arc42.md +659 -0
  59. package/explainer/docs/arc42/06-explainer-runtime-view.arc42.md +105 -0
  60. package/explainer/docs/arc42/07-explainer-deployment-view.arc42.md +34 -0
  61. package/explainer/docs/arc42/08-explainer-concepts.arc42.md +17 -0
  62. package/explainer/docs/arc42/09-explainer-decisions.arc42.md +443 -0
  63. package/explainer/docs/arc42/10-explainer-quality-requirements.arc42.md +54 -0
  64. package/explainer/docs/arc42/11-explainer-risks.arc42.md +17 -0
  65. package/explainer/docs/arc42/12-explainer-glossary.arc42.md +185 -0
  66. package/explainer/e2e/explainer.e2e.ts +3 -0
  67. package/explainer/index.html +11 -0
  68. package/explainer/package.json +18 -0
  69. package/explainer/playwright.config.ts +1 -0
  70. package/explainer/src/app.yaml +20 -0
  71. package/explainer/src/components/ProzentFeld.test.ts +30 -0
  72. package/explainer/src/components/ProzentFeld.ts +121 -0
  73. package/explainer/src/components/ProzentFeld.vue +84 -0
  74. package/explainer/src/images/hunderterfeld-klammern.svg +105 -0
  75. package/explainer/src/main.ts +4 -0
  76. package/explainer/src/prozent/chapter.yaml +18 -0
  77. package/explainer/src/prozent/grundwert.yaml +115 -0
  78. package/explainer/src/prozent/prozentsatz.yaml +99 -0
  79. package/explainer/src/prozent/prozentwert.yaml +119 -0
  80. package/explainer/tsconfig.json +1 -0
  81. package/explainer/vite.config.ts +4 -0
  82. package/interactive/.arc42ignore +5 -0
  83. package/interactive/README.md +28 -0
  84. package/interactive/_gitignore +4 -0
  85. package/interactive/docs/arc42/05-interactive-building-blocks.arc42.md +518 -0
  86. package/interactive/docs/arc42/06-interactive-runtime-view.arc42.md +58 -0
  87. package/interactive/docs/arc42/07-interactive-deployment-view.arc42.md +35 -0
  88. package/interactive/docs/arc42/08-interactive-concepts.arc42.md +52 -0
  89. package/interactive/docs/arc42/09-interactive-decisions.arc42.md +130 -0
  90. package/interactive/docs/arc42/10-interactive-quality-requirements.arc42.md +45 -0
  91. package/interactive/docs/arc42/11-interactive-risks.arc42.md +20 -0
  92. package/interactive/docs/arc42/12-interactive-glossary.arc42.md +80 -0
  93. package/interactive/e2e/interactive.e2e.ts +3 -0
  94. package/interactive/index.html +11 -0
  95. package/interactive/package.json +18 -0
  96. package/interactive/playwright.config.ts +1 -0
  97. package/interactive/src/app.yaml +28 -0
  98. package/interactive/src/core/index.ts +101 -0
  99. package/interactive/src/data/lessons.json +4 -0
  100. package/interactive/src/env.d.ts +6 -0
  101. package/interactive/src/main.ts +6 -0
  102. package/interactive/src/messages/de.json +12 -0
  103. package/interactive/src/playthroughs/grundreihe.yaml +33 -0
  104. package/interactive/src/playthroughs/obere-reihe.yaml +14 -0
  105. package/interactive/src/ui/App.vue +85 -0
  106. package/interactive/tsconfig.json +1 -0
  107. package/interactive/vite.config.ts +4 -0
  108. package/package.json +143 -4
  109. package/quiz/README.md +31 -0
  110. package/quiz/_gitignore +5 -0
  111. package/quiz/docs/arc42/05-quiz-building-blocks.arc42.md +283 -0
  112. package/quiz/docs/arc42/06-quiz-runtime-view.arc42.md +21 -0
  113. package/quiz/docs/arc42/07-quiz-deployment-view.arc42.md +33 -0
  114. package/quiz/docs/arc42/09-quiz-decisions.arc42.md +36 -0
  115. package/quiz/docs/arc42/10-quiz-quality-requirements.arc42.md +53 -0
  116. package/quiz/docs/arc42/11-quiz-risks.arc42.md +19 -0
  117. package/quiz/docs/arc42/12-quiz-glossary.arc42.md +27 -0
  118. package/quiz/e2e/quiz.e2e.ts +3 -0
  119. package/quiz/index.html +11 -0
  120. package/quiz/package.json +18 -0
  121. package/quiz/playwright.config.ts +1 -0
  122. package/quiz/src/images/berge-ordnen.jpg +0 -0
  123. package/quiz/src/images/everest-hoehe.jpg +0 -0
  124. package/quiz/src/images/galapagos.jpg +0 -0
  125. package/quiz/src/images/grand-canyon.jpg +0 -0
  126. package/quiz/src/images/totes-meer.jpg +0 -0
  127. package/quiz/src/images/uluru.jpg +0 -0
  128. package/quiz/src/images/wasserfaelle-laender.jpg +0 -0
  129. package/quiz/src/main.ts +4 -0
  130. package/quiz/src/quiz.json +312 -0
  131. package/quiz/tsconfig.json +1 -0
  132. package/quiz/vite.config.ts +4 -0
  133. package/runtime/explainer/assessment-client.ts +478 -0
  134. package/runtime/explainer/assessment-page.ts +448 -0
  135. package/runtime/explainer/assessment.ts +393 -0
  136. package/runtime/explainer/check-page.ts +520 -0
  137. package/runtime/explainer/components/exercise.ts +409 -0
  138. package/runtime/explainer/components/props.ts +230 -0
  139. package/runtime/explainer/components/read.ts +428 -0
  140. package/runtime/explainer/content.ts +277 -0
  141. package/runtime/explainer/e2e.ts +1488 -0
  142. package/runtime/explainer/exercises.ts +326 -0
  143. package/runtime/explainer/explainer.css +1283 -0
  144. package/runtime/explainer/explainer.ts +838 -0
  145. package/runtime/explainer/explainer.v1.schema.json +1165 -0
  146. package/runtime/explainer/expression.ts +407 -0
  147. package/runtime/explainer/fraction.ts +107 -0
  148. package/runtime/explainer/generated/comparator.ts +31 -0
  149. package/runtime/explainer/generated/question.ts +165 -0
  150. package/runtime/explainer/generated/soundness.ts +280 -0
  151. package/runtime/explainer/generated/texts.ts +257 -0
  152. package/runtime/explainer/generated/types.ts +103 -0
  153. package/runtime/explainer/generated/values.ts +136 -0
  154. package/runtime/explainer/islands.ts +281 -0
  155. package/runtime/explainer/load.ts +457 -0
  156. package/runtime/explainer/messages/de.json +200 -0
  157. package/runtime/explainer/messages/en.json +200 -0
  158. package/runtime/explainer/messages.ts +13 -0
  159. package/runtime/explainer/needs.ts +122 -0
  160. package/runtime/explainer/open-task.ts +235 -0
  161. package/runtime/explainer/outline.ts +306 -0
  162. package/runtime/explainer/plugin.ts +488 -0
  163. package/runtime/explainer/position.ts +62 -0
  164. package/runtime/explainer/prompt.ts +75 -0
  165. package/runtime/explainer/render.ts +686 -0
  166. package/runtime/explainer/result.ts +238 -0
  167. package/runtime/explainer/routes.ts +119 -0
  168. package/runtime/explainer/schema.ts +140 -0
  169. package/runtime/explainer/scope.ts +87 -0
  170. package/runtime/explainer/stuck.ts +57 -0
  171. package/runtime/explainer/tasks.ts +109 -0
  172. package/runtime/explainer/tutor.ts +469 -0
  173. package/runtime/explainer/tutorpage.ts +669 -0
  174. package/runtime/explainer/video.ts +123 -0
  175. package/runtime/interactive/contract.ts +121 -0
  176. package/runtime/interactive/e2e.ts +190 -0
  177. package/runtime/interactive/interactive.css +82 -0
  178. package/runtime/interactive/interactive.ts +115 -0
  179. package/runtime/interactive/interactive.v1.schema.json +146 -0
  180. package/runtime/interactive/load.ts +188 -0
  181. package/runtime/interactive/messages/de.json +14 -0
  182. package/runtime/interactive/messages/en.json +14 -0
  183. package/runtime/interactive/messages.ts +11 -0
  184. package/runtime/interactive/playthrough.v1.schema.json +143 -0
  185. package/runtime/interactive/plugin.ts +266 -0
  186. package/runtime/interactive/render.ts +126 -0
  187. package/runtime/quiz/e2e.ts +233 -0
  188. package/runtime/quiz/engine.ts +242 -0
  189. package/runtime/quiz/messages/de.json +23 -0
  190. package/runtime/quiz/messages/en.json +23 -0
  191. package/runtime/quiz/plugin.ts +150 -0
  192. package/runtime/quiz/quiz.css +154 -0
  193. package/runtime/quiz/quiz.ts +56 -0
  194. package/runtime/quiz/quiz.v1.schema.json +72 -0
  195. package/runtime/quiz/render.ts +173 -0
  196. package/runtime/quiz/validate.ts +108 -0
  197. package/runtime/shared/appname.ts +16 -0
  198. package/runtime/shared/blocks/block.ts +162 -0
  199. package/runtime/shared/blocks/blocks.css +190 -0
  200. package/runtime/shared/blocks/blocks.v1.schema.json +432 -0
  201. package/runtime/shared/blocks/code.ts +26 -0
  202. package/runtime/shared/blocks/figures.ts +49 -0
  203. package/runtime/shared/blocks/image.ts +25 -0
  204. package/runtime/shared/blocks/index.ts +13 -0
  205. package/runtime/shared/blocks/messages/de.json +4 -0
  206. package/runtime/shared/blocks/messages/en.json +4 -0
  207. package/runtime/shared/blocks/render.ts +134 -0
  208. package/runtime/shared/blocks/validate.ts +165 -0
  209. package/runtime/shared/content.ts +197 -0
  210. package/runtime/shared/examples.ts +20 -0
  211. package/runtime/shared/html.ts +10 -0
  212. package/runtime/shared/languages.ts +94 -0
  213. package/runtime/shared/page.css +101 -0
  214. package/runtime/shared/pages.ts +114 -0
  215. package/runtime/shared/questions/e2e.ts +115 -0
  216. package/runtime/shared/questions/engine.ts +209 -0
  217. package/runtime/shared/questions/index.ts +39 -0
  218. package/runtime/shared/questions/messages/de.json +26 -0
  219. package/runtime/shared/questions/messages/en.json +26 -0
  220. package/runtime/shared/questions/question.ts +433 -0
  221. package/runtime/shared/questions/question.v1.schema.json +346 -0
  222. package/runtime/shared/questions/questions.css +192 -0
  223. package/runtime/shared/questions/render.ts +255 -0
  224. package/runtime/shared/questions/validate.ts +518 -0
  225. package/runtime/shared/schema.ts +44 -0
  226. package/runtime/shared/text/check.ts +68 -0
  227. package/runtime/shared/text/formula.ts +69 -0
  228. package/runtime/shared/text/markdown.ts +185 -0
  229. package/runtime/shared/text/speech.ts +39 -0
  230. package/runtime/shared/text/text.v1.schema.json +34 -0
  231. package/runtime/shared/vue-code.ts +395 -0
  232. package/runtime/shared/vue.ts +38 -0
@@ -0,0 +1,228 @@
1
+ # Architecture Constraints
2
+
3
+ <!--
4
+ Arc42 chapter 2. Document every requirement that limits your freedom of design and
5
+ implementation decisions. Constraints must always be dealt with — though some may be
6
+ negotiable. Architects need to know exactly where they have freedom and where they must adhere.
7
+
8
+ Constraints come from three sources:
9
+ - technical — technology standards, infrastructure mandates, platform restrictions
10
+ - organizational — legal requirements, compliance rules, budget limits, governance policies
11
+ - convention — agreed coding standards, naming rules, documentation or versioning guidelines
12
+
13
+ For each constraint, write a ## section with a prose paragraph explaining the constraint,
14
+ its origin, and its architectural impact, followed by a DSL block.
15
+
16
+ The `source` field names the origin — a legal document, client contract, governance policy,
17
+ or internal standard. Omit it if the origin is an internal assumption.
18
+
19
+ See https://docs.arc42.org/section-2/ for further guidance.
20
+
21
+ Example:
22
+
23
+ ## Personal Data Must Remain in the EU
24
+
25
+ All personally identifiable information must be stored and processed within the EU.
26
+ This limits which cloud regions, caching layers, and third-party SaaS tools are usable.
27
+ Origin: GDPR Art. 44, confirmed by legal review 2025-03-01.
28
+
29
+ ```arc42
30
+ :::constraint
31
+ id: con-data-residency
32
+ title: Personal Data Must Remain in the EU
33
+ category: organizational
34
+ source: GDPR Art. 44 / Legal review 2025-03-01
35
+ :::
36
+ ```
37
+ -->
38
+
39
+ ## Frontend Only, Static Pages
40
+
41
+ An app is static files served from its repo's GitHub Pages at `lernapps.net/<repo>/`; it has no server of its own
42
+ and shares no code at runtime with other apps. All logic runs in the learner's browser, and the build renders every
43
+ page ahead of time.
44
+
45
+ ```arc42
46
+ :::constraint
47
+ id: con-frontend-only
48
+ title: Frontend only, static pages
49
+ category: organizational
50
+ source: ORGANIZATION.md "What every site shares" and "Apps and the app overview"; decided sketch, step 12
51
+ :::
52
+ ```
53
+
54
+ ## No Request Before a Click, No Tracking
55
+
56
+ No page sets a cookie, tracks, or requests anything from another server before the learner clicks; the privacy
57
+ notice of lernapps.net states this for every app. So fonts, libraries and data are bundled, and anything that leaves
58
+ the device (a tutor handoff, a link) waits for a click. `lernapps check` verifies it on the built app.
59
+
60
+ ```arc42
61
+ :::constraint
62
+ id: con-no-request-before-click
63
+ title: No request before a click, no tracking
64
+ category: organizational
65
+ source: ORGANIZATION.md "Every page, in every repo"; lernapps check rules no-request-before-click and no-tracking
66
+ :::
67
+ ```
68
+
69
+ ## TypeScript on vite-plus, Vue for Components
70
+
71
+ Every app is TypeScript built with vite-plus and the shared preset of `@lernapps/tooling`. Where an app has
72
+ components of its own (an explainer's components, an interactive app's UI), they are Vue single-file components, so
73
+ one set of component rules, lint rules and `vue-tsc` holds for every app; the quiz has none.
74
+
75
+ ```arc42
76
+ :::constraint
77
+ id: con-vue-typescript
78
+ title: TypeScript on vite-plus, Vue for components
79
+ category: technical
80
+ source: Decided sketch, step 12, section 2; owner, 2026-10-16, conversation (Vue is fixed); skill lernapps-app rule strict-typescript
81
+ :::
82
+ ```
83
+
84
+ ## Component Rules
85
+
86
+ The app's components and the modules they import are checked on the SFC compiler's output at build: no network
87
+ APIs, no `eval`, `new Function`, `innerHTML` or `v-html`, imports only from Vue, the runtime, the tooling's storage,
88
+ i18n and a11y helpers and the app's own files (an interactive app's also from the libraries in its dependencies,
89
+ never from a URL), and browser globals only once mounted, because the build renders without a browser.
90
+
91
+ ```arc42
92
+ :::constraint
93
+ id: con-component-rules
94
+ title: Component rules checked at build
95
+ category: technical
96
+ source: Decided sketch, step 12, section 2; runtime/explainer/components.ts; runtime/interactive/plugin.ts
97
+ :::
98
+ ```
99
+
100
+ ## The Runtime Is Not Changed by the App
101
+
102
+ The frame and the archetype's runtime come from `@lernapps/app-templates`, and the app does not change them; the app
103
+ writes only what its archetype allows (the quiz its question bank, the explainer its content, the interactive app its
104
+ core, UI, data, playthroughs, messages and description). Changes to the runtime reach the app as dependency updates.
105
+
106
+ ```arc42
107
+ :::constraint
108
+ id: con-runtime-unchanged
109
+ title: The app does not change the runtime
110
+ category: convention
111
+ source: Decided sketch, step 12, sections 3 and 4; skill rules quiz-only-data, explainer-only-content, keep-the-preset
112
+ :::
113
+ ```
114
+
115
+ ## State Only on the Device
116
+
117
+ What an app remembers stays in the learner's browser, under its own key prefix, through the tooling's storage
118
+ wrapper; there are no accounts and no server state. The learner's settings that hold for every app or for every app
119
+ of an archetype are kept under `lernapps:settings:` and `lernapps:settings:<archetype>:`, which every app, or every
120
+ app of that archetype, may read and write; an app's own setting wins. Storage may be blocked or full at any time, so the app must keep
121
+ working and simply remember nothing.
122
+
123
+ ```arc42
124
+ :::constraint
125
+ id: con-state-on-device
126
+ title: State only on the device, through the storage wrapper
127
+ category: technical
128
+ source: Decided sketch, step 12, section 4; @lernapps/tooling archetypes/shared/storage.ts; lint rule storage-through-wrapper
129
+ :::
130
+ ```
131
+
132
+ ## Small Storage with a Quota
133
+
134
+ All apps share the 5 MiB of `localStorage` of the one origin lernapps.net, so each app may keep at most 100 kB and
135
+ `save` refuses beyond it. The quota is decided but not built yet: the wrapper has no limit today.
136
+
137
+ ```arc42
138
+ :::constraint
139
+ id: con-storage-quota
140
+ title: Small storage with a quota of 100 kB per app
141
+ category: technical
142
+ source: Owner, 2026-10-16, conversation; decided sketch, step 12, section 3
143
+ :::
144
+ ```
145
+
146
+ ## Accessibility: Platform Rule, App Default
147
+
148
+ WCAG 2.1 AA and use at 360 px are rules for the platform's own pages; an app follows them by default and may
149
+ deviate where its idea needs it, for example a typing game against the clock, declaring what it does not offer in its
150
+ entry. Pages the runtime renders from the creator's data meet both in any case. Low stimulation is advice only. The
151
+ warnings for an app with declared limits are not built yet: `accessible` and `usable-at-360px` are errors for every
152
+ app today.
153
+
154
+ ```arc42
155
+ :::constraint
156
+ id: con-accessibility-default
157
+ title: WCAG 2.1 AA and 360 px by default, deviations declared
158
+ category: organizational
159
+ source: ORGANIZATION.md "Every page, in every repo"; decided sketch, step 12, section 5; owner, 2026-10-16, conversation
160
+ :::
161
+ ```
162
+
163
+ ## German for Learners, English for Infrastructure
164
+
165
+ Text for learners, teachers and parents is German (further languages may be declared); shared infrastructure,
166
+ identifiers, schemas and developer docs are English, and so is this architecture. Inside its own repo, an app's author
167
+ decides the language of names.
168
+
169
+ ```arc42
170
+ :::constraint
171
+ id: con-language
172
+ title: German for learner text, English for infrastructure
173
+ category: convention
174
+ source: ORGANIZATION.md "Language"; owner, 2026-10-16, conversation (architecture in English)
175
+ :::
176
+ ```
177
+
178
+ ## Bundled Libraries with Accepted Licences
179
+
180
+ A library an app uses is bundled, never loaded from a CDN, and its licence and those of its dependencies must be on
181
+ the allowlist of the `dependency-licence` check (MIT, Apache-2.0, BSD and similar). The app's own repo is MIT;
182
+ third-party content keeps its licence and is named next to it.
183
+
184
+ ```arc42
185
+ :::ignore H006 an organisation rule that lernapps check verifies (dependency-licence); no architecture decision responds to it
186
+ :::
187
+ :::constraint
188
+ id: con-bundled-licences
189
+ title: Bundled libraries under accepted licences
190
+ category: organizational
191
+ source: Decided sketch, step 12, section 2; ORGANIZATION.md "License"; lernapps check rule dependency-licence
192
+ :::
193
+ ```
194
+
195
+ ## Imprint and Privacy Notice
196
+
197
+ Every page links to the imprint and the privacy notice of lernapps.net; the runtime renders both links in the footer
198
+ of its pages.
199
+
200
+ ```arc42
201
+ :::ignore H006 an organisation rule the runtime meets in the footer of its pages; no architecture decision responds to it
202
+ :::
203
+ :::constraint
204
+ id: con-imprint-privacy
205
+ title: Links to imprint and privacy notice
206
+ category: organizational
207
+ source: ORGANIZATION.md "Every page, in every repo"; decided sketch, step 12, section 3
208
+ :::
209
+ ```
210
+
211
+ ## Architecture Kept Current
212
+
213
+ The architecture lives in the arc42 DSL: this generic part at the root of `lernapps/app-templates` and one extension
214
+ per archetype in its template folder. An app gets both in its `docs/arc42/`; only an interactive app, whose code is
215
+ free, adds a part of its own; the creator's assistant updates and validates it with every change, without a
216
+ checkpoint with the creator. `arc42 diff --staged --strict` before a commit
217
+ and `arc42 validate` in `lernapps check` are decided but not wired into the app's hooks and check yet; the copying of
218
+ the architecture into an app is not built yet either. In `lernapps/app-templates` itself, `scripts/arc42.ts` validates
219
+ the generic part with each extension strictly, in the pre-commit hook and in CI.
220
+
221
+ ```arc42
222
+ :::constraint
223
+ id: con-architecture-current
224
+ title: Architecture in docs/arc42, kept current
225
+ category: convention
226
+ source: Decided sketch, step 12, section 4; owner, 2026-10-16 (generic architecture plus one extension per archetype)
227
+ :::
228
+ ```
@@ -0,0 +1,118 @@
1
+ # System Scope and Context
2
+
3
+ The system is one lernapps app of any archetype: the frame runtime, the tooling helpers and the archetype part,
4
+ built into static pages. Outside it are the people who use or write the app and the few systems it meets: the host
5
+ that serves it, the app overview that links to it and, where an archetype has the optional tutor, the learner's own
6
+ assistant (in that archetype's extension). Each actor requires an interface of chapter 5: the pages or, for the
7
+ creator's assistant, what the archetype lets it write, the check command and the skills.
8
+
9
+ ## Context diagram
10
+
11
+ The creator's assistant writes the archetype's content and follows the skills; every other actor meets the built
12
+ pages at the boundary.
13
+
14
+ ```arc42
15
+ :::diagram
16
+ id: system-context
17
+ view: context
18
+ notation: mermaid
19
+ :::
20
+ ```
21
+
22
+ ```mermaid
23
+ flowchart LR
24
+ actor-learner["Learner"]
25
+ actor-teacher-parent["Teachers and parents"]
26
+ actor-creator-assistant["Creator and their AI assistant"]
27
+ actor-github-pages["GitHub Pages"]
28
+ actor-app-overview["lernapps.net app overview"]
29
+ subgraph system["lernapps app"]
30
+ bb-render["Page rendering (the archetype's)"]
31
+ bb-tooling["Tooling helpers"]
32
+ bb-skills["Skills"]
33
+ end
34
+ actor-learner -->|"if-pages: reads and learns on the pages"| system
35
+ actor-teacher-parent -->|"if-pages: reads the pages"| system
36
+ actor-creator-assistant -->|"if-archetype-content, if-lernapps-check, if-skills: writes, checks, follows the skills"| system
37
+ actor-github-pages -->|"if-pages: serves the built pages"| system
38
+ actor-app-overview -->|"if-pages: links to the pages and deep links"| system
39
+ ```
40
+
41
+ ## Learner
42
+
43
+ Adults and students, often in German schools, who learn in the browser, with keyboard, pointer, touch or other
44
+ input, without an account;
45
+ what the app remembers stays on their device.
46
+
47
+ ```arc42
48
+ :::actor
49
+ id: actor-learner
50
+ title: Learner
51
+ type: person
52
+ description: Reads the pages and learns on them in the browser, without an account
53
+ requires: if-pages
54
+ :::
55
+ ```
56
+
57
+ ## Teachers and parents
58
+
59
+ They read the pages and the app's entry to see what the app teaches and whether it may be used; they need the pages
60
+ in German.
61
+
62
+ ```arc42
63
+ :::actor
64
+ id: actor-teacher-parent
65
+ title: Teachers and parents
66
+ type: person
67
+ description: Read the pages to see what the app teaches and what it does not offer
68
+ requires: if-pages
69
+ :::
70
+ ```
71
+
72
+ ## Creator and their AI assistant
73
+
74
+ The creator's AI assistant writes what the archetype lets it write, runs the checks and follows the skill
75
+ `lernapps-app` and its archetype's skill (each extension names it); the creator decides and lists the app.
76
+
77
+ OPEN: No interface is modelled for `vp build` and `vp dev`, which the assistant also runs; should there be one?
78
+
79
+ ```arc42
80
+ :::actor
81
+ id: actor-creator-assistant
82
+ title: Creator and their AI assistant
83
+ type: system
84
+ description: Writes the archetype's content, runs lernapps check and follows the skills
85
+ requires: if-archetype-content, if-lernapps-check, if-skills
86
+ :::
87
+ ```
88
+
89
+ ## GitHub Pages
90
+
91
+ The app is static files published from its repo's `gh-pages` branch to `lernapps.net/<repo>/`: the pages the build
92
+ rendered and the bundle; there is no server of the app's own, and pull requests get a preview.
93
+
94
+ ```arc42
95
+ :::actor
96
+ id: actor-github-pages
97
+ title: GitHub Pages
98
+ type: system
99
+ description: Serves the built pages and bundle of the app at lernapps.net/<repo>/
100
+ requires: if-pages
101
+ :::
102
+ ```
103
+
104
+ ## lernapps.net app overview
105
+
106
+ The app connects to the platform only through its entry in the app overview, which links to the app's pages and,
107
+ through its topics, to its deep links; `entry-links-resolve` checks that these links answer. The entry's fact sheet
108
+ also states the app's size (not built yet).
109
+
110
+ ```arc42
111
+ :::actor
112
+ id: actor-app-overview
113
+ title: lernapps.net app overview
114
+ type: system
115
+ description: Lists the app with one entry whose URL and topic links point to its pages and deep links
116
+ requires: if-pages
117
+ :::
118
+ ```
@@ -0,0 +1,47 @@
1
+ # Solution Strategy
2
+
3
+ Opinionated where it makes the rules checkable, free where the learning happens: a fixed frame (the runtime of
4
+ `@lernapps/app-templates` and the tooling helpers) that the app does not change, and inside it the archetype's part.
5
+ The quiz and the explainer are generic: the runtime ships their whole part and the creator only feeds it with data.
6
+ An interactive app's part is free code against a few small contracts. The build, the end-to-end tests and
7
+ `lernapps check` verify all three.
8
+
9
+ ```arc42
10
+ :::solution-strategy
11
+ id: strategy-fixed-frame-free-app
12
+ title: Fixed, checked frame around the archetype's part
13
+ addresses: qg-privacy, qg-checkable, qg-accessibility, qg-understandable
14
+ :::
15
+ ```
16
+
17
+ | Quality goal | Approach |
18
+ | --- | --- |
19
+ | `qg-privacy` | Static pages without a server; libraries, fonts and data bundled; state only through the storage wrapper on the device; component rules and lint rules forbid network APIs; `lernapps check` sees no request before a click. |
20
+ | `qg-checkable` | What the creator writes is data under a JSON Schema or code under a contract; the build validates it and fails with one line per problem; each archetype's end-to-end tests derive their cases from it; seeds in the address make random parts replayable. |
21
+ | `qg-accessibility` | The runtime renders the pages and brings the announcer and focus helpers; axe and 360 px are checked on the built app; an app that cannot meet them declares its limits in its entry. |
22
+ | `qg-understandable` | One generic architecture and one extension per archetype, English and minimal; fixed folders and contracts, so an interactive app's own blocks go below its extension's. |
23
+
24
+ ## System decomposition
25
+
26
+ Three generic roots, the shared runtime (`bb-runtime`: page trees, languages, examples check, Vue at build), the
27
+ tooling helpers (`bb-tooling`: preset, lint rules, `lernapps check`, storage, i18n, a11y) and the skills the app
28
+ commits (`bb-skills`); each
29
+ archetype's extension adds its runtime (`bb-archetype-runtime`, which builds the pages, runs the build checks, starts
30
+ the archetype's code in the browser in `bb-shell` and brings the end-to-end tests) and the parts the creator writes,
31
+ each a root of its own, so that an interactive app can add its own blocks below them.
32
+
33
+ ## Technology and communication approach
34
+
35
+ TypeScript on vite-plus, and Vue for an app's own components (`con-vue-typescript`), so one set of component rules
36
+ holds. Every page is rendered at build and served statically (`con-frontend-only`); deep links and seeds live in the
37
+ address, so the app overview can link to them. The app talks to nothing outside the browser; anything that would leave
38
+ the device, such as the optional tutor handoff to the learner's own assistant, waits for a click
39
+ (`con-no-request-before-click`); no model runs in the browser.
40
+
41
+ ## Operational approach
42
+
43
+ Rules are checked by machine, not by review: the build fails on content or code that breaks the archetype's schema or
44
+ contract; the end-to-end tests and `lernapps check` run before a push. The app's size is not limited; it is stated in
45
+ the app's catalog entry. The runtime and tooling reach the app as dependency updates, never as edits
46
+ (`con-runtime-unchanged`). The architecture is kept current in `docs/arc42/` (`con-architecture-current`); its
47
+ pre-commit diff and validation are decided but not built yet.