@lernapps/app-templates 0.0.1 → 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.
Files changed (231) 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-By2GGTJC.mjs +1696 -0
  5. package/dist/block-BK_ohsH1.mjs +82 -0
  6. package/dist/blocks-BmRrD7UY.mjs +149 -0
  7. package/dist/blocks.mjs +4 -0
  8. package/dist/check-BkEl-m-F.mjs +254 -0
  9. package/dist/content-cYBPYg_J.mjs +140 -0
  10. package/dist/contract-PONpxJtd.mjs +52 -0
  11. package/dist/e2e-BiMI-pCL.mjs +89 -0
  12. package/dist/engine-BqF2Vffn.mjs +136 -0
  13. package/dist/explainer-e2e.mjs +1297 -0
  14. package/dist/explainer-islands.mjs +197 -0
  15. package/dist/explainer-plugin.mjs +2131 -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-C-0hUaSC.mjs +16947 -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-BKc8JYtC.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-BJey0bwl.mjs +540 -0
  33. package/dist/render-BL6fV_NI.mjs +507 -0
  34. package/dist/render-DpRO_RKm.mjs +146 -0
  35. package/dist/result-_eQcamoz.mjs +180 -0
  36. package/dist/tasks-DADUYy52.mjs +74 -0
  37. package/dist/validate-COaZso7u.mjs +1072 -0
  38. package/dist/validate-CxtdeQ5S.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 +142 -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 +446 -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 +1474 -0
  142. package/runtime/explainer/exercises.ts +324 -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 +299 -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 +430 -0
  221. package/runtime/shared/questions/question.v1.schema.json +342 -0
  222. package/runtime/shared/questions/questions.css +192 -0
  223. package/runtime/shared/questions/render.ts +247 -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/text.v1.schema.json +34 -0
  230. package/runtime/shared/vue-code.ts +395 -0
  231. package/runtime/shared/vue.ts +38 -0
@@ -0,0 +1,307 @@
1
+ # Building Blocks
2
+
3
+ The generic part has three roots that every app shares, whatever its archetype: the shared runtime of
4
+ `@lernapps/app-templates`, the tooling helpers of `@lernapps/tooling` and the skills the app commits. Each archetype's extension adds the rest of
5
+ level 1 (`quiz/docs/arc42/`, `explainer/docs/arc42/`, `interactive/docs/arc42/`): its runtime `bb-archetype-runtime`
6
+ with the parts `bb-build`, `bb-validation`, `bb-render`, `bb-shell`, `bb-e2e` and `bb-runtime-texts`, which every
7
+ extension defines under these ids, and the parts the creator writes, one of which provides `if-archetype-content`.
8
+ Parts that only some archetypes have (component rules, question types, tutor handoff, task numbers, exercise contract)
9
+ are in the extensions that use them. Not built and not in the frame now: a loading indicator (`dec-no-size-limit`) and
10
+ a settings dialog (`dec-no-settings`).
11
+
12
+ Paths are relative to the root of `lernapps/app-templates`. The parts in a template folder carry their path with the
13
+ folder as prefix (`interactive/src/core`); an app that gets this architecture as a copy has them without it
14
+ (`src/core`). An app's architecture is this part followed by its archetype's extension, chapter by chapter; so the
15
+ level-1 view of a whole app is in its extension.
16
+
17
+ ## Level 1: the generic roots
18
+
19
+ ```arc42
20
+ :::diagram
21
+ id: building-blocks-generic
22
+ view: building-block
23
+ notation: mermaid
24
+ :::
25
+ ```
26
+
27
+ ```mermaid
28
+ flowchart TB
29
+ subgraph bb-runtime["Shared runtime (runtime/shared)"]
30
+ bb-blocks["Content blocks (runtime/shared/blocks)"]
31
+ bb-questions["Questions (runtime/shared/questions)"]
32
+ bb-component-rules["Component rules (runtime/shared/vue-code.ts)"]
33
+ end
34
+ bb-tooling["Tooling helpers (@lernapps/tooling)"]
35
+ bb-skills["Skills (.agents/skills)"]
36
+ ```
37
+
38
+ ## Shared runtime
39
+
40
+ Built. The code the archetypes' runtimes share: the page trees, German at the root and every other language below
41
+ `/<language>/`, with alternates, a language switch of plain links and the 404 page, which leads every address the
42
+ app does not have to its start page (`pages.ts`); learner texts by language (`languages.ts`); the examples check,
43
+ which runs an exercise's accepted and rejected examples through the check the page uses, for the quiz and the
44
+ explainer (`examples.ts`); the content as YAML, with its problems placed at file, line and path, the errors of a schema
45
+ as problems and the checks of the texts (`content.ts`); restricted Markdown and formulas (`text/`); the checks of the
46
+ code of Vue components (`vue-code.ts`); HTML escaping (`html.ts`); the frame of every page, with its colours in the light and the dark scheme, its header with the language switch and its footer (`page.css`, `pages.ts`); the content blocks (`blocks/`); the questions, their six types with checker, schema, validation, rendering, engine, end-to-end
47
+ helpers and texts, which the quiz and the explainer's exercises both use (`questions/`); Vue at build for the archetypes with components (`vue.ts`); and the app's name, the prefix
48
+ of what it stores (`appname.ts`). The app never edits it.
49
+
50
+ ```arc42
51
+ :::building-block
52
+ id: bb-runtime
53
+ title: Shared runtime
54
+ path: runtime/shared
55
+ technology: TypeScript
56
+ implements: concept-languages, concept-readable-without-js
57
+ :::
58
+ ```
59
+
60
+ ### Shared runtime modules
61
+
62
+ The archetype's runtime imports them at build and in its tests.
63
+
64
+ ```arc42
65
+ :::interface
66
+ id: if-shared-runtime
67
+ title: Page trees, languages, examples check, Vue at build
68
+ provider: bb-runtime
69
+ protocol: TypeScript imports (runtime/shared)
70
+ path: runtime/shared
71
+ :::
72
+ ```
73
+
74
+ ### Content blocks
75
+
76
+ Built in the shared runtime, for every archetype that shows content with its questions or on its pages: prose, a
77
+ formula, a figure (drawn from data, or a bundled image of `src/images/`), a labelled figure, a table, a quotation and
78
+ program code, with the credit of an image or a quotation. Their types, their schema, their checks (what the schema
79
+ cannot say, every text complete in the declared languages), their rendering at build and their look; the quiz shows
80
+ them as the `material` of a question, the explainer as blocks of a page.
81
+
82
+ ```arc42
83
+ :::building-block
84
+ id: bb-blocks
85
+ title: Content blocks
86
+ parent: bb-runtime
87
+ path: runtime/shared/blocks
88
+ technology: TypeScript
89
+ :::
90
+ ```
91
+
92
+ #### Content blocks interface
93
+
94
+ The validation and the rendering of an archetype with content blocks use their types, checks and renderer.
95
+
96
+ ```arc42
97
+ :::interface
98
+ id: if-blocks
99
+ title: The content blocks (checkMaterial, renderMaterial, materialIn)
100
+ provider: bb-blocks
101
+ protocol: TypeScript imports (runtime/shared/blocks), @lernapps/app-templates/blocks
102
+ path: runtime/shared/blocks
103
+ :::
104
+ ```
105
+
106
+ ### Questions
107
+
108
+ Built in the shared runtime, for every archetype that has questions: the six question types and what counts as a right
109
+ answer, at build, in the browser and in the tests alike, with their schema, validation, rendering, engine, end-to-end
110
+ helpers and texts. The quiz asks them; the explainer's quiz-type exercises and the answers of its generated exercises
111
+ use the same. Neither archetype imports the other.
112
+
113
+ ```arc42
114
+ :::building-block
115
+ id: bb-questions
116
+ title: Questions
117
+ parent: bb-runtime
118
+ path: runtime/shared/questions
119
+ technology: TypeScript
120
+ :::
121
+ ```
122
+
123
+ #### Questions interface
124
+
125
+ The validation, the rendering, the client module and the tests of an archetype with questions use their types,
126
+ rendering, engine and checker.
127
+
128
+ ```arc42
129
+ :::interface
130
+ id: if-questions
131
+ title: The question types, rendering, engine and checker
132
+ provider: bb-questions
133
+ protocol: TypeScript imports (runtime/shared/questions), @lernapps/app-templates/questions
134
+ path: runtime/shared/questions
135
+ :::
136
+ ```
137
+
138
+ ### Component rules
139
+
140
+ Built in the shared runtime, for every archetype that has Vue components: code checks on the SFC compiler's output of a
141
+ component and the modules of the app it imports (no network, no `eval`, `innerHTML` or `v-html`, imports only from Vue,
142
+ the runtime, the storage, i18n and a11y helpers and the app's own modules, never from a URL, browser globals only once
143
+ mounted). Which modules are the app's own is the archetype's scope: the explainer's components import their own folder,
144
+ the interactive archetype's any file of `src/` and the libraries of its `package.json`.
145
+
146
+ ```arc42
147
+ :::building-block
148
+ id: bb-component-rules
149
+ title: Component rules
150
+ parent: bb-runtime
151
+ path: runtime/shared/vue-code.ts
152
+ technology: TypeScript, Vue SFC compiler
153
+ implements: concept-component-rules
154
+ :::
155
+ ```
156
+
157
+ #### Component rules interface
158
+
159
+ The validation of an archetype with components runs the checks on its components.
160
+
161
+ ```arc42
162
+ :::interface
163
+ id: if-component-rules
164
+ title: The code checks of a component (codeProblems, with the archetype's scope)
165
+ provider: bb-component-rules
166
+ protocol: TypeScript imports (runtime/shared/vue-code.ts)
167
+ path: runtime/shared/vue-code.ts
168
+ :::
169
+ ```
170
+
171
+ ## Tooling helpers
172
+
173
+ Built. The parts of `@lernapps/tooling` every app uses, so that rules, helpers and guidance reach the app through
174
+ updates without edits: the preset (`archetypes/shared/preset.ts`: lint with the lernapps rules, type check, format,
175
+ unit tests, the pre-commit staged files, a build with relative URLs); the lint rules (`lint/rules`: learner texts
176
+ German, no request before a click, storage through the wrapper, the Vue component rules); `lernapps check` (`check/`:
177
+ accessible, usable at 360 px, no request before a click, no tracking, links and entry links resolve, and the
178
+ end-to-end tests before a push); the Playwright configuration (`archetypes/shared/playwright.ts`: Chromium at desktop
179
+ width and 360 px on a free port); the small storage (`archetypes/shared/storage.ts`); the announcer and focus helpers
180
+ (`archetypes/shared/a11y.ts`); and i18n (`archetypes/shared/i18n.ts`). The skills are a block of their own
181
+ (`bb-skills`), which the tooling's `skills/` folder is the source of. A large storage (IndexedDB) is left out (`dec-small-storage`).
182
+
183
+ ```arc42
184
+ :::ignore H014 @lernapps/tooling is installed in node_modules (node_modules/@lernapps/tooling), which git does not track, and the validator resolves paths only among tracked files (E011)
185
+ :::
186
+ :::building-block
187
+ id: bb-tooling
188
+ title: Tooling helpers
189
+ technology: TypeScript, vite-plus, Playwright (@lernapps/tooling, an optional peer of this package)
190
+ implements: concept-accessibility, concept-component-rules, concept-device-storage, concept-languages, concept-readable-without-js
191
+ :::
192
+ ```
193
+
194
+ ### Preset interface
195
+
196
+ The app's vite.config.ts calls `lernapps({ plugins: [<archetype>()] })`; the archetype's runtime uses the preset for
197
+ its own Vite servers.
198
+
199
+ ```arc42
200
+ :::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/preset.ts)
201
+ :::
202
+ :::interface
203
+ id: if-preset
204
+ title: lernapps() preset
205
+ provider: bb-tooling
206
+ protocol: TypeScript import, @lernapps/tooling/preset
207
+ :::
208
+ ```
209
+
210
+ ### Check command
211
+
212
+ The creator's assistant, the pre-push hook and CI run `lernapps check`; its report names each rule that failed.
213
+ `arc42 validate` in the check is decided, not built.
214
+
215
+ ```arc42
216
+ :::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (check/)
217
+ :::
218
+ :::interface
219
+ id: if-lernapps-check
220
+ title: lernapps check command
221
+ provider: bb-tooling
222
+ protocol: CLI, validation report
223
+ :::
224
+ ```
225
+
226
+ ### Device storage interface
227
+
228
+ Load, save and remove JSON values through `createStorage`, under the app's prefix in `localStorage`; every access is
229
+ wrapped, so the app keeps working when storage is blocked or full. The decided quota of 100 kB per app is not built.
230
+
231
+ ```arc42
232
+ :::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/storage.ts)
233
+ :::
234
+ :::interface
235
+ id: if-device-storage
236
+ title: createStorage(app)
237
+ provider: bb-tooling
238
+ protocol: TypeScript import, @lernapps/tooling/storage
239
+ :::
240
+ ```
241
+
242
+ ### Accessibility helpers interface
243
+
244
+ Announcements through the polite live region, focus moves and the reduced-motion query; the end-to-end tests read the
245
+ same live region.
246
+
247
+ ```arc42
248
+ :::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/a11y.ts)
249
+ :::
250
+ :::interface
251
+ id: if-a11y
252
+ title: announce, moveFocus, prefersReducedMotion
253
+ provider: bb-tooling
254
+ protocol: TypeScript import, @lernapps/tooling/a11y
255
+ :::
256
+ ```
257
+
258
+ ### Translator interface
259
+
260
+ Code that shows learner texts gets them through `translator(messages)`, never as strings in code.
261
+
262
+ ```arc42
263
+ :::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/i18n.ts)
264
+ :::
265
+ :::interface
266
+ id: if-translator
267
+ title: translator(messages)
268
+ provider: bb-tooling
269
+ protocol: TypeScript import, @lernapps/tooling/i18n
270
+ :::
271
+ ```
272
+
273
+ ## Skills
274
+
275
+ Built in the tooling, one folder per skill. An app commits its skills under `.agents/skills/`: `lernapps-app` for
276
+ every app; the archetype's skill (`lernapps-quiz`, `lernapps-explainer` or `lernapps-interactive`); the content
277
+ skills (`lernapps-content-research`, `lernapps-exercise-patterns`, `lernapps-content-growth`); `lernapps-listing`;
278
+ and the app's own content guide `app-content`. `lernapps update` installs and replaces the `lernapps-*` skills from
279
+ the tooling's `skills/` folder and leaves the app's own alone. They hold the guidance no check can make
280
+ (`dec-skill-interface`).
281
+
282
+ ```arc42
283
+ :::ignore H014 the skills are committed in each app under .agents/skills; this repository has none
284
+ :::
285
+ :::building-block
286
+ id: bb-skills
287
+ title: Skills
288
+ technology: Markdown skills (SKILL.md), from the skills/ folder of @lernapps/tooling
289
+ implements: concept-low-stimulation
290
+ :::
291
+ ```
292
+
293
+ ### Skills interface
294
+
295
+ The creator's assistant loads `lernapps-app` when it starts work on an app, and its archetype's skill and the content
296
+ skills before it writes what the archetype lets it write.
297
+
298
+ ```arc42
299
+ :::ignore H014 the skills are committed in each app under .agents/skills; this repository has none
300
+ :::
301
+ :::interface
302
+ id: if-skills
303
+ title: Skill texts (lernapps-app, the archetype's skill, the content skills, app-content)
304
+ provider: bb-skills
305
+ protocol: Markdown (SKILL.md) loaded by the assistant
306
+ :::
307
+ ```
@@ -0,0 +1,98 @@
1
+ # Runtime View
2
+
3
+ Six scenarios every app shares: opening its pages, learning in the browser, an error path of the device storage,
4
+ the assistant working with the skills, building with the checks, and the end-to-end tests before a push and in CI. Each extension adds its archetype's own
5
+ scenarios (the explainer's include asking the tutor).
6
+
7
+ ## Opening the pages
8
+
9
+ A learner, teacher or parent opens `lernapps.net/<app>/`. The host serves static pages the build rendered from what
10
+ the creator wrote; what a page shows without JavaScript depends on the archetype and is in its extension (an
11
+ interactive app's app page shows only a `<noscript>` note). The language switch and the alternates are plain links to
12
+ the same page in the other language tree; an address the app does not have gets the 404 page, which leads to the
13
+ start page.
14
+
15
+ ```arc42
16
+ :::runtime-scenario
17
+ id: scenario-pages
18
+ title: Opening the pages
19
+ trigger: A learner, teacher or parent opens the app's address
20
+ involves: bb-render, bb-runtime
21
+ :::
22
+ ```
23
+
24
+ ## Learning in the browser
25
+
26
+ The page loads the app's client module; `src/main.ts` calls the archetype's start function, which takes a seed from
27
+ the address where the archetype draws anything at random, shows the learner's progress, announces changes through the
28
+ live region and moves the focus to the feedback. Its texts come in the page's language.
29
+
30
+ ```arc42
31
+ :::runtime-scenario
32
+ id: scenario-learn
33
+ title: Learning in the browser
34
+ trigger: The learner opens a page with JavaScript and answers, practises or plays
35
+ involves: bb-shell, bb-tooling
36
+ :::
37
+ ```
38
+
39
+ ## Remembering on the device, storage blocked or full
40
+
41
+ An app that remembers something loads and saves JSON values through the storage wrapper, under its own prefix in
42
+ `localStorage`. When the browser blocks storage or it is full, `load` gives nothing and `save` returns false; the app
43
+ keeps working and remembers nothing. The decided quota of 100 kB, beyond which `save` refuses, is not built yet.
44
+
45
+ ```arc42
46
+ :::runtime-scenario
47
+ id: scenario-device-storage
48
+ title: Remembering on the device, storage blocked or full
49
+ trigger: The archetype's code loads or saves a value
50
+ involves: bb-shell, bb-tooling
51
+ :::
52
+ ```
53
+
54
+ ## Working with the skills
55
+
56
+ The creator's assistant loads the skills the app commits under `.agents/skills/` (`lernapps-app`, the archetype's
57
+ skill, the content skills and the app's own `app-content`), writes what the archetype lets it write and runs
58
+ `lernapps check`. `lernapps update` replaces the `lernapps-*` skills with those of the tooling.
59
+
60
+ ```arc42
61
+ :::runtime-scenario
62
+ id: scenario-skills
63
+ title: Working with the skills
64
+ trigger: The creator's assistant starts work on the app
65
+ involves: bb-skills, bb-tooling
66
+ :::
67
+ ```
68
+
69
+ ## Building with the checks
70
+
71
+ `vp build` (and `vp dev` on each request) runs the archetype's plugin inside the tooling preset. It validates what
72
+ the creator wrote, runs the archetype's checks (the component rules on any Vue components, the examples through the
73
+ checker where the archetype has them), and only then writes every page in every language, with the shared page trees
74
+ and the runtime's texts, and the 404 page. Any problem fails the build with one line per problem.
75
+
76
+ ```arc42
77
+ :::runtime-scenario
78
+ id: scenario-build
79
+ title: Building with the checks
80
+ trigger: The creator, a git hook or CI runs the build
81
+ involves: bb-tooling, bb-archetype-runtime, bb-build, bb-validation, bb-render, bb-runtime-texts, bb-runtime
82
+ :::
83
+ ```
84
+
85
+ ## End-to-end tests before a push
86
+
87
+ `lernapps check --pre-push`, run by the pre-push hook and by CI, serves the built app on a free port and runs the
88
+ archetype's tests in Chromium at desktop width and at 360 px, with reduced motion, with cases derived from what the
89
+ creator wrote. `lernapps check` adds axe, the width check and the request check on the pages it visits.
90
+
91
+ ```arc42
92
+ :::runtime-scenario
93
+ id: scenario-e2e
94
+ title: End-to-end tests before a push
95
+ trigger: The pre-push hook or CI runs lernapps check --pre-push
96
+ involves: bb-tooling, bb-e2e, bb-render, bb-shell, bb-runtime-texts
97
+ :::
98
+ ```
@@ -0,0 +1,160 @@
1
+ # Deployment View
2
+
3
+ ## Deployment overview
4
+
5
+ Every app is static files: it is built and checked on the creator's machine and again in CI, published to its repo's
6
+ GitHub Pages and run entirely in the learner's browser. There is no server of the app's own; what the app remembers
7
+ stays in the browser's `localStorage`. A pull request gets a preview of the same files. Each extension adds nodes
8
+ below these for its archetype's blocks at build and in the browser; blocks not built yet are listed where they would
9
+ run.
10
+
11
+ Every app gets the same generated Pages workflow (app check, publish, preview) in step 2 of the plan. It is built for
12
+ the explainer and quiz archetypes; the tooling does not have the interactive archetype yet, so an interactive app has
13
+ no generated workflow today. The templates themselves are checked by the CI of `lernapps/app-templates`. The diagram
14
+ shows one representative block per node; each node's section lists all it hosts.
15
+
16
+ ```arc42
17
+ :::diagram
18
+ id: deployment-overview
19
+ view: deployment
20
+ notation: mermaid-architecture
21
+ :::
22
+ ```
23
+
24
+ ```mermaid
25
+ architecture-beta
26
+ group env-development(server)[Development]
27
+ group dn-creator-machine(server)[Creator machine] in env-development
28
+ group env-ci(cloud)[CI]
29
+ group dn-ci-runner(server)[GitHub Actions runner] in env-ci
30
+ group env-production(internet)[Production and preview]
31
+ group dn-github-pages(cloud)[GitHub Pages] in env-production
32
+ group dn-pr-preview(cloud)[Pull request preview] in env-production
33
+ group dn-learner-browser(internet)[Learner browser] in env-production
34
+ service bb-tooling(server)[Preset, hooks and lernapps check] in dn-creator-machine
35
+ service bb-build(server)[Build step] in dn-ci-runner
36
+ service bb-render(disk)[Rendered pages] in dn-github-pages
37
+ service bb-runtime(disk)[Page trees] in dn-pr-preview
38
+ service bb-shell(server)[Shell] in dn-learner-browser
39
+ bb-tooling:R --> L:bb-build
40
+ bb-build:R --> L:bb-render
41
+ bb-build:B --> T:bb-runtime
42
+ bb-render:R --> L:bb-shell
43
+ ```
44
+
45
+ ## Development
46
+
47
+ The creator's machine, where the creator's AI assistant writes the app.
48
+
49
+ ```arc42
50
+ :::deployment-node
51
+ id: env-development
52
+ title: Development
53
+ type: environment
54
+ :::
55
+ ```
56
+
57
+ ## Creator's machine
58
+
59
+ `vp dev` serves the pages, rendered on each request. The git hooks the preset installs run the checks before a commit
60
+ (format, lint, type check) and before a push (unit tests, build, checks of the built app, end-to-end tests, in
61
+ Chromium). The assistant loads the skills here. A template folder inside `lernapps/app-templates` gets no hooks of
62
+ its own.
63
+
64
+ ```arc42
65
+ :::deployment-node
66
+ id: dn-creator-machine
67
+ title: Creator's machine
68
+ type: device
69
+ parent: env-development
70
+ hosts: bb-tooling, bb-skills, bb-runtime, bb-questions, bb-blocks, bb-component-rules, bb-build, bb-validation, bb-render, bb-runtime-texts, bb-e2e
71
+ :::
72
+ ```
73
+
74
+ ## CI
75
+
76
+ GitHub Actions of the app's repo, on every push and pull request.
77
+
78
+ ```arc42
79
+ :::deployment-node
80
+ id: env-ci
81
+ title: CI
82
+ type: environment
83
+ :::
84
+ ```
85
+
86
+ ## GitHub Actions runner
87
+
88
+ The job `app` runs `lernapps check`, the same command as the hooks, and keeps the checked bundle; on `main` the job
89
+ `deploy` publishes it, on a pull request from the repo the job `preview` publishes it as a preview. A change of only
90
+ the plan or only docs checks and publishes nothing.
91
+
92
+ ```arc42
93
+ :::deployment-node
94
+ id: dn-ci-runner
95
+ title: GitHub Actions runner
96
+ type: server
97
+ parent: env-ci
98
+ hosts: bb-tooling, bb-runtime, bb-questions, bb-blocks, bb-component-rules, bb-build, bb-validation, bb-render, bb-runtime-texts, bb-e2e
99
+ :::
100
+ ```
101
+
102
+ ## Production and preview
103
+
104
+ lernapps.net as learners reach it.
105
+
106
+ ```arc42
107
+ :::deployment-node
108
+ id: env-production
109
+ title: Production and preview
110
+ type: environment
111
+ :::
112
+ ```
113
+
114
+ ## GitHub Pages
115
+
116
+ The `gh-pages` branch of the app's repo, served from its root at `lernapps.net/<repo>/` (only a repo of the lernapps
117
+ organisation is served there; any other at its own Pages address). It serves the rendered pages in every language,
118
+ the 404 page, the tutor pages where the tutor is built, and the bundle; the preset builds with relative URLs, so the
119
+ app works under any path.
120
+
121
+ ```arc42
122
+ :::deployment-node
123
+ id: dn-github-pages
124
+ title: GitHub Pages
125
+ type: server
126
+ parent: env-production
127
+ hosts: bb-render, bb-runtime, bb-questions, bb-blocks, bb-component-rules
128
+ :::
129
+ ```
130
+
131
+ ## Pull request preview
132
+
133
+ The same files below `pr-preview/pr-<number>/` of the app's address, not indexed by search engines, removed when the
134
+ pull request is closed.
135
+
136
+ ```arc42
137
+ :::deployment-node
138
+ id: dn-pr-preview
139
+ title: Pull request preview
140
+ type: server
141
+ parent: env-production
142
+ hosts: bb-render, bb-runtime, bb-questions, bb-blocks, bb-component-rules
143
+ :::
144
+ ```
145
+
146
+ ## Learner's browser
147
+
148
+ Runs the app's client module: the shell with the archetype's code and the tooling's helpers. `localStorage` of the
149
+ one origin lernapps.net holds what the app remembers, under the app's prefix; nothing leaves the device before a
150
+ click.
151
+
152
+ ```arc42
153
+ :::deployment-node
154
+ id: dn-learner-browser
155
+ title: Learner's browser
156
+ type: device
157
+ parent: env-production
158
+ hosts: bb-shell, bb-tooling
159
+ :::
160
+ ```
@@ -0,0 +1,123 @@
1
+ # Cross-cutting Concepts
2
+
3
+ The concepts every lernapps app implements, whatever its archetype. The extensions add their archetype's concepts
4
+ (the explainer's tutor; the interactive app's core and shell, playthroughs, hash routes).
5
+
6
+ ## Generic architecture and extensions
7
+
8
+ The archetypes stay separate but share their quality goals, so they share this architecture: the generic part defines
9
+ the shared runtime and the tooling helpers and what every app keeps, and each archetype's extension in its template
10
+ folder adds its runtime and the parts its creator writes, under ids the generic part names (`bb-archetype-runtime`,
11
+ `bb-build`, `bb-render`, `bb-shell`, `bb-e2e`, `if-archetype-content`, …), with its interfaces, decisions, risks and
12
+ terms. An app's architecture is the generic part followed by its archetype's extension, chapter by chapter; an
13
+ interactive app adds its own blocks below its extension's parts in the same way. The building blocks reach two levels,
14
+ roots and their parts, so that every interface can be drawn in a view.
15
+
16
+ ```arc42
17
+ :::concept
18
+ id: concept-archetype-extension
19
+ title: Generic architecture plus one extension per archetype
20
+ category: structure
21
+ :::
22
+ ```
23
+
24
+ ## Determinism by the seed in the address
25
+
26
+ Whatever an app draws at random comes from a seed in the address, so the same address gives the same order, task or
27
+ round, and a learner, a teacher, a tutor and the tests can open it again: the quiz's order of questions, the
28
+ explainer's tasks by their numbers, an interactive core's states. Each extension says how its archetype uses the seed.
29
+
30
+ ```arc42
31
+ :::concept
32
+ id: concept-determinism
33
+ title: Determinism by the seed in the address
34
+ category: testing
35
+ :::
36
+ ```
37
+
38
+ ## Readable without JavaScript
39
+
40
+ Every app has static pages that describe it without JavaScript: links, the language switch and the footer are plain
41
+ links, and what needs JavaScript says so in a `<noscript>` note. How much of an app reads without JavaScript depends on
42
+ its archetype: for the quiz and the explainer it is a quality goal of their extensions; an interactive app's start
43
+ page reads without JavaScript, its app page does not.
44
+
45
+ ```arc42
46
+ :::concept
47
+ id: concept-readable-without-js
48
+ title: Readable without JavaScript
49
+ category: accessibility
50
+ :::
51
+ ```
52
+
53
+ ## Languages
54
+
55
+ Every page exists once per declared language, German at the root and others below `/<language>/`, and an app may
56
+ declare only languages its runtime has texts for. Learner texts are language maps in the creator's data or message
57
+ files by language, reached through the translator, never strings in code.
58
+
59
+ ```arc42
60
+ :::concept
61
+ id: concept-languages
62
+ title: Languages
63
+ category: i18n
64
+ :::
65
+ ```
66
+
67
+ ## Accessibility by default
68
+
69
+ Pages meet WCAG 2.1 AA and work at 360 px by default; an app that cannot declares its limits in its entry, and only
70
+ then would its findings become warnings (not built yet: they are errors for every app today). Feedback goes through
71
+ the polite live region and the focus moves with the a11y helpers, and `lernapps check` runs axe and the width check on
72
+ the built pages.
73
+
74
+ ```arc42
75
+ :::concept
76
+ id: concept-accessibility
77
+ title: Accessibility by default, deviations declared
78
+ category: accessibility
79
+ :::
80
+ ```
81
+
82
+ ## Component rules
83
+
84
+ An app's own Vue components (the explainer's components, the interactive UI) and the modules they import are checked
85
+ on the SFC compiler's output at build and by lint rules: no network, no `eval`, `new Function`, `innerHTML` or
86
+ `v-html`, imports only from Vue, the runtime, the storage, i18n and a11y helpers and the app's own files (an
87
+ interactive app's also from the libraries in its dependencies, never from a URL), browser globals only once mounted.
88
+
89
+ ```arc42
90
+ :::concept
91
+ id: concept-component-rules
92
+ title: Component rules
93
+ category: security
94
+ :::
95
+ ```
96
+
97
+ ## Device storage
98
+
99
+ What an app remembers goes through the storage wrapper into `localStorage`, under the prefix `lernapps:<app>:`,
100
+ because all apps share one origin; every access is wrapped, so blocked or full storage means the app remembers
101
+ nothing and keeps working. The quota of 100 kB per app is decided, not built.
102
+
103
+ ```arc42
104
+ :::concept
105
+ id: concept-device-storage
106
+ title: Device storage
107
+ category: persistence
108
+ :::
109
+ ```
110
+
111
+ ## Low stimulation (advice)
112
+
113
+ Advice, not a rule or check: the skills recommend no flashing, calm motion and sound off by default, and say why
114
+ (children, attention, seizures); the creator's assistant follows them. Today the skill `lernapps-interactive` gives
115
+ this advice. A settings dialog (less motion, sound, pause) is not in scope now (`dec-no-settings`).
116
+
117
+ ```arc42
118
+ :::concept
119
+ id: concept-low-stimulation
120
+ title: Low stimulation (advice)
121
+ category: accessibility
122
+ :::
123
+ ```