Compare commits
2 Commits
96ea8e21ef
...
dd06fd1196
| Author | SHA1 | Date | |
|---|---|---|---|
| dd06fd1196 | |||
| 5c24783320 |
285
full_schema.sql
Normal file
285
full_schema.sql
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
DROP SCHEMA IF EXISTS gpi CASCADE;
|
||||||
|
-- Criar schema gpi
|
||||||
|
CREATE SCHEMA IF NOT EXISTS gpi;
|
||||||
|
|
||||||
|
-- Tabela organizations
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.organizations (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Inserir organização padrão
|
||||||
|
INSERT INTO gpi.organizations (id, name)
|
||||||
|
VALUES ('e47e6210-4879-4e5b-bf21-9285d2713123', 'Organização Migrada')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.users (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
logto_id TEXT UNIQUE,
|
||||||
|
email TEXT NOT NULL,
|
||||||
|
name TEXT,
|
||||||
|
role TEXT DEFAULT 'user',
|
||||||
|
is_banned BOOLEAN DEFAULT false,
|
||||||
|
last_seen_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.projects (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
client TEXT,
|
||||||
|
start_date DATE,
|
||||||
|
end_date DATE,
|
||||||
|
environment TEXT,
|
||||||
|
technician TEXT,
|
||||||
|
weight_kg DECIMAL(10,2),
|
||||||
|
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'archived')),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela parts
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.parts (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
|
description TEXT,
|
||||||
|
dimensions TEXT,
|
||||||
|
weight DECIMAL(10,3),
|
||||||
|
type TEXT,
|
||||||
|
area DECIMAL(10,3),
|
||||||
|
complexity INTEGER DEFAULT 1,
|
||||||
|
quantity INTEGER NOT NULL DEFAULT 1,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela painting_schemes
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.painting_schemes (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
type TEXT,
|
||||||
|
coat TEXT,
|
||||||
|
solids_volume DECIMAL(12,3),
|
||||||
|
yield_theoretical DECIMAL(12,3),
|
||||||
|
eps_min DECIMAL(12,3),
|
||||||
|
eps_max DECIMAL(12,3),
|
||||||
|
dilution DECIMAL(12,3),
|
||||||
|
manufacturer TEXT,
|
||||||
|
color TEXT,
|
||||||
|
paint_consumption DECIMAL(12,3),
|
||||||
|
thinner_consumption DECIMAL(12,3),
|
||||||
|
paint_id TEXT,
|
||||||
|
thinner_id TEXT,
|
||||||
|
color_hex TEXT,
|
||||||
|
thinner_symbol TEXT,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela application_records
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.application_records (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
|
coat_stage TEXT NOT NULL,
|
||||||
|
piece_description TEXT,
|
||||||
|
date DATE,
|
||||||
|
operator TEXT,
|
||||||
|
real_weight DECIMAL(10,3),
|
||||||
|
volume_used DECIMAL(10,3),
|
||||||
|
area_painted DECIMAL(10,3),
|
||||||
|
wet_thickness_avg DECIMAL(6,2),
|
||||||
|
dry_thickness_calc DECIMAL(6,2),
|
||||||
|
real_yield DECIMAL(10,3),
|
||||||
|
method TEXT,
|
||||||
|
diluent_used DECIMAL(10,3),
|
||||||
|
items JSONB,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela inspections
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.inspections (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
|
application_record_id UUID REFERENCES gpi.application_records(id),
|
||||||
|
stock_item_id TEXT,
|
||||||
|
instrument_id TEXT,
|
||||||
|
type TEXT CHECK (type IN ('painting', 'surface_treatment')),
|
||||||
|
date DATE,
|
||||||
|
inspector TEXT,
|
||||||
|
part_temperature DECIMAL(6,2),
|
||||||
|
weight_kg DECIMAL(10,3),
|
||||||
|
appearance TEXT,
|
||||||
|
defects TEXT,
|
||||||
|
photos TEXT[],
|
||||||
|
piece_description TEXT,
|
||||||
|
eps_points DECIMAL(6,2)[],
|
||||||
|
adhesion_test TEXT,
|
||||||
|
batch TEXT,
|
||||||
|
treatment_executor TEXT,
|
||||||
|
treatment_type TEXT,
|
||||||
|
cleaning_degree TEXT,
|
||||||
|
roughness_readings DECIMAL(6,2)[],
|
||||||
|
flash_rust TEXT,
|
||||||
|
temperature DECIMAL(6,2),
|
||||||
|
relative_humidity DECIMAL(5,2),
|
||||||
|
period TEXT CHECK (period IN ('morning', 'afternoon', 'night')),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela technical_data_sheets
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.technical_data_sheets (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
manufacturer TEXT,
|
||||||
|
type TEXT,
|
||||||
|
file_url TEXT,
|
||||||
|
upload_date DATE,
|
||||||
|
solids_volume DECIMAL(12,3),
|
||||||
|
density DECIMAL(12,3),
|
||||||
|
mixing_ratio TEXT,
|
||||||
|
yield_theoretical DECIMAL(12,3),
|
||||||
|
wft_min DECIMAL(12,3),
|
||||||
|
wft_max DECIMAL(12,3),
|
||||||
|
dft_min DECIMAL(12,3),
|
||||||
|
dft_max DECIMAL(12,3),
|
||||||
|
reducer TEXT,
|
||||||
|
mixing_ratio_weight TEXT,
|
||||||
|
mixing_ratio_volume TEXT,
|
||||||
|
dft_reference DECIMAL(12,3),
|
||||||
|
yield_factor DECIMAL(12,3),
|
||||||
|
dilution DECIMAL(12,3),
|
||||||
|
notes TEXT,
|
||||||
|
manufacturer_code TEXT,
|
||||||
|
min_stock DECIMAL(12,3),
|
||||||
|
typical_application TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela yield_studies
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.yield_studies (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
data_sheet_id TEXT NOT NULL,
|
||||||
|
target_dft DECIMAL(6,2) NOT NULL,
|
||||||
|
dilution_percent DECIMAL(5,2) NOT NULL,
|
||||||
|
categories JSONB NOT NULL,
|
||||||
|
total_weight DECIMAL(10,3),
|
||||||
|
estimated_paint_volume DECIMAL(10,3),
|
||||||
|
estimated_reducer_volume DECIMAL(10,3),
|
||||||
|
estimated_paint_volume_by_area DECIMAL(10,3),
|
||||||
|
estimated_reducer_volume_by_area DECIMAL(10,3),
|
||||||
|
average_complexity DECIMAL(3,1),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela instruments
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.instruments (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
type TEXT NOT NULL,
|
||||||
|
serial_number TEXT,
|
||||||
|
manufacturer TEXT,
|
||||||
|
model TEXT,
|
||||||
|
last_calibration DATE,
|
||||||
|
next_calibration DATE,
|
||||||
|
status TEXT DEFAULT 'active',
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela stock_items
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.stock_items (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
type TEXT NOT NULL,
|
||||||
|
batch_number TEXT,
|
||||||
|
quantity DECIMAL(10,3) DEFAULT 0,
|
||||||
|
unit TEXT DEFAULT 'L',
|
||||||
|
data_sheet_id TEXT,
|
||||||
|
location TEXT,
|
||||||
|
expiration_date DATE,
|
||||||
|
status TEXT DEFAULT 'available',
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela stock_movements
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.stock_movements (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
stock_item_id UUID REFERENCES gpi.stock_items(id) ON DELETE CASCADE,
|
||||||
|
type TEXT NOT NULL CHECK (type IN ('in', 'out', 'adjustment')),
|
||||||
|
quantity DECIMAL(10,3) NOT NULL,
|
||||||
|
reason TEXT,
|
||||||
|
performed_by TEXT,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela notifications
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.notifications (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
type TEXT DEFAULT 'info' CHECK (type IN ('info', 'warning', 'error', 'success')),
|
||||||
|
is_read BOOLEAN DEFAULT false,
|
||||||
|
is_archived BOOLEAN DEFAULT false,
|
||||||
|
archived_by TEXT[],
|
||||||
|
deleted_by TEXT[],
|
||||||
|
metadata JSONB,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabela geometry_types
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.geometry_types (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
efficiency_loss DECIMAL(5,2),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Habilitar PostgREST para o schema gpi
|
||||||
|
GRANT USAGE ON SCHEMA gpi TO postgres, anon, authenticated, service_role;
|
||||||
|
|
||||||
|
-- Grant permissions em todas as tabelas
|
||||||
|
GRANT ALL ON TABLE gpi.users TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.projects TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.parts TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.painting_schemes TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.application_records TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.inspections TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.technical_data_sheets TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.yield_studies TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.instruments TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.stock_items TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.stock_movements TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.notifications TO postgres, anon, authenticated, service_role;
|
||||||
|
GRANT ALL ON TABLE gpi.geometry_types TO postgres, anon, authenticated, service_role;
|
||||||
|
|
||||||
|
-- Grant sequences
|
||||||
|
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA gpi TO postgres, anon, authenticated, service_role;
|
||||||
|
|
||||||
|
SELECT 'Schema gpi criado com sucesso!' AS result;
|
||||||
101
migrate.js
Normal file
101
migrate.js
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import { MongoClient } from 'mongodb';
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
|
||||||
|
const MONGO_URI = "mongodb+srv://admtracksteel:mongodb26@cluster0.a4xiilu.mongodb.net/ts_gpi";
|
||||||
|
const DB_NAME = "ts_gpi";
|
||||||
|
const DEFAULT_ORG_ID = "e47e6210-4879-4e5b-bf21-9285d2713123";
|
||||||
|
|
||||||
|
const client = new MongoClient(MONGO_URI);
|
||||||
|
|
||||||
|
// Map Mongo _id -> Supabase UUID
|
||||||
|
const idMap = new Map();
|
||||||
|
|
||||||
|
function getUUID(mongoId) {
|
||||||
|
if (!mongoId) return null;
|
||||||
|
const mid = mongoId.toString();
|
||||||
|
if (idMap.has(mid)) return idMap.get(mid);
|
||||||
|
const newUuid = crypto.randomUUID();
|
||||||
|
idMap.set(mid, newUuid);
|
||||||
|
return newUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sqlSafe(val) {
|
||||||
|
if (val === null || val === undefined) return 'NULL';
|
||||||
|
if (val instanceof Date) return `'${val.toISOString()}'`;
|
||||||
|
if (Array.isArray(val)) return `'{"${val.join('","')}"}'`;
|
||||||
|
if (typeof val === 'object' && val.toString) {
|
||||||
|
const s = val.toString();
|
||||||
|
return `'${s.replace(/'/g, "''")}'`;
|
||||||
|
}
|
||||||
|
if (typeof val === 'string') return `'${val.replace(/'/g, "''")}'`;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
try {
|
||||||
|
await client.connect();
|
||||||
|
console.log("🚀 Conectado ao MongoDB Atlas...");
|
||||||
|
const db = client.db(DB_NAME);
|
||||||
|
|
||||||
|
// 1. Mapear Projetos primeiro
|
||||||
|
const mongoProjects = await db.collection('projects').find().toArray();
|
||||||
|
console.log(`📦 Encontrados ${mongoProjects.length} projetos.`);
|
||||||
|
|
||||||
|
let projectInserts = [];
|
||||||
|
for (const p of mongoProjects) {
|
||||||
|
const uuid = getUUID(p._id);
|
||||||
|
projectInserts.push(`INSERT INTO gpi.projects (id, organization_id, name, client, start_date, end_date, environment, technician, weight_kg, status, created_at, updated_at) VALUES (${sqlSafe(uuid)}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(p.name)}, ${sqlSafe(p.client)}, ${sqlSafe(p.startDate)}, ${sqlSafe(p.endDate)}, ${sqlSafe(p.environment)}, ${sqlSafe(p.technician)}, ${sqlSafe(p.weightKg)}, 'active', ${sqlSafe(p.createdAt)}, ${sqlSafe(p.updatedAt)});`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Mapear Biblioteca de Tintas (Technical Data Sheets)
|
||||||
|
const mongoTDS = await db.collection('technicaldatasheets').find().toArray();
|
||||||
|
console.log(`📚 Encontradas ${mongoTDS.length} fichas técnicas.`);
|
||||||
|
let tdsInserts = [];
|
||||||
|
for (const t of mongoTDS) {
|
||||||
|
const uuid = getUUID(t._id);
|
||||||
|
tdsInserts.push(`INSERT INTO gpi.technical_data_sheets (id, organization_id, name, manufacturer, manufacturer_code, type, min_stock, typical_application, solids_volume, mixing_ratio, yield_theoretical, wft_min, wft_max, dft_min, dft_max, reducer, mixing_ratio_weight, mixing_ratio_volume, dft_reference, yield_factor, dilution, notes, created_at, updated_at) VALUES (${sqlSafe(uuid)}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(t.name)}, ${sqlSafe(t.manufacturer)}, ${sqlSafe(t.manufacturerCode)}, ${sqlSafe(t.type)}, ${sqlSafe(t.minStock)}, ${sqlSafe(t.typicalApplication)}, ${sqlSafe(t.solidsVolume)}, ${sqlSafe(t.mixingRatio)}, ${sqlSafe(t.yieldTheoretical)}, ${sqlSafe(t.wftMin)}, ${sqlSafe(t.wftMax)}, ${sqlSafe(t.dftMin)}, ${sqlSafe(t.dftMax)}, ${sqlSafe(t.reducer)}, ${sqlSafe(t.mixingRatioWeight)}, ${sqlSafe(t.mixingRatioVolume)}, ${sqlSafe(t.dftReference)}, ${sqlSafe(t.yieldFactor)}, ${sqlSafe(t.dilution)}, ${sqlSafe(t.notes)}, ${sqlSafe(t.createdAt)}, ${sqlSafe(t.updatedAt)});`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Mapear Esquemas de Pintura
|
||||||
|
const mongoSchemes = await db.collection('paintingschemes').find().toArray();
|
||||||
|
console.log(`🎨 Encontrados ${mongoSchemes.length} esquemas de pintura.`);
|
||||||
|
let schemeInserts = [];
|
||||||
|
for (const s of mongoSchemes) {
|
||||||
|
const uuid = crypto.randomUUID();
|
||||||
|
const projectId = getUUID(s.projectId);
|
||||||
|
schemeInserts.push(`INSERT INTO gpi.painting_schemes (id, organization_id, project_id, name, type, coat, solids_volume, yield_theoretical, eps_min, eps_max, dilution, manufacturer, color, paint_consumption, thinner_consumption, paint_id, thinner_id, color_hex, thinner_symbol, notes, created_at, updated_at) VALUES (${sqlSafe(uuid)}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(projectId)}, ${sqlSafe(s.name)}, ${sqlSafe(s.type)}, ${sqlSafe(s.coat)}, ${sqlSafe(s.solidsVolume)}, ${sqlSafe(s.yieldTheoretical)}, ${sqlSafe(s.epsMin)}, ${sqlSafe(s.epsMax)}, ${sqlSafe(s.dilution)}, ${sqlSafe(s.manufacturer)}, ${sqlSafe(s.color)}, ${sqlSafe(s.paintConsumption)}, ${sqlSafe(s.thinnerConsumption)}, ${sqlSafe(s.paintId)}, ${sqlSafe(s.thinnerId)}, ${sqlSafe(s.colorHex)}, ${sqlSafe(s.thinnerSymbol)}, ${sqlSafe(s.notes)}, NOW(), NOW());`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Mapear Peças (Parts)
|
||||||
|
const mongoParts = await db.collection('parts').find().toArray();
|
||||||
|
console.log(`🧩 Encontradas ${mongoParts.length} peças.`);
|
||||||
|
let partsInserts = [];
|
||||||
|
for (const pt of mongoParts) {
|
||||||
|
const uuid = getUUID(pt._id);
|
||||||
|
const projectId = getUUID(pt.projectId);
|
||||||
|
partsInserts.push(`INSERT INTO gpi.parts (id, organization_id, project_id, description, dimensions, weight, type, area, quantity, notes, created_at, updated_at) VALUES (${sqlSafe(uuid)}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(projectId)}, ${sqlSafe(pt.description)}, ${sqlSafe(pt.dimensions)}, ${sqlSafe(pt.weight)}, ${sqlSafe(pt.type)}, ${sqlSafe(pt.area)}, ${sqlSafe(pt.quantity)}, ${sqlSafe(pt.notes)}, NOW(), NOW());`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executar SQL
|
||||||
|
const allSQL = [...projectInserts, ...tdsInserts, ...schemeInserts, ...partsInserts].join('\n');
|
||||||
|
|
||||||
|
console.log("💾 Executando SQL no Supabase...");
|
||||||
|
|
||||||
|
// Escrever para arquivo temporário
|
||||||
|
const fs = await import('fs');
|
||||||
|
fs.writeFileSync('/tmp/bulk_migration.sql', allSQL);
|
||||||
|
|
||||||
|
// Executar via docker
|
||||||
|
execSync(`docker exec -i supabase-db-h0oggskgs0ws0sco8kc4s8ws psql -U supabase_admin -d postgres < /tmp/bulk_migration.sql`);
|
||||||
|
|
||||||
|
console.log("✅ Migração Concluída com Sucesso!");
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error("❌ ERRO DURANTE MIGRAÇÃO:", e.message);
|
||||||
|
} finally {
|
||||||
|
await client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
143
package-lock.json
generated
143
package-lock.json
generated
@@ -24,6 +24,7 @@
|
|||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
"jose": "^5.2.0",
|
"jose": "^5.2.0",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
|
"mongodb": "^7.1.1",
|
||||||
"multer": "^2.0.2",
|
"multer": "^2.0.2",
|
||||||
"pdf-parse": "^1.1.1",
|
"pdf-parse": "^1.1.1",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
@@ -2389,6 +2390,15 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@mongodb-js/saslprep": {
|
||||||
|
"version": "1.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz",
|
||||||
|
"integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"sparse-bitfield": "^3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3595,6 +3605,21 @@
|
|||||||
"version": "10.0.0",
|
"version": "10.0.0",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/webidl-conversions": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/whatwg-url": {
|
||||||
|
"version": "13.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz",
|
||||||
|
"integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/webidl-conversions": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/ws": {
|
"node_modules/@types/ws": {
|
||||||
"version": "8.18.1",
|
"version": "8.18.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -5022,6 +5047,15 @@
|
|||||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bson": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bson/-/bson-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-from": {
|
"node_modules/buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
@@ -8010,6 +8044,12 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/memory-pager": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -8133,6 +8173,65 @@
|
|||||||
"mkdirp": "bin/cmd.js"
|
"mkdirp": "bin/cmd.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mongodb": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-067DXiMjcpYQl6bGjWQoTUEE9UoRViTtKFcoqX7z08I+iDZv/emH1g8XEFiO3qiDfXAheT5ozl1VffDTKhIW/w==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@mongodb-js/saslprep": "^1.3.0",
|
||||||
|
"bson": "^7.1.1",
|
||||||
|
"mongodb-connection-string-url": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.19.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@aws-sdk/credential-providers": "^3.806.0",
|
||||||
|
"@mongodb-js/zstd": "^7.0.0",
|
||||||
|
"gcp-metadata": "^7.0.1",
|
||||||
|
"kerberos": "^7.0.0",
|
||||||
|
"mongodb-client-encryption": ">=7.0.0 <7.1.0",
|
||||||
|
"snappy": "^7.3.2",
|
||||||
|
"socks": "^2.8.6"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@aws-sdk/credential-providers": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@mongodb-js/zstd": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"gcp-metadata": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"kerberos": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"mongodb-client-encryption": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"snappy": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"socks": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mongodb-connection-string-url": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-h0AZ9A7IDVwwHyMxmdMXKy+9oNlF0zFoahHiX3vQ8e3KFcSP3VmsmfvtRSuLPxmyv2vjIDxqty8smTgie/SNRQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/whatwg-url": "^13.0.0",
|
||||||
|
"whatwg-url": "^14.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mri": {
|
"node_modules/mri": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -8769,7 +8868,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -9695,6 +9793,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/sparse-bitfield": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"memory-pager": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -10084,6 +10191,18 @@
|
|||||||
"nodetouch": "bin/nodetouch.js"
|
"nodetouch": "bin/nodetouch.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": "^2.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tree-kill": {
|
"node_modules/tree-kill": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -11126,6 +11245,28 @@
|
|||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "14.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
|
||||||
|
"integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "^5.1.0",
|
||||||
|
"webidl-conversions": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
"jose": "^5.2.0",
|
"jose": "^5.2.0",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
|
"mongodb": "^7.1.1",
|
||||||
"multer": "^2.0.2",
|
"multer": "^2.0.2",
|
||||||
"pdf-parse": "^1.1.1",
|
"pdf-parse": "^1.1.1",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
|
|||||||
1
reset_gpi.sql
Normal file
1
reset_gpi.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DROP SCHEMA IF EXISTS gpi CASCADE;
|
||||||
@@ -1,7 +1,18 @@
|
|||||||
-- Criar schema gpi
|
-- Criar schema gpi
|
||||||
CREATE SCHEMA IF NOT EXISTS gpi;
|
CREATE SCHEMA IF NOT EXISTS gpi;
|
||||||
|
|
||||||
-- Tabela users (já existe em public, mas replicamos em gpi)
|
-- Tabela organizations
|
||||||
|
CREATE TABLE IF NOT EXISTS gpi.organizations (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Inserir organização padrão
|
||||||
|
INSERT INTO gpi.organizations (id, name)
|
||||||
|
VALUES ('e47e6210-4879-4e5b-bf21-9285d2713123', 'Organização Migrada')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
CREATE TABLE IF NOT EXISTS gpi.users (
|
CREATE TABLE IF NOT EXISTS gpi.users (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
logto_id TEXT UNIQUE,
|
logto_id TEXT UNIQUE,
|
||||||
@@ -14,9 +25,9 @@ CREATE TABLE IF NOT EXISTS gpi.users (
|
|||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Tabela projects
|
|
||||||
CREATE TABLE IF NOT EXISTS gpi.projects (
|
CREATE TABLE IF NOT EXISTS gpi.projects (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
client TEXT,
|
client TEXT,
|
||||||
start_date DATE,
|
start_date DATE,
|
||||||
@@ -24,8 +35,7 @@ CREATE TABLE IF NOT EXISTS gpi.projects (
|
|||||||
environment TEXT,
|
environment TEXT,
|
||||||
technician TEXT,
|
technician TEXT,
|
||||||
weight_kg DECIMAL(10,2),
|
weight_kg DECIMAL(10,2),
|
||||||
painted_weight DECIMAL(10,2),
|
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'archived')),
|
||||||
created_by TEXT,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -33,7 +43,8 @@ CREATE TABLE IF NOT EXISTS gpi.projects (
|
|||||||
-- Tabela parts
|
-- Tabela parts
|
||||||
CREATE TABLE IF NOT EXISTS gpi.parts (
|
CREATE TABLE IF NOT EXISTS gpi.parts (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
project_id UUID REFERENCES gpi/projects(id) ON DELETE CASCADE,
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
dimensions TEXT,
|
dimensions TEXT,
|
||||||
weight DECIMAL(10,3),
|
weight DECIMAL(10,3),
|
||||||
@@ -49,25 +60,25 @@ CREATE TABLE IF NOT EXISTS gpi.parts (
|
|||||||
-- Tabela painting_schemes
|
-- Tabela painting_schemes
|
||||||
CREATE TABLE IF NOT EXISTS gpi.painting_schemes (
|
CREATE TABLE IF NOT EXISTS gpi.painting_schemes (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
project_id UUID REFERENCES gpi/projects(id) ON DELETE CASCADE,
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
type TEXT,
|
type TEXT,
|
||||||
coat TEXT,
|
coat TEXT,
|
||||||
solids_volume DECIMAL(5,2),
|
solids_volume DECIMAL(12,3),
|
||||||
yield_theoretical DECIMAL(10,2),
|
yield_theoretical DECIMAL(12,3),
|
||||||
eps_min DECIMAL(5,2),
|
eps_min DECIMAL(12,3),
|
||||||
eps_max DECIMAL(5,2),
|
eps_max DECIMAL(12,3),
|
||||||
dilution DECIMAL(5,2),
|
dilution DECIMAL(12,3),
|
||||||
manufacturer TEXT,
|
manufacturer TEXT,
|
||||||
color TEXT,
|
color TEXT,
|
||||||
paint_consumption DECIMAL(10,3),
|
paint_consumption DECIMAL(12,3),
|
||||||
thinner_consumption DECIMAL(10,3),
|
thinner_consumption DECIMAL(12,3),
|
||||||
paint_id TEXT,
|
paint_id TEXT,
|
||||||
thinner_id TEXT,
|
thinner_id TEXT,
|
||||||
color_hex TEXT,
|
color_hex TEXT,
|
||||||
thinner_symbol TEXT,
|
thinner_symbol TEXT,
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
created_by TEXT,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -75,7 +86,8 @@ CREATE TABLE IF NOT EXISTS gpi.painting_schemes (
|
|||||||
-- Tabela application_records
|
-- Tabela application_records
|
||||||
CREATE TABLE IF NOT EXISTS gpi.application_records (
|
CREATE TABLE IF NOT EXISTS gpi.application_records (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
project_id UUID REFERENCES gpi/projects(id) ON DELETE CASCADE,
|
organization_id UUID NOT NULL,
|
||||||
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
coat_stage TEXT NOT NULL,
|
coat_stage TEXT NOT NULL,
|
||||||
piece_description TEXT,
|
piece_description TEXT,
|
||||||
date DATE,
|
date DATE,
|
||||||
@@ -90,7 +102,6 @@ CREATE TABLE IF NOT EXISTS gpi.application_records (
|
|||||||
diluent_used DECIMAL(10,3),
|
diluent_used DECIMAL(10,3),
|
||||||
items JSONB,
|
items JSONB,
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
created_by TEXT,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -98,8 +109,9 @@ CREATE TABLE IF NOT EXISTS gpi.application_records (
|
|||||||
-- Tabela inspections
|
-- Tabela inspections
|
||||||
CREATE TABLE IF NOT EXISTS gpi.inspections (
|
CREATE TABLE IF NOT EXISTS gpi.inspections (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
project_id UUID REFERENCES gpi/projects(id) ON DELETE CASCADE,
|
organization_id UUID NOT NULL,
|
||||||
application_record_id UUID REFERENCES gpi/application_records(id),
|
project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
|
||||||
|
application_record_id UUID REFERENCES gpi.application_records(id),
|
||||||
stock_item_id TEXT,
|
stock_item_id TEXT,
|
||||||
instrument_id TEXT,
|
instrument_id TEXT,
|
||||||
type TEXT CHECK (type IN ('painting', 'surface_treatment')),
|
type TEXT CHECK (type IN ('painting', 'surface_treatment')),
|
||||||
@@ -122,7 +134,6 @@ CREATE TABLE IF NOT EXISTS gpi.inspections (
|
|||||||
temperature DECIMAL(6,2),
|
temperature DECIMAL(6,2),
|
||||||
relative_humidity DECIMAL(5,2),
|
relative_humidity DECIMAL(5,2),
|
||||||
period TEXT CHECK (period IN ('morning', 'afternoon', 'night')),
|
period TEXT CHECK (period IN ('morning', 'afternoon', 'night')),
|
||||||
created_by TEXT,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -130,28 +141,29 @@ CREATE TABLE IF NOT EXISTS gpi.inspections (
|
|||||||
-- Tabela technical_data_sheets
|
-- Tabela technical_data_sheets
|
||||||
CREATE TABLE IF NOT EXISTS gpi.technical_data_sheets (
|
CREATE TABLE IF NOT EXISTS gpi.technical_data_sheets (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
manufacturer TEXT,
|
manufacturer TEXT,
|
||||||
type TEXT,
|
type TEXT,
|
||||||
file_url TEXT NOT NULL,
|
file_url TEXT,
|
||||||
upload_date DATE NOT NULL,
|
upload_date DATE,
|
||||||
solids_volume DECIMAL(5,2),
|
solids_volume DECIMAL(12,3),
|
||||||
density DECIMAL(6,3),
|
density DECIMAL(12,3),
|
||||||
mixing_ratio TEXT,
|
mixing_ratio TEXT,
|
||||||
yield_theoretical DECIMAL(10,2),
|
yield_theoretical DECIMAL(12,3),
|
||||||
wft_min DECIMAL(6,2),
|
wft_min DECIMAL(12,3),
|
||||||
wft_max DECIMAL(6,2),
|
wft_max DECIMAL(12,3),
|
||||||
dft_min DECIMAL(6,2),
|
dft_min DECIMAL(12,3),
|
||||||
dft_max DECIMAL(6,2),
|
dft_max DECIMAL(12,3),
|
||||||
reducer TEXT,
|
reducer TEXT,
|
||||||
mixing_ratio_weight TEXT,
|
mixing_ratio_weight TEXT,
|
||||||
mixing_ratio_volume TEXT,
|
mixing_ratio_volume TEXT,
|
||||||
dft_reference DECIMAL(6,2),
|
dft_reference DECIMAL(12,3),
|
||||||
yield_factor DECIMAL(5,3),
|
yield_factor DECIMAL(12,3),
|
||||||
dilution DECIMAL(5,2),
|
dilution DECIMAL(12,3),
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
manufacturer_code TEXT,
|
manufacturer_code TEXT,
|
||||||
min_stock DECIMAL(10,3),
|
min_stock DECIMAL(12,3),
|
||||||
typical_application TEXT,
|
typical_application TEXT,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
@@ -160,6 +172,7 @@ CREATE TABLE IF NOT EXISTS gpi.technical_data_sheets (
|
|||||||
-- Tabela yield_studies
|
-- Tabela yield_studies
|
||||||
CREATE TABLE IF NOT EXISTS gpi.yield_studies (
|
CREATE TABLE IF NOT EXISTS gpi.yield_studies (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
data_sheet_id TEXT NOT NULL,
|
data_sheet_id TEXT NOT NULL,
|
||||||
target_dft DECIMAL(6,2) NOT NULL,
|
target_dft DECIMAL(6,2) NOT NULL,
|
||||||
@@ -178,16 +191,16 @@ CREATE TABLE IF NOT EXISTS gpi.yield_studies (
|
|||||||
-- Tabela instruments
|
-- Tabela instruments
|
||||||
CREATE TABLE IF NOT EXISTS gpi.instruments (
|
CREATE TABLE IF NOT EXISTS gpi.instruments (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
type TEXT NOT NULL,
|
type TEXT NOT NULL,
|
||||||
serial_number TEXT UNIQUE,
|
serial_number TEXT,
|
||||||
manufacturer TEXT,
|
manufacturer TEXT,
|
||||||
model TEXT,
|
model TEXT,
|
||||||
last_calibration DATE,
|
last_calibration DATE,
|
||||||
next_calibration DATE,
|
next_calibration DATE,
|
||||||
status TEXT DEFAULT 'active',
|
status TEXT DEFAULT 'active',
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
organization_id TEXT,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -195,6 +208,7 @@ CREATE TABLE IF NOT EXISTS gpi.instruments (
|
|||||||
-- Tabela stock_items
|
-- Tabela stock_items
|
||||||
CREATE TABLE IF NOT EXISTS gpi.stock_items (
|
CREATE TABLE IF NOT EXISTS gpi.stock_items (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
type TEXT NOT NULL,
|
type TEXT NOT NULL,
|
||||||
batch_number TEXT,
|
batch_number TEXT,
|
||||||
@@ -205,7 +219,6 @@ CREATE TABLE IF NOT EXISTS gpi.stock_items (
|
|||||||
expiration_date DATE,
|
expiration_date DATE,
|
||||||
status TEXT DEFAULT 'available',
|
status TEXT DEFAULT 'available',
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
organization_id TEXT,
|
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
@@ -213,7 +226,8 @@ CREATE TABLE IF NOT EXISTS gpi.stock_items (
|
|||||||
-- Tabela stock_movements
|
-- Tabela stock_movements
|
||||||
CREATE TABLE IF NOT EXISTS gpi.stock_movements (
|
CREATE TABLE IF NOT EXISTS gpi.stock_movements (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
stock_item_id UUID REFERENCES gpi/stock_items(id) ON DELETE CASCADE,
|
organization_id UUID NOT NULL,
|
||||||
|
stock_item_id UUID REFERENCES gpi.stock_items(id) ON DELETE CASCADE,
|
||||||
type TEXT NOT NULL CHECK (type IN ('in', 'out', 'adjustment')),
|
type TEXT NOT NULL CHECK (type IN ('in', 'out', 'adjustment')),
|
||||||
quantity DECIMAL(10,3) NOT NULL,
|
quantity DECIMAL(10,3) NOT NULL,
|
||||||
reason TEXT,
|
reason TEXT,
|
||||||
@@ -225,6 +239,7 @@ CREATE TABLE IF NOT EXISTS gpi.stock_movements (
|
|||||||
-- Tabela notifications
|
-- Tabela notifications
|
||||||
CREATE TABLE IF NOT EXISTS gpi.notifications (
|
CREATE TABLE IF NOT EXISTS gpi.notifications (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
message TEXT NOT NULL,
|
message TEXT NOT NULL,
|
||||||
type TEXT DEFAULT 'info' CHECK (type IN ('info', 'warning', 'error', 'success')),
|
type TEXT DEFAULT 'info' CHECK (type IN ('info', 'warning', 'error', 'success')),
|
||||||
@@ -239,13 +254,13 @@ CREATE TABLE IF NOT EXISTS gpi.notifications (
|
|||||||
-- Tabela geometry_types
|
-- Tabela geometry_types
|
||||||
CREATE TABLE IF NOT EXISTS gpi.geometry_types (
|
CREATE TABLE IF NOT EXISTS gpi.geometry_types (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
organization_id UUID NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
efficiency_loss DECIMAL(5,2),
|
efficiency_loss DECIMAL(5,2),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Habilitar PostgREST para o schema gpi
|
-- Habilitar PostgREST para o schema gpi
|
||||||
ALTER SCHEMA gpi ENABLE VALUE;
|
|
||||||
GRANT USAGE ON SCHEMA gpi TO postgres, anon, authenticated, service_role;
|
GRANT USAGE ON SCHEMA gpi TO postgres, anon, authenticated, service_role;
|
||||||
|
|
||||||
-- Grant permissions em todas as tabelas
|
-- Grant permissions em todas as tabelas
|
||||||
|
|||||||
Reference in New Issue
Block a user