Knowledge
Search knowledge... ⌘K
Knowledge · Guidelines · architecture
Dictionary Two Tier Sync
Two-tier dictionary architecture — system defaults (YAML) + project extensions (DB) with CLI promotion workflow
Metadata
architecture mandatory
Procedures
Showing 3 of 6
- 1 Identify dictionary scope — shared or project-specific
Before creating dictionary values, classify them: SHARED (Tier 1 — YAML fixture default): - Used by 2+ projects (both BS and BR need "villa" as a property type) - Fundamental to the domain (land title deed types are inherent to Thai real estate) - Rarely changes after initial definition - Examples: property.type, lease.status, person.nationality PROJECT-SPECIFIC (Tier 2 — database extension): - Used by only one project (bestays-specific amenity categories) - Added by users/agents at runtime - Changes frequently or is user-defined - Examples: custom property tags, client-specific categories Decision gate: If in doubt, start as Tier 2. Promote to Tier 1 after the value proves stable and useful across projects.
- 2 Create Tier 1 system defaults
For shared dictionary values, create YAML fixture files: Location: .sbx/workspace/packages/core/go/types/dictionary/fixtures/defaults/ Format: type: dictionary namespace: {domain}.{concept} # e.g., property.type, lease.status domain_scope: {null|real-estate} # null = universal, or domain name purpose: {one-line description} default_locale: en values: - code: {machine-readable-id} # e.g., "villa", "active", "mr" label: {Human-Readable Label} translations: en: {English label} th: {Thai label} sort_order: {integer} x_provenance: # traceability — where did this data come from? source: {property2|csv|manual} file: {source file path} decision_ref: {decision number} Naming convention: {concept}.yml (e.g., property-type.yml, lease-status.yml) All values within one namespace go in ONE file. - 3 Design Tier 2 extension table
For projects that allow runtime dictionary additions, the project's database schema includes: CREATE TABLE {schema}.dictionary_extensions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), namespace VARCHAR(100) NOT NULL, code VARCHAR(50) NOT NULL, label VARCHAR(200) NOT NULL, translations JSONB DEFAULT '{}', sort_order INT DEFAULT 0, created_by VARCHAR(100), created_at TIMESTAMPTZ DEFAULT NOW(), promoted_at TIMESTAMPTZ, -- NULL until promoted to Tier 1 UNIQUE(namespace, code) ); Seed on startup: INSERT INTO dictionaries SELECT ... FROM Tier 1 YAML ON CONFLICT (namespace, code) DO NOTHING; Query pattern: SELECT * FROM dictionaries UNION ALL SELECT ... FROM dictionary_extensions WHERE promoted_at IS NULL ORDER BY sort_order;