Unified taxonomy system for all apps, stored in datalake (Silver zone) with database cache.
import { TaxonomyService } from '@stephen/taxonomy';
const taxonomyService = new TaxonomyService();
// Get taxonomy data (prefers database cache, falls back to datalake)
const taxonomy = await taxonomyService.getTaxonomyData();
// Resolve synonyms
const subjectId = await taxonomyService.resolveSubject('wiskunde');
const topicGroupId = await taxonomyService.resolveTopicGroup('algebra');
// Get display names
const displayName = await taxonomyService.getSubjectDisplayName('wiskunde-a');
sequenceDiagram
participant Admin
participant Sync as TaxonomySyncService
participant DB as PostgreSQL
participant MinIO as MinIO Datalake
Note over Admin,MinIO: Admin saves taxonomy
Admin->>DB: Save taxonomy data
Admin->>Sync: syncDatabaseToDatalake()
Sync->>DB: Read taxonomy
Sync->>MinIO: Write to silver-education/taxonomy/
MinIO-->>Sync: Confirmed
Note over Admin,MinIO: Cache refresh
Admin->>Sync: syncDatalakeToDatabase()
Sync->>MinIO: Read taxonomy
MinIO-->>Sync: Return taxonomy data
Sync->>DB: Update cache
DB-->>Sync: Confirmed
Note over Admin,MinIO: Validation
Admin->>Sync: validateSync()
Sync->>DB: Read cache
Sync->>MinIO: Read source
Sync->>Sync: Compare data
Sync-->>Admin: Validation result
import { TaxonomySyncService } from '@stephen/taxonomy';
const syncService = new TaxonomySyncService();
// Sync database → datalake (admin saves)
await syncService.syncDatabaseToDatalake();
// Sync datalake → database (cache refresh)
await syncService.syncDatalakeToDatabase();
// Validate consistency
const validation = await syncService.validateSync();
import { TaxonomyService, SynonymResolver } from '@stephen/taxonomy';
const taxonomyService = new TaxonomyService();
const taxonomy = await taxonomyService.getTaxonomyData();
const resolver = new SynonymResolver(taxonomy);
// Resolve synonyms
const subjectId = resolver.resolveSubject('wiskunde'); // Returns 'wiskunde-a' ID
const topicGroupId = resolver.resolveTopicGroup('algebra'); // Returns 'algebra-vergelijkingen' ID
graph TB
Package[@stephen/taxonomy] --> Service[TaxonomyService]
Package --> Sync[TaxonomySyncService]
Package --> Resolver[SynonymResolver]
Service --> Check{Cache Check}
Check -->|Hit| DB[(PostgreSQL<br/>Cache)]
Check -->|Miss| MinIO[MinIO Datalake<br/>Silver Zone]
MinIO --> Silver[silver-education/taxonomy/]
Silver --> Sync
Sync --> DB
Apps[Applications] -->|Import| Package
Apps --> App1[Privelessen Dashboard]
Apps --> App2[Aantekeningen App]
Apps --> App3[Other Apps]
Service --> Data[Taxonomy Data]
Data --> Subjects[Subjects]
Data --> TopicGroups[Topic Groups]
Data --> Topics[Topics]
Data --> Synonyms[Synonyms]
style Package fill:#e1f5ff
style DB fill:#fff4e1
style MinIO fill:#e8f5e9
style Silver fill:#f3e5f5
- Datalake (Silver zone): Source of truth, stored in
silver-education/taxonomy/
- Database (PostgreSQL): Fast cache for queries
- Package: Unified API for all apps
classDiagram
class Taxonomy {
+Subjects subjects
+TopicGroups topicGroups
+Topics topics
+Synonyms synonyms
}
class Subject {
+string id
+string name
+string displayName
+TopicGroup[] topicGroups
}
class TopicGroup {
+string id
+string name
+string displayName
+Subject subject
+Topic[] topics
}
class Topic {
+string id
+string name
+string displayName
+TopicGroup topicGroup
}
class Synonym {
+string id
+string term
+string targetId
+string targetType
}
Taxonomy --> Subject
Taxonomy --> TopicGroup
Taxonomy --> Topic
Taxonomy --> Synonym
Subject --> TopicGroup
TopicGroup --> Topic
Synonym --> Subject
Synonym --> TopicGroup
Synonym --> Topic
Taxonomy data includes:
- Subjects (vakken)
- Topic Groups (domeinen)
- Topics (onderwerpen)
- Synonyms (synoniemen)
All stored in JSON format in datalake, cached in PostgreSQL for performance.