@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.
- package/LICENSE +22 -0
- package/README.md +195 -2
- package/dist/appname-Bh23cUuz.mjs +12 -0
- package/dist/assessment-Dy359O1O.mjs +1696 -0
- package/dist/block-BK_ohsH1.mjs +82 -0
- package/dist/blocks-CxtCPAa5.mjs +149 -0
- package/dist/blocks.mjs +4 -0
- package/dist/check-CteIFN96.mjs +254 -0
- package/dist/content-DO6oEJxj.mjs +140 -0
- package/dist/contract-PONpxJtd.mjs +52 -0
- package/dist/e2e-CU0n_unV.mjs +89 -0
- package/dist/engine-CArxqizW.mjs +136 -0
- package/dist/explainer-e2e.mjs +1311 -0
- package/dist/explainer-islands.mjs +197 -0
- package/dist/explainer-plugin.mjs +2132 -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-RosvaPZf.mjs +16976 -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-DnW-xtCh.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-D5kwkNt1.mjs +507 -0
- package/dist/render-DqHOJyHK.mjs +146 -0
- package/dist/render-GS1Htlu8.mjs +545 -0
- package/dist/result-D_mmCVwN.mjs +180 -0
- package/dist/tasks-DADUYy52.mjs +74 -0
- package/dist/validate-BDwL7Su3.mjs +1076 -0
- package/dist/validate-Bxy9NfB8.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 +143 -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 +448 -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 +1488 -0
- package/runtime/explainer/exercises.ts +326 -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 +306 -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 +433 -0
- package/runtime/shared/questions/question.v1.schema.json +346 -0
- package/runtime/shared/questions/questions.css +192 -0
- package/runtime/shared/questions/render.ts +255 -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/speech.ts +39 -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,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.
|