Files
relspecgo/docs/DOMAINS_DRAWDB.md
Hein 5d3c86119e
Some checks failed
CI / Test (1.24) (push) Successful in -27m28s
CI / Test (1.25) (push) Successful in -27m30s
CI / Build (push) Failing after -28m36s
Integration Tests / Integration Tests (push) Failing after -28m8s
CI / Lint (push) Successful in -27m54s
feat(domains): add domain support for DrawDB integration
- Introduce Domain and DomainTable models for logical grouping of tables.
- Implement export and import functionality for domains in DrawDB format.
- Update template execution modes to include domain processing.
- Enhance documentation for domain features and usage.
2026-01-04 15:49:47 +02:00

5.1 KiB

Domains and DrawDB Areas Integration

Overview

Domains provide a way to organize tables from potentially multiple schemas into logical business groupings. When working with DrawDB format, domains are automatically imported/exported as Subject Areas - a native DrawDB feature for visually grouping tables.

How It Works

Writing Domains to DrawDB (Export)

When you export a database with domains to DrawDB format:

  1. Schema Areas are created automatically for each schema (existing behavior)
  2. Domain Areas are created for each domain, calculated based on the positions of the tables they contain
  3. The domain area bounds are automatically calculated to encompass all its tables with a small padding
// Example: Creating a domain and exporting to DrawDB
db := models.InitDatabase("mydb")

// Create an "authentication" domain
authDomain := models.InitDomain("authentication")
authDomain.Tables = append(authDomain.Tables,
    models.InitDomainTable("users", "public"),
    models.InitDomainTable("roles", "public"),
    models.InitDomainTable("permissions", "public"),
)
db.Domains = append(db.Domains, authDomain)

// Create a "financial" domain spanning multiple schemas
finDomain := models.InitDomain("financial")
finDomain.Tables = append(finDomain.Tables,
    models.InitDomainTable("accounts", "public"),
    models.InitDomainTable("transactions", "public"),
    models.InitDomainTable("ledger", "finance"),  // Different schema!
)
db.Domains = append(db.Domains, finDomain)

// Write to DrawDB - domains become subject areas
writer := drawdb.NewWriter(&writers.WriterOptions{
    OutputPath: "schema.json",
})
writer.WriteDatabase(db)

The resulting DrawDB JSON will have Subject Areas for both:

  • "authentication" area containing the auth tables
  • "financial" area containing the financial tables from both schemas

Reading Domains from DrawDB (Import)

When you import a DrawDB file with Subject Areas:

  1. Subject Areas are automatically converted to Domains
  2. Tables are assigned to a domain if they fall within the area's visual bounds
  3. Table references include both the table name and schema name
// Example: Reading DrawDB with areas
reader := drawdb.NewReader(&readers.ReaderOptions{
    FilePath: "schema.json",
})

db, err := reader.ReadDatabase()
if err != nil {
    log.Fatal(err)
}

// Access domains
for _, domain := range db.Domains {
    fmt.Printf("Domain: %s\n", domain.Name)
    for _, domainTable := range domain.Tables {
        fmt.Printf("  - %s.%s\n", domainTable.SchemaName, domainTable.TableName)
        
        // Access the actual table reference if loaded
        if domainTable.RefTable != nil {
            fmt.Printf("    Description: %s\n", domainTable.RefTable.Description)
        }
    }
}

Domain Structure

type Domain struct {
    Name        string         // Domain name (e.g., "authentication", "user_data")
    Description string         // Optional human-readable description
    Tables      []*DomainTable // Tables belonging to this domain
    Comment     string         // Optional comment
    Metadata    map[string]any // Extensible metadata
    Sequence    uint           // Ordering hint
}

type DomainTable struct {
    TableName  string // Table name
    SchemaName string // Schema containing the table
    Sequence   uint   // Ordering hint
    RefTable   *Table // Pointer to actual table (in-memory only, not serialized)
}

Multi-Schema Domains

One of the key features of domains is that they can span multiple schemas:

Domain: "user_data"
├── public.users
├── public.profiles
├── public.user_preferences
├── auth.user_sessions
└── auth.mfa_devices

This allows you to organize related tables even when they're stored in different schemas.

Visual Organization in DrawDB

When viewing the exported DrawDB file in DrawDB Editor:

  1. Schema areas appear in one color (original behavior)
  2. Domain areas appear in a different color
  3. Domain area bounds are calculated to fit all contained tables
  4. Areas can overlap - a table can visually belong to multiple areas

Integration with Other Formats

Currently, domain/area integration is implemented for DrawDB format.

To implement similar functionality for other formats:

  1. Identify if the format has a native grouping/area feature
  2. Add conversion logic in the reader to map format areas → Domain model
  3. Add conversion logic in the writer to map Domain model → format areas

Example formats that could support domains:

  • DBML: Could use DBML's TableGroup feature
  • DrawDB: Already implemented (Subject Areas)
  • GraphQL: Could use schema directives
  • Custom formats: Implement as needed

Tips and Best Practices

  1. Keep domains focused: Each domain should represent a distinct business area
  2. Document purposes: Use Description and Comment fields to explain each domain
  3. Use meaningful names: Domain names should clearly reflect their purpose
  4. Maintain schema consistency: Keep related tables together in the same schema when possible
  5. Use metadata: Store tool-specific information in the Metadata field