## **PostgreSQL Hosting: OCI Always Free + Home Lab Hybrid**

**Primary Setup: OCI Always Free Tier**
- Deploy PostgreSQL on the Arm-based Ampere A1 (4 cores, 24GB RAM)
- This gives you a production-grade, always-available database
- 200GB block storage is plenty for grants data
- 10TB monthly data transfer handles all your API calls and client deliveries

**Backup/Development: Home Lab**
- Keep a local PostgreSQL instance for development and testing
- Use it for experimentation without affecting production
- Disaster recovery backup location

**Why This Hybrid Approach:**
- **Cost**: Truly free forever (not 3-month AWS trial)
- **Performance**: 24GB RAM handles massive datasets easily
- **Reliability**: Cloud uptime for client-facing services
- **Security**: Your production data isn't on your home network
- **Scalability**: Room to grow without cost jumps

## **Database Schema for Grants Intelligence**

### **Core Tables Structure**

```sql
-- Raw grants data from Grants.gov
CREATE TABLE raw_grants (
    opportunity_id VARCHAR(50) PRIMARY KEY,
    opportunity_number VARCHAR(100),
    opportunity_title TEXT,
    cfda_number VARCHAR(20),
    cfda_title TEXT,
    funding_agency_code VARCHAR(10),
    funding_agency_name VARCHAR(200),
    award_ceiling DECIMAL(15,2),
    award_floor DECIMAL(15,2),
    posted_date DATE,
    close_date DATE,
    last_updated_date TIMESTAMP,
    opportunity_category VARCHAR(50),
    funding_instrument_type VARCHAR(100),
    eligible_applicants TEXT[],
    description TEXT,
    version_nb INTEGER,
    raw_xml_data JSONB  -- Store original XML for reference
);

-- Processed grants with intelligence flags
CREATE TABLE processed_grants (
    id SERIAL PRIMARY KEY,
    opportunity_id VARCHAR(50) REFERENCES raw_grants(opportunity_id),
    target_region VARCHAR(20), -- TX, OK, AR, etc.
    sector_category VARCHAR(100), -- Health, Education, etc.
    size_category VARCHAR(20), -- Small (50K-250K), Medium (250K-1M), Large (1M+)
    competition_level VARCHAR(20), -- Low, Medium, High (based on historical data)
    win_probability_score DECIMAL(3,2), -- 0.00 to 1.00
    strategic_notes TEXT,
    client_matches TEXT[], -- Array of client IDs this matches
    created_at TIMESTAMP DEFAULT NOW()
);

-- Historical award winners from USAspending.gov
CREATE TABLE award_winners (
    award_id VARCHAR(100) PRIMARY KEY,
    cfda_number VARCHAR(20),
    recipient_name VARCHAR(300),
    recipient_state VARCHAR(2),
    recipient_zip VARCHAR(10),
    award_amount DECIMAL(15,2),
    award_date DATE,
    funding_agency_name VARCHAR(200),
    project_title TEXT,
    project_description TEXT
);

-- Client profiles and preferences
CREATE TABLE clients (
    client_id SERIAL PRIMARY KEY,
    organization_name VARCHAR(200),
    contact_email VARCHAR(100),
    target_regions VARCHAR(10)[],
    focus_areas VARCHAR(100)[],
    min_award_size DECIMAL(15,2),
    max_award_size DECIMAL(15,2),
    cfda_preferences VARCHAR(20)[],
    subscription_tier VARCHAR(20),
    created_at TIMESTAMP DEFAULT NOW()
);

-- Weekly intelligence reports
CREATE TABLE intelligence_reports (
    report_id SERIAL PRIMARY KEY,
    client_id INTEGER REFERENCES clients(client_id),
    report_date DATE,
    opportunities_found INTEGER,
    key_insights TEXT,
    report_data JSONB,
    delivered_at TIMESTAMP
);
```

### **Key Indexes for Performance**

```sql
-- Fast filtering for common queries
CREATE INDEX idx_grants_cfda ON raw_grants(cfda_number);
CREATE INDEX idx_grants_agency ON raw_grants(funding_agency_code);
CREATE INDEX idx_grants_dates ON raw_grants(posted_date, close_date);
CREATE INDEX idx_grants_amount ON raw_grants(award_ceiling, award_floor);

-- Geographic and sector filtering
CREATE INDEX idx_winners_state ON award_winners(recipient_state);
CREATE INDEX idx_winners_cfda ON award_winners(cfda_number);
CREATE INDEX idx_winners_amount ON award_winners(award_amount);

-- Client matching
CREATE INDEX idx_processed_matches ON processed_grants USING GIN(client_matches);
```

### **Intelligence Views for Quick Analysis**

```sql
-- Texas health grants under $2M
CREATE VIEW tx_health_opportunities AS
SELECT rg.*, pg.win_probability_score, pg.competition_level
FROM raw_grants rg
JOIN processed_grants pg ON rg.opportunity_id = pg.opportunity_id
WHERE rg.cfda_number LIKE '93.%'  -- Health & Human Services
  AND rg.award_ceiling <= 2000000
  AND pg.target_region = 'TX'
  AND rg.close_date > CURRENT_DATE;

-- Weekly trend analysis
CREATE VIEW weekly_funding_trends AS
SELECT 
    funding_agency_name,
    COUNT(*) as new_opportunities,
    AVG(award_ceiling) as avg_award_size,
    SUM(award_ceiling) as total_funding
FROM raw_grants 
WHERE posted_date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY funding_agency_name
ORDER BY total_funding DESC;
```

## **Data Pipeline Architecture**

### **Weekly ETL Process**
1. **Extract**: Download Grants.gov XML files
2. **Transform**: Parse XML, clean data, calculate intelligence scores
3. **Load**: Insert into PostgreSQL with conflict resolution
4. **Analyze**: Update processed_grants with new insights
5. **Report**: Generate client-specific intelligence reports

### **Client Intelligence Queries**
```sql
-- Find grants matching a specific client profile
SELECT rg.opportunity_title, rg.funding_agency_name, 
       rg.award_ceiling, rg.close_date, pg.win_probability_score
FROM raw_grants rg
JOIN processed_grants pg ON rg.opportunity_id = pg.opportunity_id
WHERE pg.client_matches @> ARRAY['client_123']
  AND rg.close_date > CURRENT_DATE + INTERVAL '30 days'
ORDER BY pg.win_probability_score DESC;
```

This schema gives you:
- **Scalability**: Handle millions of grant records
- **Flexibility**: Easy to add new data sources (SAM.gov, etc.)
- **Performance**: Fast queries for client reports
- **Intelligence**: Built-in scoring and matching systems
- **Growth**: Room to add more sophisticated analytics

The OCI setup gives you enterprise-grade infrastructure at zero cost, while the schema design supports both your immediate needs and future expansion into contracts, more sophisticated AI analysis, and larger client bases.