# 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

```go
// 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

```go
// 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

```go
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
