Repository navigation
Expand file tree
/
Copy pathenv_template_db_init.sql
More file actions
147 lines (124 loc) · 3.8 KB
/
Copy pathenv_template_db_init.sql
File metadata and controls
147 lines (124 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
-- Each service should have its own database to enforce logical isolation
-- between services (which alleviates the headache of spinning up multiple
-- physical services).
--
-- USER SERVICE
--
CREATE DATABASE users;
-- substitutions occur via env_template_init.sh in Dockerfile.db; if not using
-- the orchestrated DB, you can skip this section.
GRANT ALL PRIVILEGES ON DATABASE users TO ${DB_USER};
\connect users;
-- the remainder of these commands create the data model + data for the
-- application
CREATE TABLE organizations (name TEXT PRIMARY KEY);
-- Note that this is synchronized with oso-policy.polar
CREATE TYPE organization_role AS ENUM ('admin', 'sales', 'analyst', 'deal_desk');
-- Do not allow duplicate usernames. Each user belongs to a single organization.
CREATE TABLE users (
username
TEXT PRIMARY KEY,
org
TEXT REFERENCES organizations (name),
"role"
organization_role,
manager
TEXT REFERENCES users (username)
);
-- Our special `global` organization
INSERT INTO organizations (name) VALUES ('_root');
-- A default, bootstrap user
INSERT INTO users (username, org, "role") VALUES ('root', '_root', 'admin');
-- substitutions occur via env_template_init.sh in Dockerfile.db; if not using
-- the orchestrated DB, you can skip this section.
CREATE DATABASE crm;
GRANT ALL PRIVILEGES ON DATABASE crm TO ${DB_USER};
\connect crm;
CREATE TABLE territories (
name TEXT PRIMARY KEY
);
CREATE TABLE territory_hierarchy (
ancestor_id TEXT NOT NULL REFERENCES territories(name),
descendant_id TEXT NOT NULL REFERENCES territories(name),
PRIMARY KEY (ancestor_id, descendant_id)
);
CREATE OR REPLACE FUNCTION get_ancestors(node_id TEXT)
RETURNS TEXT[] AS $$
WITH RECURSIVE ancestry AS (
SELECT ancestor_id, descendant_id, ARRAY[ancestor_id] as path, 1 as depth
FROM territory_hierarchy
WHERE descendant_id = node_id
AND ancestor_id != descendant_id
UNION ALL
SELECT t.ancestor_id, t.descendant_id, t.ancestor_id || a.path, a.depth + 1
FROM territory_hierarchy t
JOIN ancestry a ON t.descendant_id = a.ancestor_id
WHERE t.ancestor_id != t.descendant_id
)
SELECT COALESCE(
(SELECT path
FROM ancestry
ORDER BY depth DESC
LIMIT 1),
ARRAY[]::TEXT[]
);
$$ LANGUAGE SQL;
INSERT INTO territories (name) VALUES
('USA'),
('Northeast'),
('Northwest'),
('Southeast'),
('Southwest'),
('NY'),
('PA'),
('FL'),
('WA'),
('AZ'),
('NYC'),
('Staten Island'),
('Philadelphia'),
('Gainesville'),
('Tampa'),
('Seattle'),
('Tacoma'),
('Phoenix'),
('Tucson');
INSERT INTO territory_hierarchy (ancestor_id, descendant_id) VALUES
('USA', 'Northeast'),
('Northeast', 'NY'),
('NY', 'NYC'),
('NY', 'Staten Island'),
('Northeast', 'PA'),
('PA', 'Philadelphia'),
('USA', 'Northwest'),
('Northwest', 'WA'),
('WA', 'Seattle'),
('WA', 'Tacoma'),
('USA', 'Southeast'),
('Southeast', 'FL'),
('FL', 'Gainesville'),
('FL', 'Tampa'),
('USA', 'Southwest'),
('Southwest', 'AZ'),
('AZ', 'Phoenix'),
('AZ', 'Tucson');
CREATE TABLE sales_territory_manager(
org TEXT NOT NULL,
territory TEXT NOT NULL REFERENCES territories(name),
username TEXT NOT NULL,
PRIMARY KEY (org, territory)
);
CREATE TYPE opportunity_stage AS ENUM ('research', 'qualifying', 'poc', 'negotiating', 'closed-won', 'closed-lost');
CREATE TABLE opportunities (
name TEXT NOT NULL,
territory TEXT NOT NULL REFERENCES territories(name),
amount DECIMAL(10, 2) DEFAULT 0.0,
assignee TEXT,
organization TEXT NOT NULL,
stage opportunity_stage,
PRIMARY KEY (name, organization)
);
-- For more details about how this interacts with other components of the system,
-- see:
-- - oso_policy.polar for this application's Polar policy, for use in Oso Cloud
-- - oso_local_auth_*.yml for how services correlate the policy to the SQL schema