Kind: Service
Source: atloria-monorepo/apps/api/src/documentation/services/tutorial-detector.service.ts
Tutorial Detector Service
Detects single-step tutorials from state transitions. Each state transition becomes a quick-start tutorial (2-5 minutes).
Strategy:
- Find all state machines
- For each transition, create a tutorial
- Link tutorials via prerequisites/next steps
- Group into learning paths by category
Example:
- State machine: JobStageEnum
- Transition: Offer → Order (convertToOrder)
- Tutorial: "How to Convert an Offer to an Order"
- Difficulty: Beginner
- Time: 2-3 minutes
- Prerequisites: "How to Create a Job Offer"
- Next steps: "How to Deliver an Order"
TutorialDetectorService scans application state machines and derives micro-tutorials from their state transitions. Each transition becomes a single-step quick-start tutorial (typically 2–5 minutes), enriched with difficulty, estimated time, and navigation links (prerequisites/next steps). It helps automatically generate structured learning paths by grouping tutorials by domain/category.
Methods
| Method | Signature | Returns | Description |
|---|---|---|---|
detectTutorials | detectTutorials(entities: any[], appMap: any, features: any[]) | `Promise<{ |
tutorials: DetectedTutorial[]; learningPaths: LearningPath[];
}>` | Detect tutorials from parsed entities |
Where it refuses work
TutorialDetectorServicestops the work with an early return whenlowerMethod.includes('convert').TutorialDetectorServicestops the work with an early return whenlowerMethod.includes('approve').TutorialDetectorServicestops the work with an early return whenlowerMethod.includes('reject').TutorialDetectorServicestops the work with an early return whenlowerMethod.includes('deliver').TutorialDetectorServicestops the work with an early return whenlowerMethod.includes('cancel').TutorialDetectorServicestops the work with an early return whenlowerMethod.includes('submit').
When something fails
TutorialDetectorServicehandles failure in 1 place: it turns it into a return value in all 1.
Diagram
mermaidsequenceDiagram autonumber participant Caller as API/CLI/Job participant TDS as TutorialDetectorService participant SM as StateMachineRegistry participant GEN as TutorialGenerator participant LINK as TutorialLinker participant PATH as LearningPathGrouper participant OUT as Docs/DB Output Caller->>TDS: detectTutorials() TDS->>SM: listStateMachines() SM-->>TDS: stateMachines[] loop for each stateMachine TDS->>SM: getTransitions(stateMachine) SM-->>TDS: transitions[] loop for each transition TDS->>GEN: createTutorialFromTransition(transition) GEN-->>TDS: tutorial end end TDS->>LINK: linkPrerequisitesAndNextSteps(tutorials) LINK-->>TDS: linkedTutorials TDS->>PATH: groupByCategory(linkedTutorials) PATH-->>TDS: learningPaths TDS->>OUT: persistOrRender(learningPaths) OUT-->>Caller: result
Usage
tsimport { Injectable } from '@nestjs/common';
import { TutorialDetectorService } from './documentation/services/tutorial-detector.service';
@Injectable()
export class DocsGenerationJob {
constructor(private readonly tutorialDetector: TutorialDetectorService) {}
async run() {
// Detect tutorials derived from all known state machine transitions.
const result = await this.tutorialDetector.detectTutorials();
// Example: iterate and print a few generated tutorial titles.
for (const path of result.learningPaths ?? []) {
console.log(`Learning Path: ${path.title}`);
for (const tutorial of path.tutorials.slice(0, 3)) {
console.log(` - ${tutorial.title} (${tutorial.difficulty}, ${tutorial.estimatedTime})`);
console.log(` prereq: ${tutorial.prerequisites?.join(', ') ?? 'none'}`);
console.log(` next: ${tutorial.nextSteps?.join(', ') ?? 'none'}`);
}
}
return result;
}
}
AI Coding Instructions
- Treat each state transition as the single source of truth for tutorial generation; avoid hand-curated tutorial definitions that drift from the state machine.
- Keep tutorial titles/action verbs deterministic (e.g., derived from transition name like
convertToOrder) so linking and deduplication remain stable across runs. - When adding or renaming states/transitions, ensure the detector can still resolve prerequisites/next steps (ordering or adjacency rules are a common failure point).
- Integrate category/grouping from domain metadata (state machine ownership/module) rather than parsing strings from enum names whenever possible.
- Prefer idempotent outputs (stable IDs/keys for tutorials and learning paths) so re-running generation doesn’t create duplicates in persisted docs/DB.
Referenced By
DocumentationModule(MODULE_PROVIDES)DocumentationModule(MODULE_EXPORTS)
Was this page helpful?