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

253 lines
9.1 KiB
Markdown

# 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:**
```sql
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:**
```go
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:**
```sql
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:**
```go
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_id``organizations.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
```sql
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:**
```go
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</content>
<parameter name="filePath">/Users/damirmukimov/city_resource_graph/database_structure.md