Skip to Content

Adaptador SQL Server

O adapter SQL Server conecta o contrato de persistência do Jumentix à tecnologia SQL Server. Use cases continuam falando com portas de repositório; a escolha de banco fica na composição.

Tecnologia integrada

Microsoft SQL Server pelo perfil de cliente SQL

  • Modelo de dados: SQL relacional
  • Driver Jumentix: MSSQL
  • Seleção de runtime: JUMENTIX_DATABASE_DRIVER=MSSQL

Quando usar

Use quando: Ambientes enterprise padronizados em plataformas de dados Microsoft.

Quando evitar

Evite quando licenciamento, peso de container ou operação fora de Microsoft forem restrições.

Como validar localmente

Use o smoke test real do monorepo. Ele valida o ciclo de vida do adapter e evita publicar configuração que não conecta.

bun run docker:up:mssql JUMENTIX_DATABASE_DRIVER=MSSQL bun run smoke:db:mssql

Exemplo completo: Task e Category com porta de banco

type Category = {
  id: string;
  name: string;
};

type Task = {
  id: string;
  title: string;
  categoryId: string;
  completed: boolean;
};

type Repository<T extends { id: string }> = {
  create(record: T): Promise<T>;
  getById(id: string): Promise<T | undefined>;
  list(): Promise<T[]>;
};

function createRepository<T extends { id: string }>(): Repository<T> {
  const records = new Map<string, T>();

  return {
    async create(record) {
      records.set(record.id, record);
      return record;
    },
    async getById(id) {
      return records.get(id);
    },
    async list() {
      return [...records.values()];
    }
  };
}

const adapterProfile = {
  driver: 'MSSQL',
  dataModel: 'Relational SQL',
  smokeTest: 'bun run smoke:db:mssql'
} as const;

const categories = createRepository<Category>();
const tasks = createRepository<Task>();

export async function seedTaskCatalog() {
  const operations = await categories.create({ id: crypto.randomUUID(), name: 'Operations' });
  const finance = await categories.create({ id: crypto.randomUUID(), name: 'Finance' });

  await tasks.create({
    id: crypto.randomUUID(),
    title: 'Review adapter smoke test',
    categoryId: operations.id,
    completed: false
  });

  await tasks.create({
    id: crypto.randomUUID(),
    title: 'Close billing reconciliation',
    categoryId: finance.id,
    completed: true
  });

  return { adapterProfile, categories: await categories.list(), tasks: await tasks.list() };
}

export async function listTasksForCategory(categoryId: string): Promise<Task[]> {
  const category = await categories.getById(categoryId);

  if (!category) {
    throw new Error('Category not found');
  }

  return (await tasks.list()).filter((task) => task.categoryId === category.id);
}

O que trocar em produção

O exemplo acima mostra o contrato completo com uma implementação em memória para ser lido de ponta a ponta. Em produção, a composição injeta o cliente real selecionado por JUMENTIX_DATABASE_DRIVER=MSSQL; o domínio continua igual.