# Guia de Adaptação do ORM e Camada de Base de Dados

Mudar de Supabase (geralmente gerido via `@supabase/supabase-js`) para uma arquitetura Backend+MySQL exige a introdução de uma API Intermédia e de um ORM robusto.

## 1. Abandono do Cliente Supabase Direto
Como a RLS (Row Level Security) e a Autenticação do Supabase já não existem, a aplicação Frontend (Vue/React/Svelte/Vanilla) **NÃO PODE** aceder à base de dados diretamente.

**Antigo (Frontend Supabase):**
```javascript
const { data } = await supabase.from('products').select('*');
```

**Novo (Frontend API REST):**
```javascript
const response = await fetch('/api/products', { headers: { 'Tenant-ID': 'xxxx' } });
const data = await response.json();
```

## 2. Adaptação de Autenticação (JWT)
O Backend deve agora gerar JSON Web Tokens (JWT) quando o utilizador faz login.
1. O utilizador envia `email` e `password`.
2. O Backend usa `bcrypt.compare` contra a coluna `password_hash` da tabela `users`.
3. O Backend emite um JWT contendo o `user_id`, `tenant_id`, e `role`.
4. Todos os requests seguintes devem enviar o header `Authorization: Bearer <TOKEN>`.

## 3. Adaptação do ORM (Prisma como Exemplo)

Se escolher Prisma ORM (altamente recomendado pela Type-safety):

**A. Mudança de Provider no `schema.prisma`:**
```prisma
datasource db {
  provider = "mysql" // Antes era "postgresql"
  url      = env("DATABASE_URL")
}
```

**B. Ajuste de Tipos Nativos:**
- `UUID` torna-se `String @id @default(uuid()) @db.VarChar(36)`
- `JSONB` torna-se `Json`
- `TIMESTAMP WITH TIME ZONE` torna-se `DateTime @default(now()) @db.Timestamp(0)`

**C. Isolamento Multi-Tenant por Omissão (Middleware ou Extensão Prisma):**
Para garantir que um utilizador nunca acede a dados de outro tenant, implemente o isolamento diretamente ao nível do cliente do ORM:

```typescript
import { PrismaClient } from '@prisma/client'

// Factory para garantir que cada request tem o tenant preso
export function getPrismaForTenant(tenantId: string) {
  const prisma = new PrismaClient()
  
  return prisma.$extends({
    query: {
      $allModels: {
        async $allOperations({ args, query }) {
          // Injetar tenantId na cláusula WHERE automaticamente
          if (args.where) {
            args.where.tenant_id = tenantId
          } else {
            args.where = { tenant_id: tenantId }
          }
          return query(args)
        },
      },
    },
  })
}
```

## 4. Adaptação Drizzle ORM (Alternativa de Alta Performance)

```typescript
import { mysqlTable, varchar, decimal, json, timestamp, boolean } from 'drizzle-orm/mysql-core';

export const products = mysqlTable('products', {
  id: varchar('id', { length: 36 }).primaryKey(),
  tenantId: varchar('tenant_id', { length: 36 }).notNull(),
  name: varchar('name', { length: 255 }).notNull(),
  slug: varchar('slug', { length: 255 }).notNull(),
  price: decimal('price', { precision: 10, scale: 2 }).notNull(),
  customizationChoices: json('customization_choices'),
  createdAt: timestamp('created_at').defaultNow()
});
```

## 5. Substituição de PostgreSQL Triggers
Na arquitetura Supabase, dependia-se muito de Triggers no DB para lógica de negócio (ex: handle_new_user).
Na nova arquitetura, utilize o modelo **Event-Driven Backend**:

1. Registo de Utilizador na API.
2. Inserção na DB através do Prisma/Drizzle.
3. Despachar um Evento no código Node.js/Go: `eventEmitter.emit('user.registered', user)`.
4. Os Listeners tratam do resto (ex: enviar email de boas-vindas) sem bloquear a Base de Dados.
