auto-claude: subtask-2-3 - Create database migration script for GBP audit tab
- Create gbp_audits table with all required fields: - completeness_score (0-100) - fields_status and recommendations (JSONB) - Individual field flags (has_name, has_phone, etc.) - Photo and review metrics - Google Place integration fields - Audit metadata (source, version, errors) - Add indexes for company_id, audit_date, and score - Add update trigger for updated_at timestamp - Create views: v_company_gbp_overview, v_gbp_audit_history - Include GRANT statements for nordabiz_app user Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
edb3d41f49
commit
ecf811f168
216
database/migrations/add_gbp_audit.sql
Normal file
216
database/migrations/add_gbp_audit.sql
Normal file
@ -0,0 +1,216 @@
|
||||
-- ============================================================
|
||||
-- NordaBiz - Migration: Google Business Profile (GBP) Audit Tables
|
||||
-- ============================================================
|
||||
-- Created: 2026-01-08
|
||||
-- Description:
|
||||
-- - Creates gbp_audits table for storing GBP completeness audit results
|
||||
-- - Tracks field-by-field status with JSONB for flexibility
|
||||
-- - Stores AI-generated recommendations
|
||||
-- - Includes indexes and helpful views
|
||||
--
|
||||
-- Usage:
|
||||
-- PostgreSQL: psql -h localhost -U nordabiz_app -d nordabiz -f add_gbp_audit.sql
|
||||
-- SQLite: Not fully supported (JSONB columns)
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- 1. MAIN GBP_AUDITS TABLE
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS gbp_audits (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- Company reference
|
||||
company_id INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
||||
|
||||
-- Audit timestamp
|
||||
audit_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- Completeness scoring (0-100)
|
||||
completeness_score INTEGER,
|
||||
|
||||
-- Field-by-field status tracking (JSONB)
|
||||
-- Example: {"name": {"status": "complete", "value": "Company Name"}, "phone": {"status": "missing"}, ...}
|
||||
fields_status JSONB,
|
||||
|
||||
-- AI-generated recommendations (JSONB)
|
||||
-- Example: [{"priority": "high", "field": "description", "recommendation": "Add a detailed business description..."}, ...]
|
||||
recommendations JSONB,
|
||||
|
||||
-- Individual field completion flags
|
||||
has_name BOOLEAN DEFAULT FALSE,
|
||||
has_address BOOLEAN DEFAULT FALSE,
|
||||
has_phone BOOLEAN DEFAULT FALSE,
|
||||
has_website BOOLEAN DEFAULT FALSE,
|
||||
has_hours BOOLEAN DEFAULT FALSE,
|
||||
has_categories BOOLEAN DEFAULT FALSE,
|
||||
has_photos BOOLEAN DEFAULT FALSE,
|
||||
has_description BOOLEAN DEFAULT FALSE,
|
||||
has_services BOOLEAN DEFAULT FALSE,
|
||||
has_reviews BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- Photo metrics
|
||||
photo_count INTEGER DEFAULT 0,
|
||||
logo_present BOOLEAN DEFAULT FALSE,
|
||||
cover_photo_present BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- Review metrics
|
||||
review_count INTEGER DEFAULT 0,
|
||||
average_rating NUMERIC(2, 1),
|
||||
|
||||
-- Google Place integration
|
||||
google_place_id VARCHAR(100),
|
||||
google_maps_url VARCHAR(500),
|
||||
|
||||
-- Audit metadata
|
||||
audit_source VARCHAR(50) DEFAULT 'manual', -- manual, automated, api
|
||||
audit_version VARCHAR(20) DEFAULT '1.0',
|
||||
audit_errors TEXT,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
COMMENT ON TABLE gbp_audits IS 'Google Business Profile completeness audit results';
|
||||
COMMENT ON COLUMN gbp_audits.completeness_score IS 'Overall GBP completeness score 0-100';
|
||||
COMMENT ON COLUMN gbp_audits.fields_status IS 'Field-by-field status with values as JSON';
|
||||
COMMENT ON COLUMN gbp_audits.recommendations IS 'AI-generated improvement recommendations as JSON array';
|
||||
COMMENT ON COLUMN gbp_audits.audit_source IS 'How audit was triggered: manual, automated, api';
|
||||
COMMENT ON COLUMN gbp_audits.google_place_id IS 'Google Places API place_id for verification';
|
||||
COMMENT ON COLUMN gbp_audits.google_maps_url IS 'Direct link to Google Maps listing';
|
||||
|
||||
-- ============================================================
|
||||
-- 2. INDEXES FOR PERFORMANCE
|
||||
-- ============================================================
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_audits_company ON gbp_audits(company_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_audits_date ON gbp_audits(audit_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_audits_score ON gbp_audits(completeness_score);
|
||||
CREATE INDEX IF NOT EXISTS idx_gbp_audits_company_date ON gbp_audits(company_id, audit_date DESC);
|
||||
|
||||
-- ============================================================
|
||||
-- 3. UPDATE TRIGGER FOR updated_at
|
||||
-- ============================================================
|
||||
|
||||
CREATE OR REPLACE FUNCTION gbp_audits_update_timestamp()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DROP TRIGGER IF EXISTS trigger_gbp_audits_update ON gbp_audits;
|
||||
CREATE TRIGGER trigger_gbp_audits_update
|
||||
BEFORE UPDATE ON gbp_audits
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION gbp_audits_update_timestamp();
|
||||
|
||||
-- ============================================================
|
||||
-- 4. GBP AUDIT OVERVIEW VIEW
|
||||
-- ============================================================
|
||||
|
||||
CREATE OR REPLACE VIEW v_company_gbp_overview AS
|
||||
SELECT
|
||||
c.id,
|
||||
c.name,
|
||||
c.slug,
|
||||
c.website,
|
||||
cat.name as category_name,
|
||||
ga.completeness_score,
|
||||
ga.has_name,
|
||||
ga.has_address,
|
||||
ga.has_phone,
|
||||
ga.has_website,
|
||||
ga.has_hours,
|
||||
ga.has_categories,
|
||||
ga.has_photos,
|
||||
ga.has_description,
|
||||
ga.has_services,
|
||||
ga.has_reviews,
|
||||
ga.photo_count,
|
||||
ga.review_count,
|
||||
ga.average_rating,
|
||||
ga.google_place_id,
|
||||
ga.audit_date,
|
||||
ga.audit_source,
|
||||
-- Score category
|
||||
CASE
|
||||
WHEN ga.completeness_score >= 90 THEN 'excellent'
|
||||
WHEN ga.completeness_score >= 70 THEN 'good'
|
||||
WHEN ga.completeness_score >= 50 THEN 'needs_work'
|
||||
WHEN ga.completeness_score IS NOT NULL THEN 'poor'
|
||||
ELSE 'not_audited'
|
||||
END as score_category
|
||||
FROM companies c
|
||||
LEFT JOIN categories cat ON c.category_id = cat.id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT * FROM gbp_audits
|
||||
WHERE company_id = c.id
|
||||
ORDER BY audit_date DESC
|
||||
LIMIT 1
|
||||
) ga ON TRUE
|
||||
ORDER BY ga.completeness_score DESC NULLS LAST;
|
||||
|
||||
COMMENT ON VIEW v_company_gbp_overview IS 'Latest GBP audit results per company for dashboard';
|
||||
|
||||
-- ============================================================
|
||||
-- 5. GBP AUDIT HISTORY VIEW
|
||||
-- ============================================================
|
||||
|
||||
CREATE OR REPLACE VIEW v_gbp_audit_history AS
|
||||
SELECT
|
||||
ga.id as audit_id,
|
||||
c.id as company_id,
|
||||
c.name as company_name,
|
||||
c.slug as company_slug,
|
||||
ga.completeness_score,
|
||||
ga.audit_date,
|
||||
ga.audit_source,
|
||||
ga.audit_version,
|
||||
-- Previous score for comparison
|
||||
LAG(ga.completeness_score) OVER (
|
||||
PARTITION BY ga.company_id
|
||||
ORDER BY ga.audit_date
|
||||
) as previous_score,
|
||||
-- Score change
|
||||
ga.completeness_score - LAG(ga.completeness_score) OVER (
|
||||
PARTITION BY ga.company_id
|
||||
ORDER BY ga.audit_date
|
||||
) as score_change
|
||||
FROM gbp_audits ga
|
||||
JOIN companies c ON ga.company_id = c.id
|
||||
ORDER BY ga.audit_date DESC;
|
||||
|
||||
COMMENT ON VIEW v_gbp_audit_history IS 'GBP audit history with score trend tracking';
|
||||
|
||||
-- ============================================================
|
||||
-- 6. GRANTS FOR APPLICATION USER
|
||||
-- ============================================================
|
||||
|
||||
-- Grant permissions on table
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE gbp_audits TO nordabiz_app;
|
||||
|
||||
-- Grant permissions on sequence
|
||||
GRANT USAGE, SELECT ON SEQUENCE gbp_audits_id_seq TO nordabiz_app;
|
||||
|
||||
-- Grant permissions on views
|
||||
GRANT SELECT ON v_company_gbp_overview TO nordabiz_app;
|
||||
GRANT SELECT ON v_gbp_audit_history TO nordabiz_app;
|
||||
|
||||
-- ============================================================
|
||||
-- MIGRATION COMPLETE
|
||||
-- ============================================================
|
||||
|
||||
-- Verify migration (PostgreSQL only)
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'GBP Audit migration completed successfully!';
|
||||
RAISE NOTICE 'Created:';
|
||||
RAISE NOTICE ' - Table: gbp_audits';
|
||||
RAISE NOTICE ' - Indexes: company_id, audit_date, completeness_score, company_date';
|
||||
RAISE NOTICE ' - Trigger: updated_at auto-update';
|
||||
RAISE NOTICE ' - Views: v_company_gbp_overview, v_gbp_audit_history';
|
||||
RAISE NOTICE ' - Grants: nordabiz_app permissions';
|
||||
END $$;
|
||||
Loading…
Reference in New Issue
Block a user