Skip to content
This repository was archived by the owner on Jul 1, 2025. It is now read-only.

Commit 43c132c

Browse files
dfcoffinclaude
andcommitted
Create comprehensive PostgreSQL migration scripts for ESPI-compliant database schemas
- Add 6 Flyway PostgreSQL migration scripts (V1-V6) equivalent to MySQL migrations - Implement PostgreSQL-specific data types (BIGSERIAL, TIMESTAMP WITH TIME ZONE, JSONB) - Maintain ESPI 1.0 specification compliance with ATOM href URL loose coupling - Create separate openespi_usage and openespi_customer schemas with proper separation - Add GIN indexes for JSONB fields and comprehensive indexing strategy - Include automatic timestamp triggers and proper foreign key relationships - Fix syntax error in V5 asset_containers table definition 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 984e7b0 commit 43c132c

6 files changed

+1524
-0
lines changed
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/*
2+
* OpenESPI Usage Schema - Base Tables Migration (PostgreSQL)
3+
*
4+
* Copyright (c) 2018-2025 Green Button Alliance, Inc.
5+
* Licensed under the Apache License, Version 2.0
6+
*
7+
* This migration creates the foundational tables for the OpenESPI usage schema.
8+
* These tables implement the NAESB Energy Services Provider Interface (ESPI) 1.0 specification
9+
* for energy usage data exchange and Green Button data standards.
10+
*
11+
* PostgreSQL-specific implementation with proper data types and indexing.
12+
*/
13+
14+
-- Set schema for usage data
15+
SET search_path TO openespi_usage;
16+
17+
-- Application Information Table
18+
-- Stores information about third-party applications that access usage data
19+
CREATE TABLE application_information (
20+
id BIGSERIAL PRIMARY KEY,
21+
uuid VARCHAR(36) NOT NULL UNIQUE,
22+
uuid_msb BIGINT,
23+
uuid_lsb BIGINT,
24+
description VARCHAR(255),
25+
created TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
26+
updated TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
27+
published TIMESTAMP(6) WITH TIME ZONE,
28+
up_link_rel VARCHAR(255),
29+
up_link_href VARCHAR(1024),
30+
self_link_rel VARCHAR(255),
31+
self_link_href VARCHAR(1024),
32+
33+
-- Application specific fields
34+
client_name VARCHAR(255),
35+
client_id VARCHAR(255) NOT NULL UNIQUE,
36+
client_secret VARCHAR(255),
37+
client_id_issued_at BIGINT,
38+
client_secret_expires_at BIGINT,
39+
registration_client_uri VARCHAR(1024),
40+
registration_access_token VARCHAR(1024),
41+
redirect_uris TEXT,
42+
software_id VARCHAR(255),
43+
software_version VARCHAR(255),
44+
token_endpoint_auth_method VARCHAR(50),
45+
response_types VARCHAR(255),
46+
grant_types VARCHAR(255),
47+
application_type VARCHAR(50),
48+
contacts TEXT,
49+
logo_uri VARCHAR(1024),
50+
policy_uri VARCHAR(1024),
51+
tos_uri VARCHAR(1024),
52+
jwks_uri VARCHAR(1024),
53+
sector_identifier_uri VARCHAR(1024),
54+
subject_type VARCHAR(50),
55+
id_token_signed_response_alg VARCHAR(50),
56+
id_token_encrypted_response_alg VARCHAR(50),
57+
id_token_encrypted_response_enc VARCHAR(50),
58+
userinfo_signed_response_alg VARCHAR(50),
59+
userinfo_encrypted_response_alg VARCHAR(50),
60+
userinfo_encrypted_response_enc VARCHAR(50),
61+
request_object_signing_alg VARCHAR(50),
62+
request_object_encryption_alg VARCHAR(50),
63+
request_object_encryption_enc VARCHAR(50),
64+
default_max_age BIGINT,
65+
require_auth_time BOOLEAN DEFAULT FALSE,
66+
default_acr_values VARCHAR(255),
67+
initiate_login_uri VARCHAR(1024),
68+
request_uris TEXT
69+
);
70+
71+
-- Create indexes for application_information
72+
CREATE INDEX idx_application_client_id ON application_information(client_id);
73+
CREATE INDEX idx_application_uuid ON application_information(uuid);
74+
CREATE INDEX idx_application_created ON application_information(created);
75+
CREATE INDEX idx_application_updated ON application_information(updated);
76+
77+
-- Related Links Table for Application Information
78+
CREATE TABLE application_information_related_links (
79+
application_information_id BIGINT NOT NULL REFERENCES application_information(id) ON DELETE CASCADE,
80+
related_links VARCHAR(1024)
81+
);
82+
83+
CREATE INDEX idx_app_info_related_links ON application_information_related_links(application_information_id);
84+
85+
-- Retail Customer Table
86+
-- Represents energy consumers with access to their usage data
87+
CREATE TABLE retail_customers (
88+
id BIGSERIAL PRIMARY KEY,
89+
uuid VARCHAR(36) NOT NULL UNIQUE,
90+
uuid_msb BIGINT,
91+
uuid_lsb BIGINT,
92+
description VARCHAR(255),
93+
created TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
94+
updated TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
95+
published TIMESTAMP(6) WITH TIME ZONE,
96+
up_link_rel VARCHAR(255),
97+
up_link_href VARCHAR(1024),
98+
self_link_rel VARCHAR(255),
99+
self_link_href VARCHAR(1024),
100+
101+
-- Retail customer specific fields
102+
username VARCHAR(255) UNIQUE,
103+
first_name VARCHAR(255),
104+
last_name VARCHAR(255),
105+
password VARCHAR(255),
106+
enabled BOOLEAN DEFAULT TRUE,
107+
role VARCHAR(50) DEFAULT 'ROLE_USER'
108+
);
109+
110+
-- Create indexes for retail_customers
111+
CREATE INDEX idx_retail_customer_uuid ON retail_customers(uuid);
112+
CREATE INDEX idx_retail_customer_username ON retail_customers(username);
113+
CREATE INDEX idx_retail_customer_created ON retail_customers(created);
114+
CREATE INDEX idx_retail_customer_updated ON retail_customers(updated);
115+
116+
-- Related Links Table for Retail Customers
117+
CREATE TABLE retail_customer_related_links (
118+
retail_customer_id BIGINT NOT NULL REFERENCES retail_customers(id) ON DELETE CASCADE,
119+
related_links VARCHAR(1024)
120+
);
121+
122+
CREATE INDEX idx_retail_customer_related_links ON retail_customer_related_links(retail_customer_id);
123+
124+
-- Authorization Table
125+
-- OAuth 2.0 authorization grants for third-party access to usage data
126+
CREATE TABLE authorizations (
127+
id BIGSERIAL PRIMARY KEY,
128+
uuid VARCHAR(36) NOT NULL UNIQUE,
129+
uuid_msb BIGINT,
130+
uuid_lsb BIGINT,
131+
description VARCHAR(255),
132+
created TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
133+
updated TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
134+
published TIMESTAMP(6) WITH TIME ZONE,
135+
up_link_rel VARCHAR(255),
136+
up_link_href VARCHAR(1024),
137+
self_link_rel VARCHAR(255),
138+
self_link_href VARCHAR(1024),
139+
140+
-- Authorization specific fields
141+
application_information_id BIGINT REFERENCES application_information(id) ON DELETE CASCADE,
142+
retail_customer_id BIGINT REFERENCES retail_customers(id) ON DELETE CASCADE,
143+
access_token VARCHAR(1024),
144+
refresh_token VARCHAR(1024),
145+
authorization_uri VARCHAR(1024),
146+
ap_title VARCHAR(255),
147+
ap_description TEXT,
148+
ap_duration BIGINT,
149+
scope VARCHAR(1024),
150+
token_type VARCHAR(50) DEFAULT 'Bearer',
151+
expires_in BIGINT,
152+
state VARCHAR(255),
153+
error VARCHAR(255),
154+
error_description TEXT,
155+
error_uri VARCHAR(1024),
156+
resource_uri VARCHAR(1024),
157+
customer_resource_uri VARCHAR(1024),
158+
status VARCHAR(50) DEFAULT 'ACTIVE',
159+
expires_at TIMESTAMP(6) WITH TIME ZONE,
160+
grant_type VARCHAR(50),
161+
response_type VARCHAR(50),
162+
third_party VARCHAR(255)
163+
);
164+
165+
-- Create indexes for authorizations
166+
CREATE INDEX idx_authorization_uuid ON authorizations(uuid);
167+
CREATE INDEX idx_authorization_access_token ON authorizations(access_token);
168+
CREATE INDEX idx_authorization_refresh_token ON authorizations(refresh_token);
169+
CREATE INDEX idx_authorization_app_id ON authorizations(application_information_id);
170+
CREATE INDEX idx_authorization_customer_id ON authorizations(retail_customer_id);
171+
CREATE INDEX idx_authorization_status ON authorizations(status);
172+
CREATE INDEX idx_authorization_expires_at ON authorizations(expires_at);
173+
CREATE INDEX idx_authorization_created ON authorizations(created);
174+
CREATE INDEX idx_authorization_updated ON authorizations(updated);
175+
176+
-- Related Links Table for Authorizations
177+
CREATE TABLE authorization_related_links (
178+
authorization_id BIGINT NOT NULL REFERENCES authorizations(id) ON DELETE CASCADE,
179+
related_links VARCHAR(1024)
180+
);
181+
182+
CREATE INDEX idx_authorization_related_links ON authorization_related_links(authorization_id);
183+
184+
-- Service Delivery Point Table
185+
-- Physical locations where energy services are delivered
186+
CREATE TABLE service_delivery_points (
187+
id BIGSERIAL PRIMARY KEY,
188+
uuid VARCHAR(36) NOT NULL UNIQUE,
189+
uuid_msb BIGINT,
190+
uuid_lsb BIGINT,
191+
description VARCHAR(255),
192+
created TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
193+
updated TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
194+
published TIMESTAMP(6) WITH TIME ZONE,
195+
up_link_rel VARCHAR(255),
196+
up_link_href VARCHAR(1024),
197+
self_link_rel VARCHAR(255),
198+
self_link_href VARCHAR(1024),
199+
200+
-- Service delivery point specific fields
201+
name VARCHAR(256),
202+
tariff_profile VARCHAR(256),
203+
customer_agreement VARCHAR(256)
204+
);
205+
206+
-- Create indexes for service_delivery_points
207+
CREATE INDEX idx_sdp_uuid ON service_delivery_points(uuid);
208+
CREATE INDEX idx_sdp_name ON service_delivery_points(name);
209+
CREATE INDEX idx_sdp_tariff_profile ON service_delivery_points(tariff_profile);
210+
CREATE INDEX idx_sdp_customer_agreement ON service_delivery_points(customer_agreement);
211+
CREATE INDEX idx_sdp_created ON service_delivery_points(created);
212+
CREATE INDEX idx_sdp_updated ON service_delivery_points(updated);
213+
214+
-- Related Links Table for Service Delivery Points
215+
CREATE TABLE service_delivery_point_related_links (
216+
service_delivery_point_id BIGINT NOT NULL REFERENCES service_delivery_points(id) ON DELETE CASCADE,
217+
related_links VARCHAR(1024)
218+
);
219+
220+
CREATE INDEX idx_sdp_related_links ON service_delivery_point_related_links(service_delivery_point_id);
221+
222+
-- Create trigger function for updating timestamps
223+
CREATE OR REPLACE FUNCTION update_updated_column()
224+
RETURNS TRIGGER AS $$
225+
BEGIN
226+
NEW.updated = CURRENT_TIMESTAMP;
227+
RETURN NEW;
228+
END;
229+
$$ language 'plpgsql';
230+
231+
-- Create triggers for automatic timestamp updates
232+
CREATE TRIGGER update_application_information_updated BEFORE UPDATE ON application_information FOR EACH ROW EXECUTE FUNCTION update_updated_column();
233+
CREATE TRIGGER update_retail_customers_updated BEFORE UPDATE ON retail_customers FOR EACH ROW EXECUTE FUNCTION update_updated_column();
234+
CREATE TRIGGER update_authorizations_updated BEFORE UPDATE ON authorizations FOR EACH ROW EXECUTE FUNCTION update_updated_column();
235+
CREATE TRIGGER update_service_delivery_points_updated BEFORE UPDATE ON service_delivery_points FOR EACH ROW EXECUTE FUNCTION update_updated_column();

0 commit comments

Comments
 (0)