@dzhechkov/keysarium 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -10
- package/bin/cli.js +0 -0
- package/package.json +5 -3
- package/src/utils.js +1 -1
- package/templates/.claude/commands/analyst-manual.md +38 -0
- package/templates/.claude/commands/brain-export.md +2 -0
- package/templates/.claude/commands/bto-benchmark.md +302 -0
- package/templates/.claude/commands/casarium.md +55 -4
- package/templates/.claude/commands/feature-adr.md +8 -0
- package/templates/.claude/commands/harvest.md +28 -46
- package/templates/.claude/rules/trust-tiers.md +6 -0
- package/templates/.claude/shards/feature-adr.shard.md +64 -10
- package/templates/.claude/shards/phase-ai-factory.shard.md +109 -0
- package/templates/.claude/skills/ai-factory-mapper/README.md +90 -0
- package/templates/.claude/skills/ai-factory-mapper/SKILL.md +309 -0
- package/templates/.claude/skills/ai-factory-mapper/assets/report-template.md +123 -0
- package/templates/.claude/skills/ai-factory-mapper/references/catalog.md +230 -0
- package/templates/.claude/skills/ai-factory-mapper/references/coverage-formula.md +219 -0
- package/templates/.claude/skills/ai-factory-mapper/references/decomposition-checklist.md +183 -0
- package/templates/.claude/skills/ai-factory-mapper/references/pattern-library.md +312 -0
- package/templates/.claude/skills/ai-factory-mapper/scripts/build_docx_report.js +423 -0
- package/templates/.claude/skills/analyst-manual-full/SKILL.md +286 -0
- package/templates/.claude/skills/edu-site-generator/SKILL.md +254 -0
- package/templates/.claude/skills/edu-site-generator/examples/sample-course-structure.md +116 -0
- package/templates/.claude/skills/edu-site-generator/modules/00-content-analysis.md +84 -0
- package/templates/.claude/skills/edu-site-generator/modules/01-course-structure.md +75 -0
- package/templates/.claude/skills/edu-site-generator/modules/02-data-generation.md +186 -0
- package/templates/.claude/skills/edu-site-generator/modules/03-scaffold.md +249 -0
- package/templates/.claude/skills/edu-site-generator/modules/04-components.md +130 -0
- package/templates/.claude/skills/edu-site-generator/modules/05-gamification.md +163 -0
- package/templates/.claude/skills/edu-site-generator/modules/06-deploy.md +88 -0
- package/templates/.claude/skills/edu-site-generator/modules/07-verification.md +97 -0
- package/templates/.claude/skills/edu-site-generator/references/component-templates.md +436 -0
- package/templates/.claude/skills/edu-site-generator/references/data-schemas.md +164 -0
- package/templates/.claude/skills/edu-site-generator/references/exercise-catalog.md +110 -0
- package/templates/.claude/skills/edu-site-generator/references/tech-stack.md +69 -0
- package/templates/.claude/skills/feature-adr/SKILL.md +245 -59
- package/templates/.claude/skills/feature-adr/modules/03-adr.md +43 -0
- package/templates/.claude/skills/feature-adr/modules/03.5-ideation-swarm.md +180 -0
- package/templates/.claude/skills/feature-adr/modules/06-implementation-plan.md +56 -7
- package/templates/.claude/skills/feature-adr/modules/08-qe.md +87 -23
- package/templates/.claude/skills/feature-adr/modules/09-fleet-qe.md +305 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/README.md +143 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/brutal-honesty-review.md +240 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/chaos-engineering-resilience.md +163 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/code-goal-planner.md +446 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/enterprise-integration-testing.md +111 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/mutation-testing.md +236 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/performance-testing.md +315 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qcsd-ideation-swarm.md +126 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qcsd-production-swarm.md +108 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qe-coverage-analysis.md +193 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qe-requirements-validation.md +254 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/regression-testing.md +233 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/risk-based-testing.md +212 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/security-testing.md +311 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/shift-left-testing.md +231 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/tdd-london-chicago.md +249 -0
- package/templates/.claude/skills/knowledge-extractor/SKILL.md +254 -0
- package/templates/.claude/skills/knowledge-extractor/modules/01-extract.md +188 -0
- package/templates/.claude/skills/knowledge-extractor/modules/02-classify.md +99 -0
- package/templates/.claude/skills/knowledge-extractor/modules/03-gate.md +150 -0
- package/templates/.claude/skills/knowledge-extractor/modules/04-integrate.md +159 -0
- package/templates/.claude/skills/knowledge-extractor/references/artifact-categories.md +100 -0
- package/templates/.claude/skills/knowledge-extractor/references/maturity-model.md +94 -0
- package/templates/.claude/skills/knowledge-extractor/references/quality-gates.md +98 -0
- package/templates/.claude/skills/knowledge-extractor/templates/artifact-card.md +63 -0
- package/templates/.claude/skills/knowledge-extractor/templates/harvest-report.md +102 -0
- package/templates/.claude/skills/transcript-site-generator/SKILL.md +287 -0
- package/templates/.claude/skills/transcript-site-generator/examples/sample-text-only-site.md +123 -0
- package/templates/.claude/skills/transcript-site-generator/examples/sample-transcript-site.md +134 -0
- package/templates/.claude/skills/transcript-site-generator/modules/00-input-analysis.md +132 -0
- package/templates/.claude/skills/transcript-site-generator/modules/01-content-parsing.md +117 -0
- package/templates/.claude/skills/transcript-site-generator/modules/02-site-generation.md +293 -0
- package/templates/.claude/skills/transcript-site-generator/modules/03-interactivity.md +406 -0
- package/templates/.claude/skills/transcript-site-generator/modules/04-deploy.md +130 -0
- package/templates/.claude/skills/transcript-site-generator/modules/05-verification.md +155 -0
- package/templates/.claude/skills/transcript-site-generator/references/component-catalog.md +86 -0
- package/templates/.claude/skills/transcript-site-generator/references/data-schemas.md +123 -0
- package/templates/.claude/skills/transcript-site-generator/references/tech-stack.md +132 -0
- package/templates/CLAUDE.md +30 -9
- package/templates/docs/continuous-learning-guide.md +622 -0
- package/templates/docs/edu-site-generator/01-deployment-guide.md +911 -0
- package/templates/docs/edu-site-generator/02-admin-guide.md +901 -0
- package/templates/docs/edu-site-generator/03-user-guide.md +1008 -0
- package/templates/docs/edu-site-generator/04-infrastructure-requirements.md +489 -0
- package/templates/docs/edu-site-generator/05-architecture.md +902 -0
- package/templates/docs/edu-site-generator/06-user-flows.md +759 -0
- package/templates/docs/improvement-directions.md +8 -4
- package/templates/docs/keysarium-core/02-functionality.md +3 -1
- package/templates/docs/skills-bto/01-deployment-guide.md +1 -1
- package/templates/docs/skills-bto/02-admin-guide.md +4 -1
- package/templates/docs/skills-bto/03-user-guide.md +4 -3
- package/templates/docs/skills-bto/04-infrastructure-requirements.md +2 -1
- package/templates/docs/skills-bto/05-architecture.md +11 -11
- package/templates/docs/skills-bto/06-user-flows.md +2 -1
- package/templates/docs/transcript-site-generator/01-deployment-guide.md +1042 -0
- package/templates/docs/transcript-site-generator/02-admin-guide.md +918 -0
- package/templates/docs/transcript-site-generator/03-user-guide.md +925 -0
- package/templates/docs/transcript-site-generator/04-infrastructure-requirements.md +482 -0
- package/templates/docs/transcript-site-generator/05-architecture.md +1068 -0
- package/templates/docs/transcript-site-generator/06-user-flows.md +855 -0
- package/templates/lib/dream-engine.md +1 -1
- package/templates/lib/memory-protocol.md +6 -2
- package/templates/lib/reward-tracker.md +6 -3
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Step 4: Components
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Generate all React components: layout, interactive exercises, sections, pages, and common utilities.
|
|
5
|
+
|
|
6
|
+
## Protocol
|
|
7
|
+
|
|
8
|
+
Read `references/component-templates.md` for full component code.
|
|
9
|
+
|
|
10
|
+
### Generation Order
|
|
11
|
+
|
|
12
|
+
1. **Layout components** (no dependencies on data):
|
|
13
|
+
- `Header.jsx` — sticky top bar with title, score, progress %, dark mode toggle, nav toggle, final test link
|
|
14
|
+
- `Footer.jsx` — bottom bar with copyright, optional social link
|
|
15
|
+
- `Navigation.jsx` — sidebar with section links (uses `scrollIntoView` NOT `<a href="#...">` to avoid HashRouter conflicts)
|
|
16
|
+
- `ProgressBar.jsx` — visual bar showing course progress
|
|
17
|
+
- `SectionLayout.jsx` — wrapper for each section: icon, title, description, completion badge, theory, children
|
|
18
|
+
|
|
19
|
+
2. **Interactive components** (reusable, data-driven):
|
|
20
|
+
- `Quiz.jsx` — multiple choice with score tracking
|
|
21
|
+
- `Flashcard.jsx` — flip cards for term memorization
|
|
22
|
+
- `MatchingExercise.jsx` — pair matching with shuffle
|
|
23
|
+
- `DragOrder.jsx` — drag-and-drop ordering (@dnd-kit)
|
|
24
|
+
- `CommandBuilder.jsx` — click-to-build command
|
|
25
|
+
- `ScenarioGame.jsx` — multi-step scenario with choices
|
|
26
|
+
|
|
27
|
+
3. **Common components:**
|
|
28
|
+
- `Accordion.jsx` — expandable FAQ items
|
|
29
|
+
- `AchievementsPanel.jsx` — grid of achievement badges
|
|
30
|
+
- `Toast.jsx` — notification popup for achievements
|
|
31
|
+
- `useSwipeNav.js` — custom hook for swipe gesture navigation between sections (mobile). Uses native touch events (touchstart/touchend), 50px threshold, horizontal only. No external dependencies.
|
|
32
|
+
```jsx
|
|
33
|
+
// src/hooks/useSwipeNav.js
|
|
34
|
+
import { useRef, useEffect } from 'react'
|
|
35
|
+
|
|
36
|
+
export default function useSwipeNav(sectionIds, containerRef) {
|
|
37
|
+
const touchStart = useRef(null)
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const el = containerRef?.current || document
|
|
41
|
+
function onTouchStart(e) { touchStart.current = e.touches[0].clientX }
|
|
42
|
+
function onTouchEnd(e) {
|
|
43
|
+
if (touchStart.current === null) return
|
|
44
|
+
const diff = touchStart.current - e.changedTouches[0].clientX
|
|
45
|
+
if (Math.abs(diff) < 50) return // threshold
|
|
46
|
+
const currentIdx = sectionIds.findIndex(id =>
|
|
47
|
+
document.getElementById(id)?.getBoundingClientRect().top >= -100
|
|
48
|
+
)
|
|
49
|
+
if (currentIdx === -1) return
|
|
50
|
+
const nextIdx = diff > 0
|
|
51
|
+
? Math.min(currentIdx + 1, sectionIds.length - 1) // swipe left → next
|
|
52
|
+
: Math.max(currentIdx - 1, 0) // swipe right → prev
|
|
53
|
+
document.getElementById(sectionIds[nextIdx])?.scrollIntoView({ behavior: 'smooth' })
|
|
54
|
+
touchStart.current = null
|
|
55
|
+
}
|
|
56
|
+
el.addEventListener('touchstart', onTouchStart, { passive: true })
|
|
57
|
+
el.addEventListener('touchend', onTouchEnd, { passive: true })
|
|
58
|
+
return () => {
|
|
59
|
+
el.removeEventListener('touchstart', onTouchStart)
|
|
60
|
+
el.removeEventListener('touchend', onTouchEnd)
|
|
61
|
+
}
|
|
62
|
+
}, [sectionIds, containerRef])
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
Usage in `HomePage.jsx`: `useSwipeNav(SECTIONS.map(s => s.id))`
|
|
66
|
+
|
|
67
|
+
4. **Section components** (one per section):
|
|
68
|
+
- `Section1.jsx` through `SectionN.jsx`
|
|
69
|
+
- Each follows the pattern:
|
|
70
|
+
```jsx
|
|
71
|
+
import SectionLayout from '../layout/SectionLayout'
|
|
72
|
+
import {InteractiveComponent} from '../interactive/{Component}'
|
|
73
|
+
import { useAppStore } from '../../store/useAppStore'
|
|
74
|
+
import { SECTIONS } from '../../data/sections'
|
|
75
|
+
import { exerciseData } from '../../data/exercises' // or quizQuestions
|
|
76
|
+
|
|
77
|
+
const section = SECTIONS[INDEX]
|
|
78
|
+
|
|
79
|
+
export default function SectionN() {
|
|
80
|
+
const markComplete = useAppStore((s) => s.markSectionComplete)
|
|
81
|
+
return (
|
|
82
|
+
<SectionLayout {...section} theory={section.theory}>
|
|
83
|
+
<InteractiveComponent
|
|
84
|
+
{...data}
|
|
85
|
+
onComplete={(score) => markComplete(section.id, score)}
|
|
86
|
+
/>
|
|
87
|
+
</SectionLayout>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
5. **Page components:**
|
|
93
|
+
- `HomePage.jsx` — main page with Navigation sidebar, all sections, AchievementsPanel, FAQ, reset button
|
|
94
|
+
- `FinalTestPage.jsx` — final test with results display
|
|
95
|
+
|
|
96
|
+
6. **App component:**
|
|
97
|
+
- `App.jsx` — HashRouter with routes, Header, Footer, ProgressBar, Toast
|
|
98
|
+
|
|
99
|
+
## Critical Implementation Notes
|
|
100
|
+
|
|
101
|
+
### Navigation: Use scrollIntoView, NOT href anchors
|
|
102
|
+
HashRouter interprets `#section-id` as a route. Use `<button>` with `document.getElementById(id).scrollIntoView()`.
|
|
103
|
+
|
|
104
|
+
### Quiz scoring: Do NOT double-count
|
|
105
|
+
`handleSelect` increments `correctCount` on correct answer. `handleNext` must use `correctCount` directly without adding `+1` for the current answer (it's already counted).
|
|
106
|
+
|
|
107
|
+
### ScenarioGame scoring: Same pattern
|
|
108
|
+
`handleSelect` increments `score` on positive result. `handleNext` finished block uses `score` directly.
|
|
109
|
+
|
|
110
|
+
### Dark mode: Toggle class on documentElement
|
|
111
|
+
```javascript
|
|
112
|
+
document.documentElement.classList.toggle('dark')
|
|
113
|
+
```
|
|
114
|
+
Persist to Zustand store + restore in `onRehydrateStorage`.
|
|
115
|
+
|
|
116
|
+
### DragOrder: Randomize initial order
|
|
117
|
+
Shuffle items on mount so user has to reorder them. Use Fisher-Yates shuffle.
|
|
118
|
+
|
|
119
|
+
### MatchingExercise: Shuffle right side only
|
|
120
|
+
Left side stays in order, right side is shuffled.
|
|
121
|
+
|
|
122
|
+
## Checkpoint
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Step 4/7: Components Complete
|
|
126
|
+
Layout: 5 | Interactive: 6 | Common: 3 | Sections: N | Pages: 2 | App: 1
|
|
127
|
+
Total components: {count}
|
|
128
|
+
|
|
129
|
+
"ok" to continue | "[feedback]" to adjust
|
|
130
|
+
```
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Step 5: Gamification
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Generate the state management layer: Zustand store, progress hook, achievements hook, toast system.
|
|
5
|
+
|
|
6
|
+
## Protocol
|
|
7
|
+
|
|
8
|
+
### 1. Generate `src/store/useAppStore.js`
|
|
9
|
+
|
|
10
|
+
Zustand store with `persist` middleware (localStorage):
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
import { create } from 'zustand'
|
|
14
|
+
import { persist } from 'zustand/middleware'
|
|
15
|
+
|
|
16
|
+
export const useAppStore = create(
|
|
17
|
+
persist(
|
|
18
|
+
(set, get) => ({
|
|
19
|
+
// Progress
|
|
20
|
+
completedSections: {},
|
|
21
|
+
sectionScores: {},
|
|
22
|
+
markSectionComplete: (id, score) =>
|
|
23
|
+
set((s) => ({
|
|
24
|
+
completedSections: { ...s.completedSections, [id]: true },
|
|
25
|
+
sectionScores: { ...s.sectionScores, [id]: score },
|
|
26
|
+
})),
|
|
27
|
+
|
|
28
|
+
// Achievements
|
|
29
|
+
unlockedAchievements: [],
|
|
30
|
+
unlockAchievement: (id) =>
|
|
31
|
+
set((s) => ({
|
|
32
|
+
unlockedAchievements: s.unlockedAchievements.includes(id)
|
|
33
|
+
? s.unlockedAchievements
|
|
34
|
+
: [...s.unlockedAchievements, id],
|
|
35
|
+
})),
|
|
36
|
+
|
|
37
|
+
// Final test
|
|
38
|
+
finalTestScore: null,
|
|
39
|
+
finalTestAnswers: {},
|
|
40
|
+
setFinalTestResult: (score, answers) =>
|
|
41
|
+
set({ finalTestScore: score, finalTestAnswers: answers }),
|
|
42
|
+
|
|
43
|
+
// UI
|
|
44
|
+
navOpen: false,
|
|
45
|
+
toggleNav: () => set((s) => ({ navOpen: !s.navOpen })),
|
|
46
|
+
setNavOpen: (v) => set({ navOpen: v }),
|
|
47
|
+
|
|
48
|
+
// Dark mode
|
|
49
|
+
darkMode: false,
|
|
50
|
+
toggleDarkMode: () =>
|
|
51
|
+
set((s) => {
|
|
52
|
+
const next = !s.darkMode
|
|
53
|
+
document.documentElement.classList.toggle('dark', next)
|
|
54
|
+
return { darkMode: next }
|
|
55
|
+
}),
|
|
56
|
+
|
|
57
|
+
// Toast
|
|
58
|
+
toast: null,
|
|
59
|
+
showToast: (toast) => set({ toast }),
|
|
60
|
+
clearToast: () => set({ toast: null }),
|
|
61
|
+
|
|
62
|
+
// Reset
|
|
63
|
+
resetProgress: () =>
|
|
64
|
+
set({
|
|
65
|
+
completedSections: {},
|
|
66
|
+
sectionScores: {},
|
|
67
|
+
unlockedAchievements: [],
|
|
68
|
+
finalTestScore: null,
|
|
69
|
+
finalTestAnswers: {},
|
|
70
|
+
}),
|
|
71
|
+
}),
|
|
72
|
+
{
|
|
73
|
+
name: '{course-slug}-progress', // Unique per course
|
|
74
|
+
partialize: (state) => ({
|
|
75
|
+
completedSections: state.completedSections,
|
|
76
|
+
sectionScores: state.sectionScores,
|
|
77
|
+
unlockedAchievements: state.unlockedAchievements,
|
|
78
|
+
finalTestScore: state.finalTestScore,
|
|
79
|
+
finalTestAnswers: state.finalTestAnswers,
|
|
80
|
+
darkMode: state.darkMode,
|
|
81
|
+
}),
|
|
82
|
+
onRehydrateStorage: () => (state) => {
|
|
83
|
+
if (state?.darkMode) {
|
|
84
|
+
document.documentElement.classList.add('dark')
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. Generate `src/hooks/useProgress.js`
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
import { useAppStore } from '../store/useAppStore'
|
|
96
|
+
import { TOTAL_SECTIONS, SECTIONS } from '../data/sections'
|
|
97
|
+
|
|
98
|
+
export function useProgress() {
|
|
99
|
+
const completedSections = useAppStore((s) => s.completedSections)
|
|
100
|
+
const sectionScores = useAppStore((s) => s.sectionScores)
|
|
101
|
+
|
|
102
|
+
const count = Object.keys(completedSections).length
|
|
103
|
+
const percentage = Math.round((count / TOTAL_SECTIONS) * 100)
|
|
104
|
+
const totalScore = Object.values(sectionScores).reduce((a, b) => a + b, 0)
|
|
105
|
+
|
|
106
|
+
return { count, total: TOTAL_SECTIONS, percentage, totalScore }
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Generate `src/hooks/useAchievements.js`
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
import { useEffect } from 'react'
|
|
114
|
+
import { useAppStore } from '../store/useAppStore'
|
|
115
|
+
import { ACHIEVEMENTS } from '../data/achievements'
|
|
116
|
+
|
|
117
|
+
export function useAchievements() {
|
|
118
|
+
const completedSections = useAppStore((s) => s.completedSections)
|
|
119
|
+
const sectionScores = useAppStore((s) => s.sectionScores)
|
|
120
|
+
const finalTestScore = useAppStore((s) => s.finalTestScore)
|
|
121
|
+
const unlocked = useAppStore((s) => s.unlockedAchievements)
|
|
122
|
+
const unlock = useAppStore((s) => s.unlockAchievement)
|
|
123
|
+
const showToast = useAppStore((s) => s.showToast)
|
|
124
|
+
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
const state = useAppStore.getState()
|
|
127
|
+
for (const achievement of ACHIEVEMENTS) {
|
|
128
|
+
if (!unlocked.includes(achievement.id) && achievement.condition(state)) {
|
|
129
|
+
unlock(achievement.id)
|
|
130
|
+
showToast({
|
|
131
|
+
type: 'achievement',
|
|
132
|
+
title: achievement.title,
|
|
133
|
+
description: achievement.description,
|
|
134
|
+
icon: achievement.icon,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}, [completedSections, sectionScores, finalTestScore])
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 4. Wire Toast in App.jsx
|
|
143
|
+
|
|
144
|
+
Toast component auto-dismisses after 4 seconds. Displays at top-right with slide-in animation.
|
|
145
|
+
|
|
146
|
+
## Score Calculation
|
|
147
|
+
|
|
148
|
+
- Each section: 0-100 based on exercise performance
|
|
149
|
+
- Total score: sum of all section scores (displayed in Header)
|
|
150
|
+
- Final test: separate score (pass threshold: 70%)
|
|
151
|
+
- Progress: count of completed sections / total sections
|
|
152
|
+
|
|
153
|
+
## Checkpoint
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
Step 5/7: Gamification Complete
|
|
157
|
+
Store: useAppStore.js (persist to localStorage)
|
|
158
|
+
Hooks: useProgress.js, useAchievements.js
|
|
159
|
+
Achievements: {count} defined
|
|
160
|
+
Toast: wired in App.jsx
|
|
161
|
+
|
|
162
|
+
"ok" to continue | "[feedback]" to adjust
|
|
163
|
+
```
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Step 6: Deployment
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Configure GitHub Pages auto-deployment via GitHub Actions.
|
|
5
|
+
|
|
6
|
+
## Protocol
|
|
7
|
+
|
|
8
|
+
### 1. Create `.github/workflows/deploy.yml`
|
|
9
|
+
|
|
10
|
+
```yaml
|
|
11
|
+
name: Deploy to GitHub Pages
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
pages: write
|
|
21
|
+
id-token: write
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: pages
|
|
25
|
+
cancel-in-progress: false
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
build-and-deploy:
|
|
29
|
+
environment:
|
|
30
|
+
name: github-pages
|
|
31
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-node@v4
|
|
37
|
+
with:
|
|
38
|
+
node-version: 20
|
|
39
|
+
cache: npm
|
|
40
|
+
|
|
41
|
+
- run: npm ci
|
|
42
|
+
- run: npm run build
|
|
43
|
+
|
|
44
|
+
- uses: actions/configure-pages@v4
|
|
45
|
+
with:
|
|
46
|
+
enablement: true
|
|
47
|
+
|
|
48
|
+
- uses: actions/upload-pages-artifact@v3
|
|
49
|
+
with:
|
|
50
|
+
path: dist
|
|
51
|
+
|
|
52
|
+
- id: deployment
|
|
53
|
+
uses: actions/deploy-pages@v4
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Verify `vite.config.js` base path
|
|
57
|
+
|
|
58
|
+
The `base` must match the GitHub repo name:
|
|
59
|
+
- Repo: `https://github.com/user/my-course` -> `base: '/my-course/'`
|
|
60
|
+
|
|
61
|
+
### 3. Verify `index.html` has correct asset paths
|
|
62
|
+
|
|
63
|
+
All assets use relative paths (Vite handles this with `base` config).
|
|
64
|
+
|
|
65
|
+
### 4. Verify HashRouter usage
|
|
66
|
+
|
|
67
|
+
GitHub Pages serves `index.html` for all routes. HashRouter ensures client-side routing works:
|
|
68
|
+
```jsx
|
|
69
|
+
import { HashRouter, Routes, Route } from 'react-router-dom'
|
|
70
|
+
// NOT BrowserRouter
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Important Notes
|
|
74
|
+
|
|
75
|
+
- `enablement: true` in `actions/configure-pages@v4` auto-enables Pages if not yet configured
|
|
76
|
+
- First deployment may take 1-2 minutes to propagate
|
|
77
|
+
- If Pages was previously configured for Jekyll, it will be reconfigured for Actions
|
|
78
|
+
|
|
79
|
+
## Checkpoint
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Step 6/7: Deployment Complete
|
|
83
|
+
Workflow: .github/workflows/deploy.yml
|
|
84
|
+
Base path: /{repo-name}/
|
|
85
|
+
Router: HashRouter
|
|
86
|
+
|
|
87
|
+
"ok" to continue | "[feedback]" to adjust
|
|
88
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Step 7: Verification
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Build the project and verify everything works correctly.
|
|
5
|
+
|
|
6
|
+
## Protocol
|
|
7
|
+
|
|
8
|
+
### 1. Run build
|
|
9
|
+
```bash
|
|
10
|
+
npm run build
|
|
11
|
+
```
|
|
12
|
+
Must complete with zero errors.
|
|
13
|
+
|
|
14
|
+
### 2. Verify file structure
|
|
15
|
+
Check that all expected files exist:
|
|
16
|
+
- [ ] `src/data/sections.js` — has correct number of sections
|
|
17
|
+
- [ ] `src/data/exercises.js` — has data for each exercise type used
|
|
18
|
+
- [ ] `src/data/quizQuestions.js` — has questions for quiz sections + final test
|
|
19
|
+
- [ ] `src/data/achievements.js` — has 8+ achievements
|
|
20
|
+
- [ ] `src/store/useAppStore.js` — Zustand store with persist
|
|
21
|
+
- [ ] `src/hooks/useProgress.js` — progress calculations
|
|
22
|
+
- [ ] `src/hooks/useAchievements.js` — achievement detection
|
|
23
|
+
- [ ] All section components (`Section1.jsx` through `SectionN.jsx`)
|
|
24
|
+
- [ ] All interactive components used by sections
|
|
25
|
+
- [ ] All layout components
|
|
26
|
+
- [ ] `src/App.jsx` — routing
|
|
27
|
+
- [ ] `src/pages/HomePage.jsx` — main page
|
|
28
|
+
- [ ] `src/pages/FinalTestPage.jsx` — test page
|
|
29
|
+
- [ ] `.github/workflows/deploy.yml` — deployment
|
|
30
|
+
|
|
31
|
+
### 3. Cross-reference checks
|
|
32
|
+
- [ ] Every section in `SECTIONS` array has a corresponding `SectionN.jsx` component
|
|
33
|
+
- [ ] Every section's `interactiveType` has matching exercise data
|
|
34
|
+
- [ ] `finalTestQuestions` has one entry per section with valid `sectionId`
|
|
35
|
+
- [ ] All imports in components resolve to existing files
|
|
36
|
+
- [ ] No circular dependencies
|
|
37
|
+
|
|
38
|
+
### 4. Known bug prevention
|
|
39
|
+
- [ ] Quiz.jsx: `handleNext` uses `correctCount` directly, NOT `correctCount + (selected === correctAnswer ? 1 : 0)`
|
|
40
|
+
- [ ] ScenarioGame.jsx: same pattern — no double-counting in `handleNext` or finished view
|
|
41
|
+
- [ ] Navigation.jsx: uses `scrollIntoView()` NOT `<a href="#section-...">` (HashRouter conflict)
|
|
42
|
+
- [ ] Dark mode: `onRehydrateStorage` restores `.dark` class
|
|
43
|
+
|
|
44
|
+
### 5. Responsiveness check
|
|
45
|
+
- [ ] Navigation hides on mobile (hamburger menu)
|
|
46
|
+
- [ ] Sections stack vertically on small screens
|
|
47
|
+
- [ ] Cards and buttons have proper touch targets (min 44px)
|
|
48
|
+
- [ ] Text is readable at all breakpoints
|
|
49
|
+
- [ ] Swipe gesture navigation works on mobile (left = next section, right = previous)
|
|
50
|
+
- [ ] Swipe threshold (50px) prevents accidental navigation
|
|
51
|
+
|
|
52
|
+
### 6. Flashcard toggle check
|
|
53
|
+
- [ ] Cards flip from front to back on click
|
|
54
|
+
- [ ] Cards flip back from back to front on second click
|
|
55
|
+
- [ ] "Viewed" indicator shows on cards that have been flipped at least once
|
|
56
|
+
- [ ] onComplete(100) fires when ALL cards have been viewed at least once (regardless of current flip state)
|
|
57
|
+
- [ ] Keyboard navigation works (Enter/Space to flip)
|
|
58
|
+
|
|
59
|
+
### 7. SEO files check
|
|
60
|
+
- [ ] `public/robots.txt` exists with `User-agent: *`, `Allow: /`, and `Sitemap:` directive
|
|
61
|
+
- [ ] `public/sitemap.xml` exists with valid XML structure
|
|
62
|
+
- [ ] sitemap.xml contains URL for each section
|
|
63
|
+
- [ ] Sitemap URL in robots.txt matches actual sitemap location
|
|
64
|
+
|
|
65
|
+
### 6. Error Recovery
|
|
66
|
+
|
|
67
|
+
If `npm run build` fails, diagnose and fix:
|
|
68
|
+
|
|
69
|
+
| Error | Cause | Fix |
|
|
70
|
+
|-------|-------|-----|
|
|
71
|
+
| `Module not found: Can't resolve './components/...'` | Missing component file or wrong import path | Create the missing file or fix the import |
|
|
72
|
+
| `'X' is not exported from 'Y'` | Wrong export name in data file | Check data file exports match imports |
|
|
73
|
+
| `Cannot find module '@dnd-kit/...'` | Missing dependency | Run `npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities` |
|
|
74
|
+
| `Unexpected token` in JSX | Syntax error in component | Check for unclosed tags, missing returns |
|
|
75
|
+
| TailwindCSS class not resolving | Custom class without `@theme` definition | Verify all semantic colors defined in index.css |
|
|
76
|
+
| `npm install` fails with ERESOLVE | Peer dependency conflict | Try `npm install --legacy-peer-deps` |
|
|
77
|
+
| `npm install` fails with network error | No internet or registry down | Check network, retry, or use `--registry https://registry.npmjs.org` |
|
|
78
|
+
|
|
79
|
+
**Recovery protocol:**
|
|
80
|
+
1. Read the full error message
|
|
81
|
+
2. Match to table above (or diagnose)
|
|
82
|
+
3. Fix the specific issue
|
|
83
|
+
4. Re-run `npm run build`
|
|
84
|
+
5. Repeat until clean build
|
|
85
|
+
|
|
86
|
+
## Output
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Step 7/7: Verification Complete
|
|
90
|
+
Build: SUCCESS
|
|
91
|
+
Files: {count} verified
|
|
92
|
+
Cross-references: OK
|
|
93
|
+
Known bugs: mitigated
|
|
94
|
+
|
|
95
|
+
Site ready for deployment. Push to main to trigger GitHub Pages deploy.
|
|
96
|
+
URL: https://{user}.github.io/{repo}/
|
|
97
|
+
```
|