Update VSCode settings: Configure ESLint with flat config, set working directories for apps and packages, enable format on save, and specify default formatters for TypeScript, JSONC, and Svelte files.

This commit is contained in:
2026-01-08 11:21:30 -03:00
parent 0fbd56d39e
commit 91925a9dea
6 changed files with 490 additions and 4 deletions

View File

@@ -0,0 +1,143 @@
---
alwaysApply: true
---
# Banco de Dados: Frontend → Remote Functions (SvelteKit) + Drizzle (Server)
Neste projeto, **o frontend NÃO se comunica diretamente com o banco**. Toda leitura/escrita no DB deve acontecer **no servidor**, usando **SvelteKit Remote Functions** (`*.remote.ts`) e **Drizzle ORM**.
## Regras obrigatórias
- **NUNCA** importe/instancie `db` ou tabelas do Drizzle no client:
- Proibido em `.svelte`, `+page.ts`, `+layout.ts`, `src/lib/**` (código compartilhado) etc.
- `db` e o schema (`$lib/server/db/**`) são **server-only**.
- Qualquer acesso ao DB deve ficar em **`*.remote.ts` co-localizado com a rota**.
- Remote functions devem:
- Importar `query`, `command`, `form` de `$app/server`
- Validar input com `z` de `zod/v4`
- Usar Drizzle via `db` de `$lib/server/db` e tabelas de `$lib/server/db/schema`
- O frontend deve consumir **apenas** as remote functions, e usar:
- `$derived(remoteQuery(args))` para promessas reativas
- `.updates(remoteQuery(args))` após `command()`/`form()` para invalidar seletivamente
## Exemplo 1: Query (leitura) com Drizzle
```ts
// src/routes/admin/users/users.remote.ts
import { query } from '$app/server';
import z from 'zod/v4';
import { ilike, or } from 'drizzle-orm';
import { db } from '$lib/server/db';
import { user } from '$lib/server/db/schema';
export const listUsers = query(
z.object({
search: z.string().trim().min(1).optional()
}),
async ({ search }) => {
const where =
search
? or(ilike(user.name, `%${search}%`), ilike(user.email, `%${search}%`))
: undefined;
return await db
.select({
id: user.id,
name: user.name,
email: user.email,
createdAt: user.createdAt
})
.from(user)
.where(where);
}
);
```
## Exemplo 2: Command (mutação) com Drizzle + invalidação
```ts
// src/routes/admin/users/users.remote.ts
import { command } from '$app/server';
import z from 'zod/v4';
import { eq } from 'drizzle-orm';
import { db } from '$lib/server/db';
import { user } from '$lib/server/db/schema';
export const deleteUser = command(z.object({ id: z.string().min(1) }), async ({ id }) => {
await db.delete(user).where(eq(user.id, id));
// Se fizer sentido, você pode forçar refresh global da query para todos os clientes:
// await listUsers({ search: undefined }).refresh();
});
```
## Exemplo 3: Form (submit) com Drizzle
```ts
// src/routes/admin/users/users.remote.ts
import { form } from '$app/server';
import z from 'zod/v4';
import { eq } from 'drizzle-orm';
import { db } from '$lib/server/db';
import { user } from '$lib/server/db/schema';
export const updateUserName = form(
z.object({
id: z.string().min(1),
name: z.string().trim().min(2).max(100)
}),
async ({ id, name }) => {
await db.update(user).set({ name }).where(eq(user.id, id));
return { success: true as const };
}
);
```
## Exemplo 4: Frontend consumindo remote functions (sem acesso ao DB)
```svelte
<!-- src/routes/admin/users/+page.svelte -->
<script lang="ts">
import { listUsers, deleteUser, updateUserName } from './users.remote';
let search = $state('');
let usersPromise = $derived(listUsers({ search: search || undefined }));
</script>
<input bind:value={search} placeholder="Buscar por nome ou email" />
{#await usersPromise then users}
<ul>
{#each users as u}
<li>
<strong>{u.name}</strong> ({u.email})
<button
type="button"
onclick={async () => {
await deleteUser({ id: u.id }).updates(listUsers({ search: search || undefined }));
}}
>
Remover
</button>
</li>
{/each}
</ul>
{/await}
<form
{...updateUserName.enhance(async ({ submit }) => {
await submit().updates(listUsers({ search: search || undefined }));
})}
>
<!-- inputs do updateUserName.fields.* -->
<button type="submit">Salvar</button>
</form>
```
## Checklist rápido (antes de abrir PR)
- A leitura/escrita no DB está **somente** em `*.remote.ts`?
- O `.svelte` importa apenas remote functions (e não `db`/schema)?
- Inputs das remote functions estão validados com `zod/v4`?
- Mutação faz `.updates()` (ou `.refresh()` server-side) quando precisa atualizar listas?