This project is an editor for CASE frameworks, built as an open-source reference implementation.
It enables users to:
- Create and edit CASE Frameworks (
CFDocument) - Define framework items (
CFItem) - Create associations (
CFAssociation) between items - Manage frameworks in a draft → publish lifecycle
This project intentionally focuses on core authoring capabilities only and does not attempt to compete with full-featured commercial CASE authoring or management systems.
- 1EdTech members
- CASE implementers and integrators
- Standards, curriculum, policy, and workforce teams
Users may work in different contexts:
- K–12: standards, curriculum alignment
- Higher Education: learning outcomes, program competencies
- Workforce: skills and competency frameworks
The underlying CASE data model is identical, but terminology adapts to user context.
- React
- TypeScript
- Tailwind CSS v4
- shadcn/ui
- React Flow (
@xyflow/react) for framework visualization
- CASE-compatible API
- Extended with authoring endpoints (
POST,PUT,DELETE) - Publishing creates explicit framework versions
- CASE concepts are modeled explicitly in the domain layer
- UI components do not own domain logic
- Domain objects are framework-agnostic (not tied to React Flow)
- Domain → Application → Infrastructure → UI
- Dependencies flow inward
- React Flow lives entirely in the UI layer
Aggregate Root
Represents one CASE framework being edited.
Maps to:
CFDocumentCFPackage(as needed)
Owns:
- Items (
CFItem) - Associations (
CFAssociation) - Framework metadata
- Draft / published state
Framework
├─ id
├─ metadata
├─ items: Map<ItemId, Item>
├─ associations: Map<AssociationId, Association>
└─ status: Draft | PublishedRepresents a node in the framework.
Maps to:
CFItem
Item
├─ id
├─ statement
├─ type
├─ metadata
└─ ordering / hierarchy hintsTypical semantic types (UI lens, not CASE schema):
- Standard
- Learning Outcome
- Competency
- Skill
These are presentation concerns, not schema-level CASE types.
Represents a relationship between items.
Maps to:
CFAssociation
Association
├─ id
├─ fromItemId
├─ toItemId
├─ associationType
└─ metadataCommon association types:
isChildOf(hierarchy)isPartOfisRelatedToalignsTo(future)
The domain model is a graph, not a tree.
- CASE allows multiple association types
- Hierarchy is just one association pattern
- Cross-links must be supported later without re-architecture
Framework
├─ Items (nodes)
└─ Associations (edges)
React Flow is a projection of the domain graph.
Item → ReactFlowNode{
id: item.id,
type: 'caseItemNode',
data: {
itemId: item.id,
title: item.statement,
itemType: item.type
},
position: { x, y } // layout-derived
}Association → ReactFlowEdge{
id: association.id,
source: association.fromItemId,
target: association.toItemId,
type: 'caseAssociationEdge',
data: {
associationType: association.type
}
}React Flow nodes/edges are never the source of truth.
- The domain graph is authoritative
- React Flow state is derived
- User interactions are translated into domain commands
- Tree-like hierarchy rendered using layout algorithms (e.g. Dagre / ELK)
- Layout is recalculated on structural changes
- Node dragging is optional and cosmetic
- Layout data may be persisted separately from CASE data
-
Command handlers:
addItemupdateItemremoveItemaddAssociationpublishFramework
-
Validation rules (e.g. no cycles in hierarchy if enforced)
-
Draft state management
- Render domain graph using React Flow
- Translate UI actions → application commands
- Display draft/publish status
- Adapt terminology by user context
- Ensure accessibility (WCAG)
- Canvas interaction must be keyboard accessible
- Nodes must be focusable
- Screen readers must have a logical navigation order
- Optional outline / ARIA tree view can mirror the same domain graph
- Multi-user collaboration
- Workflow approvals
- Analytics or reporting
- Vendor-specific extensions
This project:
- Is a CASE framework editor
- Uses DDD + Clean Architecture
- Treats CASE as a graph domain
- Uses React Flow as a visual projection
- Prioritizes clarity, trust, and extensibility