gmoonc 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/assets/supabase/001_tables.sql +117 -0
- package/assets/supabase/002_rls.sql +223 -0
- package/assets/supabase/003_functions_triggers.sql +244 -0
- package/assets/supabase/004_seed.sql +126 -0
- package/dist/index.cjs +210 -12
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -37,6 +37,44 @@ npx gmoonc --base /dashboard
|
|
|
37
37
|
- `--skip-router-patch`: Skip automatic router integration (only copy files and inject CSS)
|
|
38
38
|
- `--dry-run`: Show what would be done without making changes
|
|
39
39
|
|
|
40
|
+
## Supabase Integration
|
|
41
|
+
|
|
42
|
+
### Setup Supabase Auth + RBAC
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx gmoonc supabase --vite
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This command:
|
|
49
|
+
- Installs `@supabase/supabase-js` dependency
|
|
50
|
+
- Generates Supabase client, env validation, and RBAC helpers
|
|
51
|
+
- Creates/updates `.env.example` with Supabase variables
|
|
52
|
+
- Automatically patches existing code to use Supabase provider
|
|
53
|
+
|
|
54
|
+
### Seed Database
|
|
55
|
+
|
|
56
|
+
After setting up Supabase integration, seed your database with the complete schema:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx gmoonc supabase-seed --vite
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Prerequisites:**
|
|
63
|
+
- `gmoonc` must be installed (`npx gmoonc`)
|
|
64
|
+
- `supabase --vite` must have been executed
|
|
65
|
+
- `.env.local` must contain `SUPABASE_DB_URL` (connection string from Supabase Dashboard → Settings → Database)
|
|
66
|
+
|
|
67
|
+
**What it does:**
|
|
68
|
+
- Executes SQL files in order: tables → functions/triggers → RLS → seed data
|
|
69
|
+
- Creates marker file `.gmoonc/supabase-seed.json` to prevent duplicate execution
|
|
70
|
+
- One-shot by default (delete marker to re-seed)
|
|
71
|
+
|
|
72
|
+
**To get `SUPABASE_DB_URL`:**
|
|
73
|
+
1. Go to your Supabase project dashboard
|
|
74
|
+
2. Navigate to Settings → Database
|
|
75
|
+
3. Copy the "Connection string (URI)"
|
|
76
|
+
4. Add to `.env.local` as: `SUPABASE_DB_URL=postgresql://postgres:[PASSWORD]@[HOST]:5432/postgres`
|
|
77
|
+
|
|
40
78
|
## After installation
|
|
41
79
|
|
|
42
80
|
Your dashboard is now available at:
|
|
@@ -63,6 +101,13 @@ The logo is installed at `src/gmoonc/assets/gmoonc-logo.png`. You can replace it
|
|
|
63
101
|
|
|
64
102
|
## Changelog
|
|
65
103
|
|
|
104
|
+
### 0.0.22
|
|
105
|
+
- Feature: New `supabase-seed --vite` command to seed Supabase database
|
|
106
|
+
- Feature: Automatic SQL file execution (tables, functions, RLS, seed data)
|
|
107
|
+
- Feature: One-shot protection with marker file
|
|
108
|
+
- Feature: SQL files copied to project for transparency
|
|
109
|
+
- Feature: SUPABASE_DB_URL added to .env.example
|
|
110
|
+
|
|
66
111
|
### 0.0.21
|
|
67
112
|
- Fix: Navigate import now always added when route protection is present in GMooncAppLayout.tsx
|
|
68
113
|
- Fix: Improved Navigate import detection - checks for route protection code, not just usage
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
-- ============================================
|
|
2
|
+
-- 001_tables.sql: Definição de Tabelas (gmoonc)
|
|
3
|
+
-- ============================================
|
|
4
|
+
-- Contém apenas CREATE TABLE no formato final
|
|
5
|
+
-- Sem ALTER TABLE redundantes
|
|
6
|
+
-- Schema para gmoonc (Sicoop-app refatorado)
|
|
7
|
+
|
|
8
|
+
-- ============================================
|
|
9
|
+
-- profiles - Usuários do Sistema
|
|
10
|
+
-- ============================================
|
|
11
|
+
CREATE TABLE IF NOT EXISTS public.profiles (
|
|
12
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
13
|
+
email TEXT UNIQUE NOT NULL,
|
|
14
|
+
name TEXT NOT NULL,
|
|
15
|
+
role TEXT NOT NULL,
|
|
16
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
17
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
-- ============================================
|
|
21
|
+
-- roles - Papéis/Funções do Sistema
|
|
22
|
+
-- ============================================
|
|
23
|
+
CREATE TABLE IF NOT EXISTS public.roles (
|
|
24
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
25
|
+
name TEXT UNIQUE NOT NULL,
|
|
26
|
+
description TEXT,
|
|
27
|
+
is_system_role BOOLEAN DEFAULT true,
|
|
28
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
29
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
-- ============================================
|
|
33
|
+
-- modules - Módulos da Aplicação
|
|
34
|
+
-- ============================================
|
|
35
|
+
CREATE TABLE IF NOT EXISTS public.modules (
|
|
36
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
37
|
+
name TEXT UNIQUE NOT NULL,
|
|
38
|
+
display_name TEXT NOT NULL,
|
|
39
|
+
description TEXT,
|
|
40
|
+
is_active BOOLEAN DEFAULT true,
|
|
41
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
42
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
-- ============================================
|
|
46
|
+
-- permissions - Permissões por Role e Módulo
|
|
47
|
+
-- ============================================
|
|
48
|
+
CREATE TABLE IF NOT EXISTS public.permissions (
|
|
49
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
50
|
+
role_id UUID NOT NULL REFERENCES public.roles(id) ON DELETE CASCADE,
|
|
51
|
+
module_id UUID NOT NULL REFERENCES public.modules(id) ON DELETE CASCADE,
|
|
52
|
+
can_access BOOLEAN DEFAULT false,
|
|
53
|
+
can_create BOOLEAN DEFAULT false,
|
|
54
|
+
can_read BOOLEAN DEFAULT false,
|
|
55
|
+
can_update BOOLEAN DEFAULT false,
|
|
56
|
+
can_delete BOOLEAN DEFAULT false,
|
|
57
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
58
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
-- ============================================
|
|
62
|
+
-- messages - Sistema de Mensagens (renomeado de mensagens)
|
|
63
|
+
-- ============================================
|
|
64
|
+
CREATE TABLE IF NOT EXISTS public.messages (
|
|
65
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
66
|
+
user_id UUID REFERENCES public.profiles(id) ON DELETE CASCADE,
|
|
67
|
+
name TEXT NOT NULL,
|
|
68
|
+
email TEXT NOT NULL,
|
|
69
|
+
phone TEXT,
|
|
70
|
+
company_farm TEXT NOT NULL,
|
|
71
|
+
message TEXT NOT NULL,
|
|
72
|
+
status TEXT CHECK (status IS NULL OR status IN ('draft', 'pending', 'in_analysis', 'completed', 'cancelled')) DEFAULT 'pending',
|
|
73
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
74
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
-- ============================================
|
|
78
|
+
-- notification_categories - Categorias de Notificação
|
|
79
|
+
-- ============================================
|
|
80
|
+
CREATE TABLE IF NOT EXISTS public.notification_categories (
|
|
81
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
82
|
+
name TEXT UNIQUE NOT NULL,
|
|
83
|
+
display_name TEXT NOT NULL,
|
|
84
|
+
description TEXT,
|
|
85
|
+
is_active BOOLEAN DEFAULT true,
|
|
86
|
+
email_template_subject TEXT,
|
|
87
|
+
email_template_body TEXT,
|
|
88
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
89
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
-- ============================================
|
|
93
|
+
-- notification_settings - Preferências de Notificação
|
|
94
|
+
-- ============================================
|
|
95
|
+
CREATE TABLE IF NOT EXISTS public.notification_settings (
|
|
96
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
97
|
+
user_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
|
|
98
|
+
category_id UUID NOT NULL REFERENCES public.notification_categories(id) ON DELETE CASCADE,
|
|
99
|
+
is_enabled BOOLEAN DEFAULT true,
|
|
100
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
101
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
-- ============================================
|
|
105
|
+
-- notification_logs - Histórico de Notificações
|
|
106
|
+
-- ============================================
|
|
107
|
+
CREATE TABLE IF NOT EXISTS public.notification_logs (
|
|
108
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
109
|
+
category_id UUID NOT NULL REFERENCES public.notification_categories(id) ON DELETE CASCADE,
|
|
110
|
+
user_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
|
|
111
|
+
entity_type TEXT NOT NULL,
|
|
112
|
+
entity_id TEXT NOT NULL,
|
|
113
|
+
email_sent BOOLEAN,
|
|
114
|
+
email_error TEXT,
|
|
115
|
+
sent_at TIMESTAMP WITH TIME ZONE,
|
|
116
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
117
|
+
);
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
-- ============================================
|
|
2
|
+
-- 002_rls.sql: Row Level Security e Políticas (gmoonc)
|
|
3
|
+
-- ============================================
|
|
4
|
+
-- Habilita RLS e define políticas de acesso
|
|
5
|
+
-- Políticas para gmoonc
|
|
6
|
+
|
|
7
|
+
-- ============================================
|
|
8
|
+
-- ENABLE RLS em todas as tabelas
|
|
9
|
+
-- ============================================
|
|
10
|
+
|
|
11
|
+
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
|
|
12
|
+
ALTER TABLE public.roles ENABLE ROW LEVEL SECURITY;
|
|
13
|
+
ALTER TABLE public.modules ENABLE ROW LEVEL SECURITY;
|
|
14
|
+
ALTER TABLE public.permissions ENABLE ROW LEVEL SECURITY;
|
|
15
|
+
ALTER TABLE public.messages ENABLE ROW LEVEL SECURITY;
|
|
16
|
+
ALTER TABLE public.notification_categories ENABLE ROW LEVEL SECURITY;
|
|
17
|
+
ALTER TABLE public.notification_settings ENABLE ROW LEVEL SECURITY;
|
|
18
|
+
ALTER TABLE public.notification_logs ENABLE ROW LEVEL SECURITY;
|
|
19
|
+
|
|
20
|
+
-- ============================================
|
|
21
|
+
-- POLÍTICAS: profiles
|
|
22
|
+
-- ============================================
|
|
23
|
+
|
|
24
|
+
-- Administradores podem ver todos os perfis
|
|
25
|
+
CREATE POLICY "admin_can_read_all_profiles" ON public.profiles
|
|
26
|
+
FOR SELECT
|
|
27
|
+
USING (
|
|
28
|
+
auth.uid() IN (
|
|
29
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
-- Usuários podem ver seu próprio perfil
|
|
34
|
+
CREATE POLICY "users_can_read_own_profile" ON public.profiles
|
|
35
|
+
FOR SELECT
|
|
36
|
+
USING (auth.uid() = id);
|
|
37
|
+
|
|
38
|
+
-- Administradores podem atualizar qualquer perfil
|
|
39
|
+
CREATE POLICY "admin_can_update_all_profiles" ON public.profiles
|
|
40
|
+
FOR UPDATE
|
|
41
|
+
USING (
|
|
42
|
+
auth.uid() IN (
|
|
43
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
-- Usuários podem atualizar seu próprio perfil
|
|
48
|
+
CREATE POLICY "users_can_update_own_profile" ON public.profiles
|
|
49
|
+
FOR UPDATE
|
|
50
|
+
USING (auth.uid() = id);
|
|
51
|
+
|
|
52
|
+
-- ============================================
|
|
53
|
+
-- POLÍTICAS: roles
|
|
54
|
+
-- ============================================
|
|
55
|
+
|
|
56
|
+
-- Todos podem ler roles (necessário para aplicação)
|
|
57
|
+
CREATE POLICY "all_can_read_roles" ON public.roles
|
|
58
|
+
FOR SELECT
|
|
59
|
+
USING (true);
|
|
60
|
+
|
|
61
|
+
-- Apenas administradores podem criar/atualizar/deletar roles
|
|
62
|
+
CREATE POLICY "admin_can_manage_roles" ON public.roles
|
|
63
|
+
FOR ALL
|
|
64
|
+
USING (
|
|
65
|
+
auth.uid() IN (
|
|
66
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
-- ============================================
|
|
71
|
+
-- POLÍTICAS: modules
|
|
72
|
+
-- ============================================
|
|
73
|
+
|
|
74
|
+
-- Todos podem ler módulos
|
|
75
|
+
CREATE POLICY "all_can_read_modules" ON public.modules
|
|
76
|
+
FOR SELECT
|
|
77
|
+
USING (true);
|
|
78
|
+
|
|
79
|
+
-- Apenas administradores podem gerenciar módulos
|
|
80
|
+
CREATE POLICY "admin_can_manage_modules" ON public.modules
|
|
81
|
+
FOR ALL
|
|
82
|
+
USING (
|
|
83
|
+
auth.uid() IN (
|
|
84
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
85
|
+
)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
-- ============================================
|
|
89
|
+
-- POLÍTICAS: permissions
|
|
90
|
+
-- ============================================
|
|
91
|
+
|
|
92
|
+
-- Todos podem ler permissões (necessário para verificar acesso)
|
|
93
|
+
CREATE POLICY "all_can_read_permissions" ON public.permissions
|
|
94
|
+
FOR SELECT
|
|
95
|
+
USING (true);
|
|
96
|
+
|
|
97
|
+
-- Apenas administradores podem gerenciar permissões
|
|
98
|
+
CREATE POLICY "admin_can_manage_permissions" ON public.permissions
|
|
99
|
+
FOR ALL
|
|
100
|
+
USING (
|
|
101
|
+
auth.uid() IN (
|
|
102
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
-- ============================================
|
|
107
|
+
-- POLÍTICAS: messages
|
|
108
|
+
-- ============================================
|
|
109
|
+
|
|
110
|
+
-- Administradores podem ver todas as mensagens
|
|
111
|
+
CREATE POLICY "admin_can_read_all_messages" ON public.messages
|
|
112
|
+
FOR SELECT
|
|
113
|
+
USING (
|
|
114
|
+
auth.uid() IN (
|
|
115
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
116
|
+
)
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
-- Usuários podem ver suas próprias mensagens
|
|
120
|
+
CREATE POLICY "users_can_read_own_messages" ON public.messages
|
|
121
|
+
FOR SELECT
|
|
122
|
+
USING (user_id = auth.uid() OR user_id IS NULL);
|
|
123
|
+
|
|
124
|
+
-- Usuários podem criar mensagens
|
|
125
|
+
CREATE POLICY "users_can_create_messages" ON public.messages
|
|
126
|
+
FOR INSERT
|
|
127
|
+
WITH CHECK (user_id = auth.uid() OR user_id IS NULL);
|
|
128
|
+
|
|
129
|
+
-- Administradores podem atualizar qualquer mensagem
|
|
130
|
+
CREATE POLICY "admin_can_update_all_messages" ON public.messages
|
|
131
|
+
FOR UPDATE
|
|
132
|
+
USING (
|
|
133
|
+
auth.uid() IN (
|
|
134
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
-- Usuários podem atualizar suas próprias mensagens
|
|
139
|
+
CREATE POLICY "users_can_update_own_messages" ON public.messages
|
|
140
|
+
FOR UPDATE
|
|
141
|
+
USING (user_id = auth.uid());
|
|
142
|
+
|
|
143
|
+
-- ============================================
|
|
144
|
+
-- POLÍTICAS: notification_categories
|
|
145
|
+
-- ============================================
|
|
146
|
+
|
|
147
|
+
-- Todos podem ler categorias de notificação
|
|
148
|
+
CREATE POLICY "all_can_read_notification_categories" ON public.notification_categories
|
|
149
|
+
FOR SELECT
|
|
150
|
+
USING (true);
|
|
151
|
+
|
|
152
|
+
-- Apenas administradores podem gerenciar categorias
|
|
153
|
+
CREATE POLICY "admin_can_manage_notification_categories" ON public.notification_categories
|
|
154
|
+
FOR ALL
|
|
155
|
+
USING (
|
|
156
|
+
auth.uid() IN (
|
|
157
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
158
|
+
)
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
-- ============================================
|
|
162
|
+
-- POLÍTICAS: notification_settings
|
|
163
|
+
-- ============================================
|
|
164
|
+
|
|
165
|
+
-- Usuários podem ver suas próprias configurações
|
|
166
|
+
CREATE POLICY "users_can_read_own_notification_settings" ON public.notification_settings
|
|
167
|
+
FOR SELECT
|
|
168
|
+
USING (user_id = auth.uid());
|
|
169
|
+
|
|
170
|
+
-- Administradores podem ver todas as configurações
|
|
171
|
+
CREATE POLICY "admin_can_read_all_notification_settings" ON public.notification_settings
|
|
172
|
+
FOR SELECT
|
|
173
|
+
USING (
|
|
174
|
+
auth.uid() IN (
|
|
175
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
-- Usuários podem criar suas próprias configurações
|
|
180
|
+
CREATE POLICY "users_can_create_notification_settings" ON public.notification_settings
|
|
181
|
+
FOR INSERT
|
|
182
|
+
WITH CHECK (user_id = auth.uid());
|
|
183
|
+
|
|
184
|
+
-- Usuários podem atualizar suas próprias configurações
|
|
185
|
+
CREATE POLICY "users_can_update_own_notification_settings" ON public.notification_settings
|
|
186
|
+
FOR UPDATE
|
|
187
|
+
USING (user_id = auth.uid());
|
|
188
|
+
|
|
189
|
+
-- Administradores podem gerenciar todas as configurações
|
|
190
|
+
CREATE POLICY "admin_can_manage_all_notification_settings" ON public.notification_settings
|
|
191
|
+
FOR ALL
|
|
192
|
+
USING (
|
|
193
|
+
auth.uid() IN (
|
|
194
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
-- ============================================
|
|
199
|
+
-- POLÍTICAS: notification_logs
|
|
200
|
+
-- ============================================
|
|
201
|
+
|
|
202
|
+
-- Usuários podem ver seus próprios logs
|
|
203
|
+
CREATE POLICY "users_can_read_own_notification_logs" ON public.notification_logs
|
|
204
|
+
FOR SELECT
|
|
205
|
+
USING (user_id = auth.uid());
|
|
206
|
+
|
|
207
|
+
-- Administradores podem ver todos os logs
|
|
208
|
+
CREATE POLICY "admin_can_read_all_notification_logs" ON public.notification_logs
|
|
209
|
+
FOR SELECT
|
|
210
|
+
USING (
|
|
211
|
+
auth.uid() IN (
|
|
212
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
213
|
+
)
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
-- Apenas administradores podem criar logs (via sistema)
|
|
217
|
+
CREATE POLICY "admin_can_create_notification_logs" ON public.notification_logs
|
|
218
|
+
FOR INSERT
|
|
219
|
+
WITH CHECK (
|
|
220
|
+
auth.uid() IN (
|
|
221
|
+
SELECT id FROM public.profiles WHERE role = 'administrator'
|
|
222
|
+
)
|
|
223
|
+
);
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
-- ============================================
|
|
2
|
+
-- 003_functions_triggers.sql: Funções e Triggers (gmoonc)
|
|
3
|
+
-- ============================================
|
|
4
|
+
-- Contém todas as funções PL/pgSQL e triggers
|
|
5
|
+
-- Otimizadas para gmoonc
|
|
6
|
+
|
|
7
|
+
-- ============================================
|
|
8
|
+
-- FUNÇÃO: update_updated_at_column
|
|
9
|
+
-- ============================================
|
|
10
|
+
-- Atualiza o campo updated_at automaticamente
|
|
11
|
+
CREATE OR REPLACE FUNCTION public.update_updated_at_column()
|
|
12
|
+
RETURNS TRIGGER AS $$
|
|
13
|
+
BEGIN
|
|
14
|
+
NEW.updated_at = NOW();
|
|
15
|
+
RETURN NEW;
|
|
16
|
+
END;
|
|
17
|
+
$$ LANGUAGE plpgsql;
|
|
18
|
+
|
|
19
|
+
-- ============================================
|
|
20
|
+
-- TRIGGERS: updated_at
|
|
21
|
+
-- ============================================
|
|
22
|
+
|
|
23
|
+
CREATE TRIGGER update_profiles_updated_at
|
|
24
|
+
BEFORE UPDATE ON public.profiles
|
|
25
|
+
FOR EACH ROW
|
|
26
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
27
|
+
|
|
28
|
+
CREATE TRIGGER update_roles_updated_at
|
|
29
|
+
BEFORE UPDATE ON public.roles
|
|
30
|
+
FOR EACH ROW
|
|
31
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
32
|
+
|
|
33
|
+
CREATE TRIGGER update_modules_updated_at
|
|
34
|
+
BEFORE UPDATE ON public.modules
|
|
35
|
+
FOR EACH ROW
|
|
36
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
37
|
+
|
|
38
|
+
CREATE TRIGGER update_permissions_updated_at
|
|
39
|
+
BEFORE UPDATE ON public.permissions
|
|
40
|
+
FOR EACH ROW
|
|
41
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
42
|
+
|
|
43
|
+
CREATE TRIGGER update_messages_updated_at
|
|
44
|
+
BEFORE UPDATE ON public.messages
|
|
45
|
+
FOR EACH ROW
|
|
46
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
47
|
+
|
|
48
|
+
CREATE TRIGGER update_notification_categories_updated_at
|
|
49
|
+
BEFORE UPDATE ON public.notification_categories
|
|
50
|
+
FOR EACH ROW
|
|
51
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
52
|
+
|
|
53
|
+
CREATE TRIGGER update_notification_settings_updated_at
|
|
54
|
+
BEFORE UPDATE ON public.notification_settings
|
|
55
|
+
FOR EACH ROW
|
|
56
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
57
|
+
|
|
58
|
+
-- ============================================
|
|
59
|
+
-- FUNÇÃO: get_user_permissions
|
|
60
|
+
-- ============================================
|
|
61
|
+
-- Retorna as permissões de um usuário
|
|
62
|
+
CREATE OR REPLACE FUNCTION public.get_user_permissions(user_id UUID)
|
|
63
|
+
RETURNS TABLE (
|
|
64
|
+
module_name TEXT,
|
|
65
|
+
can_access BOOLEAN,
|
|
66
|
+
can_create BOOLEAN,
|
|
67
|
+
can_read BOOLEAN,
|
|
68
|
+
can_update BOOLEAN,
|
|
69
|
+
can_delete BOOLEAN
|
|
70
|
+
) AS $$
|
|
71
|
+
BEGIN
|
|
72
|
+
RETURN QUERY
|
|
73
|
+
SELECT
|
|
74
|
+
m.name,
|
|
75
|
+
p.can_access,
|
|
76
|
+
p.can_create,
|
|
77
|
+
p.can_read,
|
|
78
|
+
p.can_update,
|
|
79
|
+
p.can_delete
|
|
80
|
+
FROM public.permissions p
|
|
81
|
+
JOIN public.modules m ON p.module_id = m.id
|
|
82
|
+
JOIN public.roles r ON p.role_id = r.id
|
|
83
|
+
WHERE r.id = (
|
|
84
|
+
SELECT role FROM public.profiles WHERE id = user_id
|
|
85
|
+
)::UUID;
|
|
86
|
+
END;
|
|
87
|
+
$$ LANGUAGE plpgsql;
|
|
88
|
+
|
|
89
|
+
-- ============================================
|
|
90
|
+
-- FUNÇÃO: check_user_permission
|
|
91
|
+
-- ============================================
|
|
92
|
+
-- Verifica se um usuário tem permissão para uma ação
|
|
93
|
+
CREATE OR REPLACE FUNCTION public.check_user_permission(
|
|
94
|
+
user_id UUID,
|
|
95
|
+
module_name TEXT,
|
|
96
|
+
action TEXT
|
|
97
|
+
) RETURNS BOOLEAN AS $$
|
|
98
|
+
DECLARE
|
|
99
|
+
user_role TEXT;
|
|
100
|
+
has_permission BOOLEAN;
|
|
101
|
+
BEGIN
|
|
102
|
+
-- Obter role do usuário
|
|
103
|
+
SELECT role INTO user_role FROM public.profiles WHERE id = user_id;
|
|
104
|
+
|
|
105
|
+
IF user_role IS NULL THEN
|
|
106
|
+
RETURN false;
|
|
107
|
+
END IF;
|
|
108
|
+
|
|
109
|
+
-- Verificar permissão baseado na ação
|
|
110
|
+
CASE action
|
|
111
|
+
WHEN 'create' THEN
|
|
112
|
+
SELECT can_create INTO has_permission
|
|
113
|
+
FROM public.permissions p
|
|
114
|
+
JOIN public.roles r ON p.role_id = r.id
|
|
115
|
+
JOIN public.modules m ON p.module_id = m.id
|
|
116
|
+
WHERE r.name = user_role AND m.name = module_name;
|
|
117
|
+
WHEN 'read' THEN
|
|
118
|
+
SELECT can_read INTO has_permission
|
|
119
|
+
FROM public.permissions p
|
|
120
|
+
JOIN public.roles r ON p.role_id = r.id
|
|
121
|
+
JOIN public.modules m ON p.module_id = m.id
|
|
122
|
+
WHERE r.name = user_role AND m.name = module_name;
|
|
123
|
+
WHEN 'update' THEN
|
|
124
|
+
SELECT can_update INTO has_permission
|
|
125
|
+
FROM public.permissions p
|
|
126
|
+
JOIN public.roles r ON p.role_id = r.id
|
|
127
|
+
JOIN public.modules m ON p.module_id = m.id
|
|
128
|
+
WHERE r.name = user_role AND m.name = module_name;
|
|
129
|
+
WHEN 'delete' THEN
|
|
130
|
+
SELECT can_delete INTO has_permission
|
|
131
|
+
FROM public.permissions p
|
|
132
|
+
JOIN public.roles r ON p.role_id = r.id
|
|
133
|
+
JOIN public.modules m ON p.module_id = m.id
|
|
134
|
+
WHERE r.name = user_role AND m.name = module_name;
|
|
135
|
+
ELSE
|
|
136
|
+
RETURN false;
|
|
137
|
+
END CASE;
|
|
138
|
+
|
|
139
|
+
RETURN COALESCE(has_permission, false);
|
|
140
|
+
END;
|
|
141
|
+
$$ LANGUAGE plpgsql;
|
|
142
|
+
|
|
143
|
+
-- ============================================
|
|
144
|
+
-- FUNÇÃO: log_notification
|
|
145
|
+
-- ============================================
|
|
146
|
+
-- Registra uma notificação no histórico
|
|
147
|
+
CREATE OR REPLACE FUNCTION public.log_notification(
|
|
148
|
+
p_category_id UUID,
|
|
149
|
+
p_user_id UUID,
|
|
150
|
+
p_entity_type TEXT,
|
|
151
|
+
p_entity_id TEXT,
|
|
152
|
+
p_email_sent BOOLEAN DEFAULT false,
|
|
153
|
+
p_email_error TEXT DEFAULT NULL
|
|
154
|
+
) RETURNS UUID AS $$
|
|
155
|
+
DECLARE
|
|
156
|
+
log_id UUID;
|
|
157
|
+
BEGIN
|
|
158
|
+
INSERT INTO public.notification_logs (
|
|
159
|
+
category_id,
|
|
160
|
+
user_id,
|
|
161
|
+
entity_type,
|
|
162
|
+
entity_id,
|
|
163
|
+
email_sent,
|
|
164
|
+
email_error,
|
|
165
|
+
sent_at,
|
|
166
|
+
created_at
|
|
167
|
+
) VALUES (
|
|
168
|
+
p_category_id,
|
|
169
|
+
p_user_id,
|
|
170
|
+
p_entity_type,
|
|
171
|
+
p_entity_id,
|
|
172
|
+
p_email_sent,
|
|
173
|
+
p_email_error,
|
|
174
|
+
CASE WHEN p_email_sent THEN NOW() ELSE NULL END,
|
|
175
|
+
NOW()
|
|
176
|
+
) RETURNING id INTO log_id;
|
|
177
|
+
|
|
178
|
+
RETURN log_id;
|
|
179
|
+
END;
|
|
180
|
+
$$ LANGUAGE plpgsql;
|
|
181
|
+
|
|
182
|
+
-- ============================================
|
|
183
|
+
-- FUNÇÃO: is_user_admin
|
|
184
|
+
-- ============================================
|
|
185
|
+
-- Verifica se um usuário é administrador
|
|
186
|
+
CREATE OR REPLACE FUNCTION public.is_user_admin(user_id UUID)
|
|
187
|
+
RETURNS BOOLEAN AS $$
|
|
188
|
+
BEGIN
|
|
189
|
+
RETURN EXISTS (
|
|
190
|
+
SELECT 1 FROM public.profiles
|
|
191
|
+
WHERE id = user_id AND role = 'administrator'
|
|
192
|
+
);
|
|
193
|
+
END;
|
|
194
|
+
$$ LANGUAGE plpgsql;
|
|
195
|
+
|
|
196
|
+
-- ============================================
|
|
197
|
+
-- FUNÇÃO: is_user_employee
|
|
198
|
+
-- ============================================
|
|
199
|
+
-- Verifica se um usuário é funcionário
|
|
200
|
+
CREATE OR REPLACE FUNCTION public.is_user_employee(user_id UUID)
|
|
201
|
+
RETURNS BOOLEAN AS $$
|
|
202
|
+
BEGIN
|
|
203
|
+
RETURN EXISTS (
|
|
204
|
+
SELECT 1 FROM public.profiles
|
|
205
|
+
WHERE id = user_id AND role = 'employee'
|
|
206
|
+
);
|
|
207
|
+
END;
|
|
208
|
+
$$ LANGUAGE plpgsql;
|
|
209
|
+
|
|
210
|
+
-- ============================================
|
|
211
|
+
-- FUNÇÃO: is_user_customer
|
|
212
|
+
-- ============================================
|
|
213
|
+
-- Verifica se um usuário é cliente
|
|
214
|
+
CREATE OR REPLACE FUNCTION public.is_user_customer(user_id UUID)
|
|
215
|
+
RETURNS BOOLEAN AS $$
|
|
216
|
+
BEGIN
|
|
217
|
+
RETURN EXISTS (
|
|
218
|
+
SELECT 1 FROM public.profiles
|
|
219
|
+
WHERE id = user_id AND role = 'customer'
|
|
220
|
+
);
|
|
221
|
+
END;
|
|
222
|
+
$$ LANGUAGE plpgsql;
|
|
223
|
+
|
|
224
|
+
-- ============================================
|
|
225
|
+
-- FUNÇÃO: get_notification_settings_for_user
|
|
226
|
+
-- ============================================
|
|
227
|
+
-- Retorna as configurações de notificação de um usuário
|
|
228
|
+
CREATE OR REPLACE FUNCTION public.get_notification_settings_for_user(user_id UUID)
|
|
229
|
+
RETURNS TABLE (
|
|
230
|
+
category_id UUID,
|
|
231
|
+
category_name TEXT,
|
|
232
|
+
is_enabled BOOLEAN
|
|
233
|
+
) AS $$
|
|
234
|
+
BEGIN
|
|
235
|
+
RETURN QUERY
|
|
236
|
+
SELECT
|
|
237
|
+
ns.category_id,
|
|
238
|
+
nc.name,
|
|
239
|
+
ns.is_enabled
|
|
240
|
+
FROM public.notification_settings ns
|
|
241
|
+
JOIN public.notification_categories nc ON ns.category_id = nc.id
|
|
242
|
+
WHERE ns.user_id = user_id;
|
|
243
|
+
END;
|
|
244
|
+
$$ LANGUAGE plpgsql;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
-- ============================================
|
|
2
|
+
-- 004_seed.sql: Dados Iniciais (gmoonc - Fake Data)
|
|
3
|
+
-- ============================================
|
|
4
|
+
-- Dados fictícios 100% fake para desenvolvimento
|
|
5
|
+
-- Todos em inglês conforme gmoonc
|
|
6
|
+
-- Inspirado em Missão Apollo
|
|
7
|
+
|
|
8
|
+
-- ============================================
|
|
9
|
+
-- 1. ROLES (System Roles)
|
|
10
|
+
-- ============================================
|
|
11
|
+
|
|
12
|
+
INSERT INTO public.roles (id, name, description, is_system_role, created_at, updated_at) VALUES
|
|
13
|
+
('550e8400-e29b-41d4-a716-446655440001'::uuid, 'administrator', 'System Administrator', true, NOW(), NOW()),
|
|
14
|
+
('550e8400-e29b-41d4-a716-446655440002'::uuid, 'employee', 'Employee/Collaborator', true, NOW(), NOW()),
|
|
15
|
+
('550e8400-e29b-41d4-a716-446655440003'::uuid, 'customer', 'Customer/End User', true, NOW(), NOW());
|
|
16
|
+
|
|
17
|
+
-- ============================================
|
|
18
|
+
-- 2. MODULES (Application Modules)
|
|
19
|
+
-- ============================================
|
|
20
|
+
|
|
21
|
+
INSERT INTO public.modules (id, name, display_name, description, is_active, created_at, updated_at) VALUES
|
|
22
|
+
('550e8400-e29b-41d4-a716-446655440010'::uuid, 'admin', 'Administrative Module', 'Administrative functions and system management', true, NOW(), NOW()),
|
|
23
|
+
('550e8400-e29b-41d4-a716-446655440011'::uuid, 'financial', 'Financial Module', 'Financial management and reporting', true, NOW(), NOW()),
|
|
24
|
+
('550e8400-e29b-41d4-a716-446655440012'::uuid, 'technical', 'Technical Support Module', 'Technical support and help desk', true, NOW(), NOW()),
|
|
25
|
+
('550e8400-e29b-41d4-a716-446655440013'::uuid, 'customer', 'Customer Module', 'Customer portal and self-service', true, NOW(), NOW());
|
|
26
|
+
|
|
27
|
+
-- ============================================
|
|
28
|
+
-- 3. PERMISSIONS (Role-Based Access Control)
|
|
29
|
+
-- ============================================
|
|
30
|
+
|
|
31
|
+
INSERT INTO public.permissions (id, role_id, module_id, can_access, can_create, can_read, can_update, can_delete, created_at, updated_at) VALUES
|
|
32
|
+
-- Administrator: Full access to all modules
|
|
33
|
+
('550e8400-e29b-41d4-a716-446655440100'::uuid, '550e8400-e29b-41d4-a716-446655440001'::uuid, '550e8400-e29b-41d4-a716-446655440010'::uuid, true, true, true, true, true, NOW(), NOW()),
|
|
34
|
+
('550e8400-e29b-41d4-a716-446655440101'::uuid, '550e8400-e29b-41d4-a716-446655440001'::uuid, '550e8400-e29b-41d4-a716-446655440011'::uuid, true, true, true, true, true, NOW(), NOW()),
|
|
35
|
+
('550e8400-e29b-41d4-a716-446655440102'::uuid, '550e8400-e29b-41d4-a716-446655440001'::uuid, '550e8400-e29b-41d4-a716-446655440012'::uuid, true, true, true, true, true, NOW(), NOW()),
|
|
36
|
+
('550e8400-e29b-41d4-a716-446655440103'::uuid, '550e8400-e29b-41d4-a716-446655440001'::uuid, '550e8400-e29b-41d4-a716-446655440013'::uuid, true, true, true, true, true, NOW(), NOW()),
|
|
37
|
+
|
|
38
|
+
-- Employee: Read and update access (no delete)
|
|
39
|
+
('550e8400-e29b-41d4-a716-446655440110'::uuid, '550e8400-e29b-41d4-a716-446655440002'::uuid, '550e8400-e29b-41d4-a716-446655440010'::uuid, true, false, true, true, false, NOW(), NOW()),
|
|
40
|
+
('550e8400-e29b-41d4-a716-446655440111'::uuid, '550e8400-e29b-41d4-a716-446655440002'::uuid, '550e8400-e29b-41d4-a716-446655440011'::uuid, true, false, true, true, false, NOW(), NOW()),
|
|
41
|
+
('550e8400-e29b-41d4-a716-446655440112'::uuid, '550e8400-e29b-41d4-a716-446655440002'::uuid, '550e8400-e29b-41d4-a716-446655440012'::uuid, true, true, true, true, false, NOW(), NOW()),
|
|
42
|
+
('550e8400-e29b-41d4-a716-446655440113'::uuid, '550e8400-e29b-41d4-a716-446655440002'::uuid, '550e8400-e29b-41d4-a716-446655440013'::uuid, true, false, true, false, false, NOW(), NOW()),
|
|
43
|
+
|
|
44
|
+
-- Customer: Read-only access (create messages)
|
|
45
|
+
('550e8400-e29b-41d4-a716-446655440120'::uuid, '550e8400-e29b-41d4-a716-446655440003'::uuid, '550e8400-e29b-41d4-a716-446655440010'::uuid, false, false, false, false, false, NOW(), NOW()),
|
|
46
|
+
('550e8400-e29b-41d4-a716-446655440121'::uuid, '550e8400-e29b-41d4-a716-446655440003'::uuid, '550e8400-e29b-41d4-a716-446655440011'::uuid, false, false, false, false, false, NOW(), NOW()),
|
|
47
|
+
('550e8400-e29b-41d4-a716-446655440122'::uuid, '550e8400-e29b-41d4-a716-446655440003'::uuid, '550e8400-e29b-41d4-a716-446655440012'::uuid, true, true, true, false, false, NOW(), NOW()),
|
|
48
|
+
('550e8400-e29b-41d4-a716-446655440123'::uuid, '550e8400-e29b-41d4-a716-446655440003'::uuid, '550e8400-e29b-41d4-a716-446655440013'::uuid, true, false, true, false, false, NOW(), NOW());
|
|
49
|
+
|
|
50
|
+
-- ============================================
|
|
51
|
+
-- 4. PROFILES (Users - Apollo Astronauts)
|
|
52
|
+
-- ============================================
|
|
53
|
+
|
|
54
|
+
INSERT INTO public.profiles (id, email, name, role, created_at, updated_at) VALUES
|
|
55
|
+
-- Administrators
|
|
56
|
+
('550e8400-e29b-41d4-a716-446655440200'::uuid, 'neil.armstrong@apollo.nasa.gov', 'Neil Armstrong', 'administrator', NOW(), NOW()),
|
|
57
|
+
('550e8400-e29b-41d4-a716-446655440201'::uuid, 'buzz.aldrin@apollo.nasa.gov', 'Buzz Aldrin', 'administrator', NOW(), NOW()),
|
|
58
|
+
|
|
59
|
+
-- Employees
|
|
60
|
+
('550e8400-e29b-41d4-a716-446655440210'::uuid, 'michael.collins@apollo.nasa.gov', 'Michael Collins', 'employee', NOW(), NOW()),
|
|
61
|
+
('550e8400-e29b-41d4-a716-446655440211'::uuid, 'alan.bean@apollo.nasa.gov', 'Alan Bean', 'employee', NOW(), NOW()),
|
|
62
|
+
('550e8400-e29b-41d4-a716-446655440212'::uuid, 'pete.conrad@apollo.nasa.gov', 'Pete Conrad', 'employee', NOW(), NOW()),
|
|
63
|
+
|
|
64
|
+
-- Customers
|
|
65
|
+
('550e8400-e29b-41d4-a716-446655440220'::uuid, 'john.glenn@apollo.nasa.gov', 'John Glenn', 'customer', NOW(), NOW()),
|
|
66
|
+
('550e8400-e29b-41d4-a716-446655440221'::uuid, 'alan.shepard@apollo.nasa.gov', 'Alan Shepard', 'customer', NOW(), NOW()),
|
|
67
|
+
('550e8400-e29b-41d4-a716-446655440222'::uuid, 'gus.grissom@apollo.nasa.gov', 'Gus Grissom', 'customer', NOW(), NOW());
|
|
68
|
+
|
|
69
|
+
-- ============================================
|
|
70
|
+
-- 5. NOTIFICATION CATEGORIES
|
|
71
|
+
-- ============================================
|
|
72
|
+
|
|
73
|
+
INSERT INTO public.notification_categories (id, name, display_name, description, is_active, email_template_subject, email_template_body, created_at, updated_at) VALUES
|
|
74
|
+
('550e8400-e29b-41d4-a716-446655440300'::uuid, 'message_received', 'Message Received', 'Notification when a new message is received', true, 'New message from {{sender}}', 'You have received a new message from {{sender}}: {{message}}', NOW(), NOW()),
|
|
75
|
+
('550e8400-e29b-41d4-a716-446655440301'::uuid, 'message_updated', 'Message Updated', 'Notification when a message status is updated', true, 'Message status updated', 'Your message status has been updated to: {{status}}', NOW(), NOW()),
|
|
76
|
+
('550e8400-e29b-41d4-a716-446655440302'::uuid, 'system_alert', 'System Alert', 'General system alerts and notifications', true, 'System Alert', 'System Alert: {{message}}', NOW(), NOW()),
|
|
77
|
+
('550e8400-e29b-41d4-a716-446655440303'::uuid, 'support_ticket', 'Support Ticket', 'Support ticket related notifications', true, 'Support Ticket {{ticket_id}}', 'Your support ticket {{ticket_id}} has been updated', NOW(), NOW());
|
|
78
|
+
|
|
79
|
+
-- ============================================
|
|
80
|
+
-- 6. NOTIFICATION SETTINGS (User Preferences)
|
|
81
|
+
-- ============================================
|
|
82
|
+
|
|
83
|
+
INSERT INTO public.notification_settings (id, user_id, category_id, is_enabled, created_at, updated_at) VALUES
|
|
84
|
+
-- Neil Armstrong (Admin) - receives all notifications
|
|
85
|
+
('550e8400-e29b-41d4-a716-446655440400'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, '550e8400-e29b-41d4-a716-446655440300'::uuid, true, NOW(), NOW()),
|
|
86
|
+
('550e8400-e29b-41d4-a716-446655440401'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, '550e8400-e29b-41d4-a716-446655440301'::uuid, true, NOW(), NOW()),
|
|
87
|
+
('550e8400-e29b-41d4-a716-446655440402'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, '550e8400-e29b-41d4-a716-446655440302'::uuid, true, NOW(), NOW()),
|
|
88
|
+
('550e8400-e29b-41d4-a716-446655440403'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, '550e8400-e29b-41d4-a716-446655440303'::uuid, true, NOW(), NOW()),
|
|
89
|
+
|
|
90
|
+
-- Michael Collins (Employee) - selective notifications
|
|
91
|
+
('550e8400-e29b-41d4-a716-446655440410'::uuid, '550e8400-e29b-41d4-a716-446655440210'::uuid, '550e8400-e29b-41d4-a716-446655440300'::uuid, true, NOW(), NOW()),
|
|
92
|
+
('550e8400-e29b-41d4-a716-446655440411'::uuid, '550e8400-e29b-41d4-a716-446655440210'::uuid, '550e8400-e29b-41d4-a716-446655440301'::uuid, true, NOW(), NOW()),
|
|
93
|
+
('550e8400-e29b-41d4-a716-446655440412'::uuid, '550e8400-e29b-41d4-a716-446655440210'::uuid, '550e8400-e29b-41d4-a716-446655440302'::uuid, false, NOW(), NOW()),
|
|
94
|
+
('550e8400-e29b-41d4-a716-446655440413'::uuid, '550e8400-e29b-41d4-a716-446655440210'::uuid, '550e8400-e29b-41d4-a716-446655440303'::uuid, true, NOW(), NOW()),
|
|
95
|
+
|
|
96
|
+
-- John Glenn (Customer) - limited notifications
|
|
97
|
+
('550e8400-e29b-41d4-a716-446655440420'::uuid, '550e8400-e29b-41d4-a716-446655440220'::uuid, '550e8400-e29b-41d4-a716-446655440300'::uuid, true, NOW(), NOW()),
|
|
98
|
+
('550e8400-e29b-41d4-a716-446655440421'::uuid, '550e8400-e29b-41d4-a716-446655440220'::uuid, '550e8400-e29b-41d4-a716-446655440301'::uuid, true, NOW(), NOW()),
|
|
99
|
+
('550e8400-e29b-41d4-a716-446655440422'::uuid, '550e8400-e29b-41d4-a716-446655440220'::uuid, '550e8400-e29b-41d4-a716-446655440302'::uuid, false, NOW(), NOW()),
|
|
100
|
+
('550e8400-e29b-41d4-a716-446655440423'::uuid, '550e8400-e29b-41d4-a716-446655440220'::uuid, '550e8400-e29b-41d4-a716-446655440303'::uuid, true, NOW(), NOW());
|
|
101
|
+
|
|
102
|
+
-- ============================================
|
|
103
|
+
-- 7. MESSAGES (System Messages)
|
|
104
|
+
-- ============================================
|
|
105
|
+
|
|
106
|
+
INSERT INTO public.messages (id, user_id, name, email, phone, company_farm, message, status, created_at, updated_at) VALUES
|
|
107
|
+
-- From Neil Armstrong
|
|
108
|
+
('550e8400-e29b-41d4-a716-446655440600'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, 'Neil Armstrong', 'neil.armstrong@apollo.nasa.gov', '+55 11 98765-4321', 'NASA - Apollo Mission', 'Requesting analysis of lunar region coverage', 'completed', NOW(), NOW()),
|
|
109
|
+
|
|
110
|
+
-- From John Glenn
|
|
111
|
+
('550e8400-e29b-41d4-a716-446655440601'::uuid, '550e8400-e29b-41d4-a716-446655440220'::uuid, 'John Glenn', 'john.glenn@apollo.nasa.gov', '+55 21 99999-8888', 'NASA - Mercury Program', 'Question about coverage analysis', 'in_analysis', NOW(), NOW()),
|
|
112
|
+
|
|
113
|
+
-- From Alan Shepard
|
|
114
|
+
('550e8400-e29b-41d4-a716-446655440602'::uuid, '550e8400-e29b-41d4-a716-446655440221'::uuid, 'Alan Shepard', 'alan.shepard@apollo.nasa.gov', '+55 85 97777-6666', 'NASA - Gemini Program', 'Feedback on previous analysis', 'pending', NOW(), NOW()),
|
|
115
|
+
|
|
116
|
+
-- Draft message
|
|
117
|
+
('550e8400-e29b-41d4-a716-446655440603'::uuid, '550e8400-e29b-41d4-a716-446655440222'::uuid, 'Gus Grissom', 'gus.grissom@apollo.nasa.gov', '+55 31 98888-7777', 'NASA - Apollo Applications', 'Support request for system access', 'draft', NOW(), NOW());
|
|
118
|
+
|
|
119
|
+
-- ============================================
|
|
120
|
+
-- 8. NOTIFICATION LOGS (Notification History)
|
|
121
|
+
-- ============================================
|
|
122
|
+
|
|
123
|
+
INSERT INTO public.notification_logs (id, category_id, user_id, entity_type, entity_id, email_sent, email_error, sent_at, created_at) VALUES
|
|
124
|
+
('550e8400-e29b-41d4-a716-446655440700'::uuid, '550e8400-e29b-41d4-a716-446655440300'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, 'messages', '550e8400-e29b-41d4-a716-446655440600'::uuid, true, null, NOW(), NOW()),
|
|
125
|
+
('550e8400-e29b-41d4-a716-446655440701'::uuid, '550e8400-e29b-41d4-a716-446655440301'::uuid, '550e8400-e29b-41d4-a716-446655440200'::uuid, 'messages', '550e8400-e29b-41d4-a716-446655440600'::uuid, true, null, NOW(), NOW()),
|
|
126
|
+
('550e8400-e29b-41d4-a716-446655440702'::uuid, '550e8400-e29b-41d4-a716-446655440300'::uuid, '550e8400-e29b-41d4-a716-446655440220'::uuid, 'messages', '550e8400-e29b-41d4-a716-446655440601'::uuid, false, 'User disabled email notifications', null, NOW());
|
package/dist/index.cjs
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// src/cli/index.ts
|
|
5
5
|
var import_commander = require("commander");
|
|
6
6
|
var import_process = require("process");
|
|
7
|
-
var
|
|
8
|
-
var
|
|
7
|
+
var import_path8 = require("path");
|
|
8
|
+
var import_fs13 = require("fs");
|
|
9
9
|
|
|
10
10
|
// src/cli/lib/detect.ts
|
|
11
11
|
var import_fs = require("fs");
|
|
@@ -1626,9 +1626,13 @@ export type { UserPermission } from './getUserPermissions';
|
|
|
1626
1626
|
}
|
|
1627
1627
|
function updateEnvExample(projectDir) {
|
|
1628
1628
|
const envExamplePath = (0, import_path6.join)(projectDir, ".env.example");
|
|
1629
|
-
const envExampleContent = `# Supabase Configuration
|
|
1629
|
+
const envExampleContent = `# Supabase Configuration (Client-side)
|
|
1630
1630
|
VITE_SUPABASE_URL=
|
|
1631
1631
|
VITE_SUPABASE_ANON_KEY=
|
|
1632
|
+
|
|
1633
|
+
# Supabase Database Connection (Server-only, for seeding)
|
|
1634
|
+
# Get this from Supabase Dashboard \u2192 Settings \u2192 Database \u2192 Connection string (URI)
|
|
1635
|
+
SUPABASE_DB_URL=
|
|
1632
1636
|
`;
|
|
1633
1637
|
if ((0, import_fs9.existsSync)(envExamplePath)) {
|
|
1634
1638
|
const existing = (0, import_fs9.readFileSync)(envExamplePath, "utf-8");
|
|
@@ -1808,9 +1812,173 @@ function updateAllSessionImports(gmooncDir) {
|
|
|
1808
1812
|
}
|
|
1809
1813
|
}
|
|
1810
1814
|
|
|
1815
|
+
// src/cli/lib/supabaseSeedVite.ts
|
|
1816
|
+
var import_path7 = require("path");
|
|
1817
|
+
var import_fs11 = require("fs");
|
|
1818
|
+
var import_pg = require("pg");
|
|
1819
|
+
var import_dotenv = require("dotenv");
|
|
1820
|
+
function getPackageRoot() {
|
|
1821
|
+
try {
|
|
1822
|
+
const currentDir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
1823
|
+
return (0, import_path7.join)(currentDir, "../../..");
|
|
1824
|
+
} catch {
|
|
1825
|
+
return (0, import_path7.join)(process.cwd(), "node_modules", "gmoonc");
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
var PACKAGE_ROOT = getPackageRoot();
|
|
1829
|
+
async function seedSupabase(options) {
|
|
1830
|
+
const { projectDir, dryRun } = options;
|
|
1831
|
+
try {
|
|
1832
|
+
(0, import_dotenv.config)({ path: (0, import_path7.join)(projectDir, ".env") });
|
|
1833
|
+
(0, import_dotenv.config)({ path: (0, import_path7.join)(projectDir, ".env.local") });
|
|
1834
|
+
const gmooncDir = (0, import_path7.join)(projectDir, "src/gmoonc");
|
|
1835
|
+
if (!(0, import_fs11.existsSync)(gmooncDir)) {
|
|
1836
|
+
logError('gmoonc is not installed. Run "npx gmoonc" first.');
|
|
1837
|
+
return { success: false, message: "gmoonc not installed" };
|
|
1838
|
+
}
|
|
1839
|
+
const supabaseDir = (0, import_path7.join)(gmooncDir, "supabase");
|
|
1840
|
+
if (!(0, import_fs11.existsSync)(supabaseDir)) {
|
|
1841
|
+
logError('Supabase integration not found. Run "npx gmoonc supabase --vite" first.');
|
|
1842
|
+
return { success: false, message: "Supabase not set up" };
|
|
1843
|
+
}
|
|
1844
|
+
const markerPath = (0, import_path7.join)(projectDir, ".gmoonc", "supabase-seed.json");
|
|
1845
|
+
if ((0, import_fs11.existsSync)(markerPath)) {
|
|
1846
|
+
logError("supabase-seed already executed in this project.");
|
|
1847
|
+
logError("To re-seed, delete the marker file: .gmoonc/supabase-seed.json");
|
|
1848
|
+
logError("Then manually clean the database in Supabase before re-running.");
|
|
1849
|
+
return { success: false, message: "Already seeded" };
|
|
1850
|
+
}
|
|
1851
|
+
const dbUrl = process.env.SUPABASE_DB_URL;
|
|
1852
|
+
if (!dbUrl) {
|
|
1853
|
+
logError("SUPABASE_DB_URL is not set in .env or .env.local");
|
|
1854
|
+
logError("");
|
|
1855
|
+
logError("To get the connection string:");
|
|
1856
|
+
logError("1. Go to your Supabase project dashboard");
|
|
1857
|
+
logError("2. Navigate to Settings \u2192 Database");
|
|
1858
|
+
logError('3. Copy the "Connection string (URI)"');
|
|
1859
|
+
logError("4. Add it to .env.local as:");
|
|
1860
|
+
logError(" SUPABASE_DB_URL=postgresql://postgres:[YOUR-PASSWORD]@[HOST]:5432/postgres");
|
|
1861
|
+
logError("");
|
|
1862
|
+
logError("\u26A0\uFE0F This is a server-only variable (no VITE_ prefix)");
|
|
1863
|
+
return { success: false, message: "SUPABASE_DB_URL not set" };
|
|
1864
|
+
}
|
|
1865
|
+
if (dryRun) {
|
|
1866
|
+
logInfo("\u{1F50D} Dry run mode - would execute SQL files");
|
|
1867
|
+
return { success: true };
|
|
1868
|
+
}
|
|
1869
|
+
const sqlFiles = [
|
|
1870
|
+
{ name: "001_tables.sql", order: 1 },
|
|
1871
|
+
{ name: "003_functions_triggers.sql", order: 2 },
|
|
1872
|
+
{ name: "002_rls.sql", order: 3 },
|
|
1873
|
+
{ name: "004_seed.sql", order: 4 }
|
|
1874
|
+
];
|
|
1875
|
+
const projectSqlDir = (0, import_path7.join)(gmooncDir, "supabase", "sql");
|
|
1876
|
+
const packageSqlDir = (0, import_path7.join)(PACKAGE_ROOT, "assets", "supabase");
|
|
1877
|
+
if (!(0, import_fs11.existsSync)(projectSqlDir)) {
|
|
1878
|
+
ensureDirectoryExists((0, import_path7.join)(projectSqlDir, "dummy"));
|
|
1879
|
+
logInfo("\u{1F4CB} Copying SQL files to project...");
|
|
1880
|
+
for (const sqlFile of sqlFiles) {
|
|
1881
|
+
const packagePath = (0, import_path7.join)(packageSqlDir, sqlFile.name);
|
|
1882
|
+
const projectPath = (0, import_path7.join)(projectSqlDir, sqlFile.name);
|
|
1883
|
+
if ((0, import_fs11.existsSync)(packagePath)) {
|
|
1884
|
+
const content = (0, import_fs11.readFileSync)(packagePath, "utf-8");
|
|
1885
|
+
(0, import_fs11.writeFileSync)(projectPath, content, "utf-8");
|
|
1886
|
+
logSuccess(`Copied ${sqlFile.name} to src/gmoonc/supabase/sql/`);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
logInfo("\n\u{1F50C} Connecting to Supabase database...");
|
|
1891
|
+
const client = new import_pg.Client({
|
|
1892
|
+
connectionString: dbUrl,
|
|
1893
|
+
ssl: { rejectUnauthorized: false }
|
|
1894
|
+
});
|
|
1895
|
+
await client.connect();
|
|
1896
|
+
logSuccess("Connected to database");
|
|
1897
|
+
const executedFiles = [];
|
|
1898
|
+
for (const sqlFile of sqlFiles) {
|
|
1899
|
+
logInfo(`
|
|
1900
|
+
\u{1F4DD} Applying ${sqlFile.name}...`);
|
|
1901
|
+
let sqlPath = (0, import_path7.join)(projectSqlDir, sqlFile.name);
|
|
1902
|
+
if (!(0, import_fs11.existsSync)(sqlPath)) {
|
|
1903
|
+
sqlPath = (0, import_path7.join)(packageSqlDir, sqlFile.name);
|
|
1904
|
+
}
|
|
1905
|
+
if (!(0, import_fs11.existsSync)(sqlPath)) {
|
|
1906
|
+
logError(`SQL file not found: ${sqlFile.name}`);
|
|
1907
|
+
await client.end();
|
|
1908
|
+
return { success: false, message: `SQL file not found: ${sqlFile.name}` };
|
|
1909
|
+
}
|
|
1910
|
+
const sql = (0, import_fs11.readFileSync)(sqlPath, "utf-8");
|
|
1911
|
+
try {
|
|
1912
|
+
await client.query("BEGIN");
|
|
1913
|
+
await client.query(sql);
|
|
1914
|
+
await client.query("COMMIT");
|
|
1915
|
+
executedFiles.push(sqlFile.name);
|
|
1916
|
+
logSuccess(`\u2713 Applied ${sqlFile.name}`);
|
|
1917
|
+
} catch (error) {
|
|
1918
|
+
await client.query("ROLLBACK");
|
|
1919
|
+
const errorMessage = error.message || "Unknown error";
|
|
1920
|
+
const errorPosition = error.position ? ` at position ${error.position}` : "";
|
|
1921
|
+
logError(`\u2717 Failed to apply ${sqlFile.name}${errorPosition}`);
|
|
1922
|
+
logError(`Error: ${errorMessage}`);
|
|
1923
|
+
if (error.position && sql) {
|
|
1924
|
+
const lines = sql.split("\n");
|
|
1925
|
+
const charPos = error.position;
|
|
1926
|
+
let currentPos = 0;
|
|
1927
|
+
let errorLine = 0;
|
|
1928
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1929
|
+
currentPos += lines[i].length + 1;
|
|
1930
|
+
if (currentPos >= charPos) {
|
|
1931
|
+
errorLine = i + 1;
|
|
1932
|
+
break;
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
if (errorLine > 0) {
|
|
1936
|
+
const start = Math.max(0, errorLine - 3);
|
|
1937
|
+
const end = Math.min(lines.length, errorLine + 2);
|
|
1938
|
+
logError("\nSQL context around error:");
|
|
1939
|
+
for (let i = start; i < end; i++) {
|
|
1940
|
+
const marker = i === errorLine - 1 ? ">>> " : " ";
|
|
1941
|
+
logError(`${marker}${i + 1}: ${lines[i]}`);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
await client.end();
|
|
1946
|
+
return { success: false, message: `SQL execution failed: ${sqlFile.name}` };
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
await client.end();
|
|
1950
|
+
logSuccess("\n\u2705 All SQL files applied successfully");
|
|
1951
|
+
const markerDir = (0, import_path7.join)(projectDir, ".gmoonc");
|
|
1952
|
+
ensureDirectoryExists((0, import_path7.join)(markerDir, "dummy"));
|
|
1953
|
+
const packageJsonPath = (0, import_path7.join)(PACKAGE_ROOT, "package.json");
|
|
1954
|
+
let version = "0.0.22";
|
|
1955
|
+
try {
|
|
1956
|
+
if ((0, import_fs11.existsSync)(packageJsonPath)) {
|
|
1957
|
+
const packageJson = JSON.parse((0, import_fs11.readFileSync)(packageJsonPath, "utf-8"));
|
|
1958
|
+
version = packageJson.version || version;
|
|
1959
|
+
}
|
|
1960
|
+
} catch {
|
|
1961
|
+
}
|
|
1962
|
+
const markerContent = JSON.stringify({
|
|
1963
|
+
version,
|
|
1964
|
+
executedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1965
|
+
files: executedFiles
|
|
1966
|
+
}, null, 2);
|
|
1967
|
+
(0, import_fs11.writeFileSync)(markerPath, markerContent, "utf-8");
|
|
1968
|
+
logSuccess("Created marker file: .gmoonc/supabase-seed.json");
|
|
1969
|
+
return { success: true };
|
|
1970
|
+
} catch (error) {
|
|
1971
|
+
logError(`Error: ${error.message}`);
|
|
1972
|
+
if (error.stack && process.env.DEBUG) {
|
|
1973
|
+
console.error(error.stack);
|
|
1974
|
+
}
|
|
1975
|
+
return { success: false, message: error.message };
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1811
1979
|
// src/cli/index.ts
|
|
1812
1980
|
var program = new import_commander.Command();
|
|
1813
|
-
program.name("gmoonc").description("Goalmoon Ctrl (gmoonc): Install complete dashboard into your React project").version("0.0.
|
|
1981
|
+
program.name("gmoonc").description("Goalmoon Ctrl (gmoonc): Install complete dashboard into your React project").version("0.0.22").option("--base <path>", "Base path for dashboard routes", "/app").option("--skip-router-patch", "Skip automatic router integration (only copy files and inject CSS)").option("--dry-run", "Show what would be done without making changes").action(async (options) => {
|
|
1814
1982
|
try {
|
|
1815
1983
|
logInfo("\u{1F680} Starting gmoonc installer...");
|
|
1816
1984
|
logInfo("\u{1F4E6} Installing complete dashboard into your React project\n");
|
|
@@ -1818,9 +1986,9 @@ program.name("gmoonc").description("Goalmoon Ctrl (gmoonc): Install complete das
|
|
|
1818
1986
|
const basePath = options.base || "/app";
|
|
1819
1987
|
const dryRun = options.dryRun || false;
|
|
1820
1988
|
const skipRouterPatch = options.skipRouterPatch || false;
|
|
1821
|
-
const gmooncDir = (0,
|
|
1822
|
-
const markerFile = (0,
|
|
1823
|
-
if ((0,
|
|
1989
|
+
const gmooncDir = (0, import_path8.join)(projectDir, "src/gmoonc");
|
|
1990
|
+
const markerFile = (0, import_path8.join)(gmooncDir, ".gmoonc-installed.json");
|
|
1991
|
+
if ((0, import_fs13.existsSync)(gmooncDir) || (0, import_fs13.existsSync)(markerFile)) {
|
|
1824
1992
|
logError("gmoonc already installed (src/gmoonc exists or marker file found).");
|
|
1825
1993
|
logError("Remove src/gmoonc and restore backups to reinstall.");
|
|
1826
1994
|
process.exit(1);
|
|
@@ -1861,7 +2029,7 @@ program.name("gmoonc").description("Goalmoon Ctrl (gmoonc): Install complete das
|
|
|
1861
2029
|
process.exit(1);
|
|
1862
2030
|
}
|
|
1863
2031
|
logInfo("\n\u{1F4DD} Injecting CSS imports...");
|
|
1864
|
-
const entrypointPath = (0,
|
|
2032
|
+
const entrypointPath = (0, import_path8.join)(projectDir, project.entrypoint);
|
|
1865
2033
|
const cssResult = patchEntryCss(entrypointPath, dryRun);
|
|
1866
2034
|
if (!cssResult.success && !dryRun) {
|
|
1867
2035
|
logError("Failed to inject CSS");
|
|
@@ -1883,11 +2051,11 @@ program.name("gmoonc").description("Goalmoon Ctrl (gmoonc): Install complete das
|
|
|
1883
2051
|
}
|
|
1884
2052
|
if (!dryRun) {
|
|
1885
2053
|
ensureDirectoryExists(markerFile);
|
|
1886
|
-
const packageJsonPath = (0,
|
|
2054
|
+
const packageJsonPath = (0, import_path8.join)(projectDir, "package.json");
|
|
1887
2055
|
let version = "0.0.10";
|
|
1888
2056
|
try {
|
|
1889
|
-
if ((0,
|
|
1890
|
-
const packageJson = JSON.parse((0,
|
|
2057
|
+
if ((0, import_fs13.existsSync)(packageJsonPath)) {
|
|
2058
|
+
const packageJson = JSON.parse((0, import_fs13.readFileSync)(packageJsonPath, "utf-8"));
|
|
1891
2059
|
const gmooncVersion = packageJson.dependencies?.gmoonc || packageJson.devDependencies?.gmoonc;
|
|
1892
2060
|
if (gmooncVersion) {
|
|
1893
2061
|
version = gmooncVersion.replace(/^[\^~]/, "");
|
|
@@ -1899,7 +2067,7 @@ program.name("gmoonc").description("Goalmoon Ctrl (gmoonc): Install complete das
|
|
|
1899
2067
|
version,
|
|
1900
2068
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1901
2069
|
}, null, 2);
|
|
1902
|
-
(0,
|
|
2070
|
+
(0, import_fs13.writeFileSync)(markerFile, markerContent, "utf-8");
|
|
1903
2071
|
}
|
|
1904
2072
|
logSuccess("\n\u2705 Installation complete!");
|
|
1905
2073
|
logInfo("\nYour dashboard is now available at:");
|
|
@@ -1945,4 +2113,34 @@ program.command("supabase").description("Setup Supabase integration (Auth + RBAC
|
|
|
1945
2113
|
process.exit(1);
|
|
1946
2114
|
}
|
|
1947
2115
|
});
|
|
2116
|
+
program.command("supabase-seed").description("Seed Supabase database with schema, RLS, functions, and initial data").option("--vite", "Seed for Vite projects").action(async (options) => {
|
|
2117
|
+
try {
|
|
2118
|
+
logInfo("\u{1F331} Starting Supabase database seeding...");
|
|
2119
|
+
const projectDir = (0, import_process.cwd)();
|
|
2120
|
+
const dryRun = false;
|
|
2121
|
+
if (!options.vite) {
|
|
2122
|
+
logError("Missing platform flag. Use: gmoonc supabase-seed --vite (Next will be added later).");
|
|
2123
|
+
process.exit(1);
|
|
2124
|
+
}
|
|
2125
|
+
const result = await seedSupabase({
|
|
2126
|
+
projectDir,
|
|
2127
|
+
dryRun
|
|
2128
|
+
});
|
|
2129
|
+
if (!result.success) {
|
|
2130
|
+
process.exit(1);
|
|
2131
|
+
}
|
|
2132
|
+
logSuccess("\n\u2705 Database seeding complete!");
|
|
2133
|
+
logInfo("\nYour Supabase database is now ready with:");
|
|
2134
|
+
logInfo(" - Tables (profiles, roles, modules, permissions, etc.)");
|
|
2135
|
+
logInfo(" - Functions and triggers");
|
|
2136
|
+
logInfo(" - Row Level Security (RLS) policies");
|
|
2137
|
+
logInfo(" - Initial seed data (Apollo user)");
|
|
2138
|
+
} catch (error) {
|
|
2139
|
+
logError(`Error: ${error.message}`);
|
|
2140
|
+
if (error.stack && process.env.DEBUG) {
|
|
2141
|
+
console.error(error.stack);
|
|
2142
|
+
}
|
|
2143
|
+
process.exit(1);
|
|
2144
|
+
}
|
|
2145
|
+
});
|
|
1948
2146
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gmoonc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "Goalmoon Ctrl (gmoonc): Complete dashboard installer for React projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://gmoonc.com",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"dist",
|
|
21
21
|
"src/templates",
|
|
22
|
+
"assets",
|
|
22
23
|
"scripts",
|
|
23
24
|
"README.md",
|
|
24
25
|
"LICENSE"
|
|
@@ -32,10 +33,13 @@
|
|
|
32
33
|
"postinstall": "node scripts/block-global-install.cjs"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"commander": "^12.0.0"
|
|
36
|
+
"commander": "^12.0.0",
|
|
37
|
+
"dotenv": "^16.4.5",
|
|
38
|
+
"pg": "^8.11.3"
|
|
36
39
|
},
|
|
37
40
|
"devDependencies": {
|
|
38
41
|
"@types/node": "^20.0.0",
|
|
42
|
+
"@types/pg": "^8.10.9",
|
|
39
43
|
"rimraf": "^6.0.0",
|
|
40
44
|
"tsup": "^8.0.0",
|
|
41
45
|
"typescript": "^5.0.0"
|