turash/docs/app/database_structure.md
Damir Mukimov 000eab4740
Major repository reorganization and missing backend endpoints implementation
Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools

Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
  * GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
  * GET /api/v1/users/me/organizations - User organizations
  * POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue

API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules

Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
2025-11-25 06:01:16 +01:00

9.1 KiB

Database Structure and Interconnectivity

Overview

The City Resource Graph database uses PostgreSQL with PostGIS for spatial data and GORM as the ORM layer. The architecture follows the concept documentation with enhancements for industrial symbiosis matching.

Core Entities:

  • Organizations: Businesses, institutions, and other entities (commercial, healthcare, educational, cultural, religious, government, infrastructure)
  • Sites: Physical locations/buildings where organizations operate
  • ResourceFlows: Resource inputs/outputs and services at specific sites
  • Matches: Potential or actual resource exchanges between organizations
  • SharedAssets: Equipment/infrastructure that can be shared among businesses

Domain Models (GORM)

Organizations Table

Represents all types of organizations including businesses, healthcare facilities, educational institutions, cultural venues, and religious organizations.

Schema:

CREATE TABLE organizations (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    sector TEXT,
    subtype VARCHAR(50) NOT NULL,
    description TEXT,
    logo_url TEXT,
    website TEXT,
    address TEXT,
    verified BOOLEAN DEFAULT FALSE,
    products JSONB,
    certifications JSONB DEFAULT '[]'::jsonb,
    readiness_maturity INTEGER DEFAULT 3,
    trust_score DOUBLE PRECISION DEFAULT 0.7,
    latitude DOUBLE PRECISION,
    longitude DOUBLE PRECISION,
    year_built TEXT,
    builder_owner TEXT,
    architect TEXT,
    original_purpose TEXT,
    current_use TEXT,
    style TEXT,
    materials TEXT,
    storeys INTEGER,
    heritage_status TEXT,
    notes TEXT,
    sources JSONB,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Indexes:

  • Primary key on id
  • GIN index on products (JSONB)
  • GIN index on certifications (JSONB)
  • B-tree index on subtype
  • B-tree index on sector
  • B-tree index on verified
  • Spatial index on (latitude, longitude) if using PostGIS

GORM Model:

type Organization struct {
    ID                string             `gorm:"primaryKey;type:text"`
    Name              string             `gorm:"not null;type:text"`
    Sector            string             `gorm:"type:text"`
    Subtype           OrganizationSubtype `gorm:"not null;type:varchar(50)"`
    Description       string             `gorm:"type:text"`
    LogoURL           string             `gorm:"type:text"`
    Website           string             `gorm:"type:text"`
    Address           string             `gorm:"type:text"`
    Verified          bool               `gorm:"default:false"`
    Products          datatypes.JSON     `gorm:"type:jsonb"`
    Certifications    datatypes.JSON     `gorm:"type:jsonb;default:'[]'"`
    ReadinessMaturity int                `gorm:"default:3"`
    TrustScore        float64            `gorm:"type:double precision;default:0.7"`
    Latitude          float64            `gorm:"type:double precision"`
    Longitude         float64            `gorm:"type:double precision"`
    YearBuilt         string             `gorm:"type:text"`
    BuilderOwner      string             `gorm:"type:text"`
    Architect         string             `gorm:"type:text"`
    OriginalPurpose   string             `gorm:"type:text"`
    CurrentUse        string             `gorm:"type:text"`
    Style             string             `gorm:"type:text"`
    Materials         string             `gorm:"type:text"`
    Storeys           int                `gorm:"type:integer"`
    HeritageStatus    string             `gorm:"type:text"`
    Notes             string             `gorm:"type:text"`
    Sources           datatypes.JSON     `gorm:"type:jsonb"`
    CreatedAt         time.Time          `gorm:"autoCreateTime"`
    UpdatedAt         time.Time          `gorm:"autoUpdateTime"`

    // Relationships
    OwnedSites        []Site             `gorm:"foreignKey:OwnerBusinessID"`
    OperatingSites    []Site             `gorm:"many2many:site_operating_businesses;"`
}

Sites Table

Represents physical locations and buildings where organizations operate.

Schema:

CREATE TABLE sites (
    id TEXT PRIMARY KEY,
    name TEXT,
    address TEXT,
    latitude DOUBLE PRECISION,
    longitude DOUBLE PRECISION,
    site_type VARCHAR(50),
    floor_area_m2 DOUBLE PRECISION,
    ownership VARCHAR(50),
    owner_business_id TEXT,
    operating_businesses JSONB DEFAULT '[]'::jsonb,
    available_utilities JSONB DEFAULT '[]'::jsonb,
    parking_spaces INTEGER,
    loading_docks INTEGER,
    crane_capacity_tonnes DOUBLE PRECISION,
    energy_rating TEXT,
    waste_management JSONB DEFAULT '[]'::jsonb,
    environmental_impact TEXT,
    year_built TEXT,
    builder_owner TEXT,
    architect TEXT,
    original_purpose TEXT,
    current_use TEXT,
    style TEXT,
    materials TEXT,
    storeys INTEGER,
    heritage_status TEXT,
    notes TEXT,
    sources JSONB,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Indexes:

  • Primary key on id
  • B-tree index on site_type
  • B-tree index on owner_business_id
  • GIN index on operating_businesses (JSONB)
  • GIN index on available_utilities (JSONB)
  • GIN index on waste_management (JSONB)
  • Spatial index on (latitude, longitude) using PostGIS

GORM Model:

type Site struct {
    ID                   string         `gorm:"primaryKey;type:text"`
    Name                 string         `gorm:"type:text"`
    Address              string         `gorm:"type:text"`
    Latitude             float64        `gorm:"type:double precision"`
    Longitude            float64        `gorm:"type:double precision"`
    SiteType             string         `gorm:"type:varchar(50)"`
    FloorAreaM2          float64        `gorm:"type:double precision"`
    Ownership            string         `gorm:"type:varchar(50)"`
    OwnerBusinessID      string         `gorm:"type:text"`
    OperatingBusinesses  datatypes.JSON `gorm:"type:jsonb;default:'[]'"`
    AvailableUtilities   datatypes.JSON `gorm:"type:jsonb;default:'[]'"`
    ParkingSpaces        int            `gorm:"type:integer"`
    LoadingDocks         int            `gorm:"type:integer"`
    CraneCapacityTonnes  float64        `gorm:"type:double precision"`
    EnergyRating         string         `gorm:"type:text"`
    WasteManagement      datatypes.JSON `gorm:"type:jsonb;default:'[]'"`
    EnvironmentalImpact  string         `gorm:"type:text"`
    YearBuilt            string         `gorm:"type:text"`
    BuilderOwner         string         `gorm:"type:text"`
    Architect            string         `gorm:"type:text"`
    OriginalPurpose      string         `gorm:"type:text"`
    CurrentUse           string         `gorm:"type:text"`
    Style                string         `gorm:"type:text"`
    Materials            string         `gorm:"type:text"`
    Storeys              int            `gorm:"type:integer"`
    HeritageStatus       string         `gorm:"type:text"`
    Notes                string         `gorm:"type:text"`
    Sources              datatypes.JSON `gorm:"type:jsonb"`
    CreatedAt            time.Time      `gorm:"autoCreateTime"`
    UpdatedAt            time.Time      `gorm:"autoUpdateTime"`

    // Relationships
    OwnerBusiness        *Organization  `gorm:"foreignKey:OwnerBusinessID"`
    OperatingBusinessesRel []Organization `gorm:"many2many:site_operating_businesses;"`
}

Relationships and Interconnectivity

Organization-Site Relationships

  1. Ownership: An Organization can own multiple Sites

    • sites.owner_business_idorganizations.id
    • One-to-many relationship
  2. Operation: Organizations can operate at multiple Sites (multi-tenant buildings)

    • Many-to-many relationship via site_operating_businesses junction table
    • sites.operating_businesses stores array of organization IDs

Junction Table for Many-to-Many

CREATE TABLE site_operating_businesses (
    site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
    organization_id TEXT REFERENCES organizations(id) ON DELETE CASCADE,
    PRIMARY KEY (site_id, organization_id)
);

GORM Junction Model:

type SiteOperatingBusiness struct {
    SiteID         string `gorm:"primaryKey"`
    OrganizationID string `gorm:"primaryKey"`
    Site           Site
    Organization   Organization
}

Additional Tables

  • city_geometry: Spatial boundaries and geometries (PostGIS)
  • historical_timeline: Historical events and data points
  • businesses: Legacy table (can be deprecated)
  • sqlite_businesses: Raw imported data (can be deprecated)

Migration Strategy

  1. Use existing Organizations and Sites tables
  2. Create junction table for many-to-many relationships
  3. Add GORM models to the domain layer
  4. Update repository implementations to use GORM
  5. Add database migrations for any schema changes

Notes

  • All tables use UUIDs for IDs (stored as TEXT)
  • JSONB fields for flexible data storage
  • PostGIS for spatial queries on coordinates
  • Timestamps use timezone-aware types
  • Indexes optimized for common query patterns /Users/damirmukimov/city_resource_graph/database_structure.md