@delivery-db-shared/core
v0.1.5
Published
Shared database layer with Prisma for delivery system
Maintainers
Readme
🗂️ @delivery-db-shared/core
Shared database layer with Prisma for delivery/stock management system.
⚠️ Security Notice: This package is currently published as public for demonstration purposes. For production use, republish as restricted (
--access=restricted) and use NPM tokens for authentication. See SECURITY-TOKENS.md for details.
📋 Quick Start Guide
Prerequisites
- Node.js >= 18
- Docker & Docker Compose
- npm account with access to @delivery scope
Local Development Setup
# 1. Clone the repository
git clone https://github.com/luisrca-tech/delivery-db-shared.git
cd delivery-db-shared
# 2. Install dependencies
npm install
# 3. Copy environment variables
cp .env.example .env
# 4. Start MySQL with Docker
docker compose up -d
# 5. Run migrations
npm run migrate:dev
# 6. Generate Prisma Client
npm run generate
# 7. (Optional) Open Prisma Studio
npm run studioAvailable Commands
| Command | Description |
|---------|-------------|
| npm run build | Build the package (ESM + CJS) |
| npm run generate | Generate Prisma Client |
| npm run migrate:dev | Create and apply migrations (dev) |
| npm run migrate:deploy | Apply migrations (production) |
| npm run studio | Open Prisma Studio (DB GUI) |
Usage in Other Projects
# Install the package
npm install @delivery-db-shared/core// Import and use
import { prisma } from '@delivery-db-shared/core';
const users = await prisma.user.findMany();
console.log(users);Troubleshooting
Docker não está rodando?
# Verifique se o Docker Desktop está aberto
docker ps
# Se não estiver, abra o Docker Desktop e rode:
docker compose up -dErro de permissão no shadow database?
# Execute este comando uma vez:
docker exec delivery_db mysql -u root -proot -e "GRANT ALL PRIVILEGES ON \`prisma_migrate_shadow_db_%\`.* TO 'delivery'@'%'; FLUSH PRIVILEGES;"Erro ao conectar no banco?
# Verifique se o container está rodando
docker ps | grep delivery_db
# Verifique as variáveis de ambiente
cat .env⚖️ Comparativo de Publicação (Resumo)
| Critério | npmjs.com (Private Scoped Package) | GitHub Packages (npm.pkg.github.com) |
|-----------|--------------------------------------|--------------------------------------------|
| URL do Registry | https://registry.npmjs.org/ | https://npm.pkg.github.com/ |
| Controle de acesso | Tokens de leitura/publicação do npm | Permissões herdadas do GitHub repo |
| Distribuição | Instalação via token (.npmrc) | Instalação automática entre repos da org |
| CI/CD | Simples, usa NPM_TOKEN | Requer GITHUB_TOKEN com read:packages |
| Performance | CDN global da npm (rápido) | CDN menor (GitHub) |
| Casos ideais | Multi-projetos independentes | Projetos internos da org GitHub |
💡 Decisão: usar npmjs.com (Private Scoped Package) por ser mais flexível para microserviços e múltiplos consumidores independentes.
📚 Referências e Documentação
Documentação essencial para consulta durante a implementação:
Prisma
- Prisma Documentation - Documentação oficial completa
- Prisma Schema Reference - Sintaxe e tipos do schema
- Prisma MySQL Connector - Específico para MySQL
- Prisma Best Practices - Connection pooling e otimização
- Prisma Migrations - Sistema de migrações
MySQL
- MySQL 8.0 Reference - Documentação oficial do MySQL
- MySQL Data Types - Tipos de dados disponíveis
- MySQL Indexes - Otimização com índices
NPM & TypeScript
- NPM Private Packages - Guia de pacotes privados
- Publishing Scoped Packages - Publicação de pacotes com scope
- tsup Documentation - Bundler TypeScript zero-config
- TypeScript Handbook - Guia completo de TypeScript
Tooling
- ESLint Getting Started - Setup de linting
- Prettier Documentation - Formatação de código
- Husky Documentation - Git hooks automation
🚀 Phase 1 — Foundation Setup
Objetivo: criar o repositório base com Prisma + MySQL + estrutura de export do client.
Checklist
- [x] Criar repositório
@delivery/db-sharedno GitHub - [x] Inicializar projeto Node + TypeScript:
npm init -y npm install prisma @prisma/client --save npm install typescript tsup @types/node --save-dev npx prisma init - [x] Configurar
package.jsonbásico:{ "name": "@delivery/db-shared", "version": "0.1.0", "description": "Shared database layer with Prisma for delivery system", "main": "dist/index.js", "types": "dist/index.d.ts", "files": ["dist", "prisma"], "scripts": { "build": "tsup src/index.ts --dts --format esm,cjs", "generate": "prisma generate", "migrate:dev": "prisma migrate dev", "migrate:deploy": "prisma migrate deploy", "studio": "prisma studio", "prepublishOnly": "npm run build && npm run generate" }, "engines": { "node": ">=18" } } - [x] Configurar
tsconfig.json:{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "lib": ["ES2020"], "declaration": true, "outDir": "dist", "rootDir": "src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "moduleResolution": "node" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } - [x] Configurar
prisma/schema.prismacom tabelaUserinicial:generator client { provider = "prisma-client-js" output = "../node_modules/.prisma/client" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) name String @db.VarChar(255) email String @unique @db.VarChar(255) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@map("users") } - [x] Criar
src/index.tscom Prisma singleton pattern:import { PrismaClient } from '@prisma/client'; const globalForPrisma = global as unknown as { prisma: PrismaClient | undefined; }; export const prisma = globalForPrisma.prisma ?? new PrismaClient({ log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'], }); if (process.env.NODE_ENV !== 'production') { globalForPrisma.prisma = prisma; } // Export Prisma types for consumers export * from '@prisma/client'; - [x] Configurar ESLint:
Criarnpm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev.eslintrc.json:{ "parser": "@typescript-eslint/parser", "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ], "parserOptions": { "ecmaVersion": 2020, "sourceType": "module" }, "rules": { "@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/no-explicit-any": "warn" } } - [x] Configurar Prettier:
Criarnpm install prettier eslint-config-prettier --save-dev.prettierrc:{ "semi": true, "trailingComma": "es5", "singleQuote": true, "printWidth": 80, "tabWidth": 2 } - [x] Configurar Husky e lint-staged:
Criarnpm install husky lint-staged --save-dev npx husky init.husky/pre-commit:
Adicionar no#!/bin/sh npx lint-stagedpackage.json:"lint-staged": { "*.ts": ["eslint --fix", "prettier --write"] } - [x] Criar
.gitignore:node_modules/ dist/ .env .env.local *.log .DS_Store .vscode/ .idea/ - [x] Rodar primeira migração local:
npx prisma migrate dev --name init_user_table
🐳 Phase 2 — Docker Development Setup
Objetivo: padronizar ambiente local e facilitar onboarding de novos devs.
Checklist
[x] Criar
docker-compose.yml:version: '3.8' services: db: image: mysql:8.0 container_name: delivery_db restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: delivery MYSQL_USER: delivery MYSQL_PASSWORD: delivery ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql command: --default-authentication-plugin=mysql_native_password healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10 volumes: mysql_data: driver: local[x] Criar
.env.example:# Database DATABASE_URL="mysql://delivery:delivery@localhost:3306/delivery" # Node NODE_ENV="development"[x] Criar
.envlocal (não commitado):cp .env.example .env[x] Criar
README.mdcom instruções de setup:# @delivery/db-shared Shared database layer with Prisma for delivery/stock management system. ## Prerequisites - Node.js >= 18 - Docker & Docker Compose - npm account with access to @delivery scope ## Local Development Setup 1. Clone the repository 2. Install dependencies: `npm install` 3. Copy environment variables: `cp .env.example .env` 4. Start MySQL: `docker compose up -d db` 5. Run migrations: `npm run migrate:dev` 6. Generate Prisma Client: `npm run generate` ## Commands - `npm run build` - Build the package - `npm run generate` - Generate Prisma Client - `npm run migrate:dev` - Create and apply migrations - `npm run migrate:deploy` - Apply migrations in production - `npm run studio` - Open Prisma Studio (DB GUI) ## Usage in other projects ```bash npm install @delivery/db-sharedimport { prisma } from '@delivery/db-shared'; const users = await prisma.user.findMany();[x] Testar ambiente local:
docker compose up -d npm run migrate:dev npm run studio[x] Documentar troubleshooting comum no README
🔒 Phase 3 — Private NPM Publish & Integration
Objetivo: publicar o pacote protegido e testá-lo em outro projeto consumidor.
Checklist
- [x] Criar conta/org no npm:
@delivery-db-shared# Via web: https://www.npmjs.com/org/create # Ou via CLI: npm org create delivery - [x] Validar
package.jsonpara publicação:{ "name": "@delivery/db-shared", "version": "0.1.0", "description": "Shared database layer with Prisma for delivery system", "main": "dist/index.js", "types": "dist/index.d.ts", "files": ["dist", "prisma", "README.md"], "keywords": ["prisma", "mysql", "delivery", "database"], "author": "Your Name", "license": "UNLICENSED", "repository": { "type": "git", "url": "https://github.com/your-org/delivery-db-shared" }, "publishConfig": { "access": "restricted", "registry": "https://registry.npmjs.org/" }, "peerDependencies": { "@prisma/client": "^5.0.0" } } - [x] Login no npm:
npm login # Enter credentials - [x] Build e validação antes de publicar:
npm run build npm pack --dry-run - [x] Publicar primeira versão (v0.1.0, v0.1.1, v0.1.2):
npm publish --access=public - [x] Criar token de leitura para CI/CD e outros projetos:
npm token create --read-only # Save token securely - [x] Documentar instalação em projeto consumidor:
- Criar
.npmrcno projeto:@delivery:registry=https://registry.npmjs.org/ //registry.npmjs.org/:_authToken=${NPM_TOKEN} - Instalar:
npm install @delivery-db-shared/core
- Criar
- [x] Criar projeto de teste simples:
Criarmkdir test-consumer cd test-consumer npm init -y npm install @delivery-db-shared/coretest-delivery-db.js:const { prisma } = require('@delivery-db-shared/core'); async function main() { const users = await prisma.user.findMany(); console.log('Users:', users); } main() .catch(console.error) .finally(() => prisma.$disconnect()); - [x] Validar que o pacote funciona no projeto consumidor (testado em
test-delivery-consumerestock-hono-api) - [x] Documentar processo de atualização de versão (ver
documentation/Guides/NPM-UPDATE-WORKFLOW.md)
⚙️ Phase 4 — GitHub CI/CD Workflow
Objetivo: automatizar build, testes e publicação.
Checklist
- [ ] Criar
.github/workflows/ci.ymlpara validação:name: CI on: push: branches: [main, develop] pull_request: branches: [main, develop] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npx eslint src/ - run: npx prettier --check src/ build: runs-on: ubuntu-latest needs: lint steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npm run generate - run: npm run build - name: Upload build artifacts uses: actions/upload-artifact@v3 with: name: dist path: dist/ - [ ] Criar
.github/workflows/publish.ymlpara publicação:name: Publish Package on: push: tags: - 'v*.*.*' jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 registry-url: https://registry.npmjs.org/ - name: Install dependencies run: npm ci - name: Generate Prisma Client run: npm run generate - name: Build package run: npm run build - name: Publish to npm run: npm publish --access=restricted env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Create GitHub Release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} draft: false prerelease: false - [ ] Adicionar
NPM_TOKENem GitHub Secrets:- Ir em Settings > Secrets > Actions
- New repository secret:
NPM_TOKEN - Valor: token criado na Phase 3
- [ ] Criar
.github/workflows/migrations.ymlpara validar migrations:name: Validate Migrations on: pull_request: paths: - 'prisma/**' jobs: validate: runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: test_delivery ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - name: Run migrations run: npx prisma migrate deploy env: DATABASE_URL: mysql://root:root@localhost:3306/test_delivery - [ ] Testar workflow criando uma tag:
git tag v0.1.0 git push origin v0.1.0 - [ ] Documentar processo de release no README
🗄️ Phase 5 — Database Schema Design (Delivery/Stock System)
Objetivo: planejar e implementar schema completo para sistema de delivery e gestão de estoque.
Schema Overview
Sistema completo para gerenciar:
- Usuários e permissões
- Fornecedores
- Produtos e estoque
- Movimentações de entrada/saída
- Pedidos de delivery
- Histórico completo de transações
Checklist
[ ] Criar model
Usercompleto com roles:enum UserRole { ADMIN OPERATOR VIEWER } model User { id Int @id @default(autoincrement()) name String @db.VarChar(255) email String @unique @db.VarChar(255) role UserRole @default(VIEWER) active Boolean @default(true) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") // Relations stockMovementsCreated StockMovement[] ordersCreated Order[] @@map("users") @@index([email]) @@index([active]) }[ ] Criar model
Supplier:model Supplier { id Int @id @default(autoincrement()) name String @db.VarChar(255) tradeName String? @map("trade_name") @db.VarChar(255) document String @unique @db.VarChar(20) // CNPJ/CPF email String? @db.VarChar(255) phone String? @db.VarChar(20) address String? @db.Text city String? @db.VarChar(100) state String? @db.VarChar(2) zipCode String? @map("zip_code") @db.VarChar(10) active Boolean @default(true) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") // Relations products Product[] @@map("suppliers") @@index([document]) @@index([active]) }[ ] Criar model
Product:model Product { id Int @id @default(autoincrement()) sku String @unique @db.VarChar(50) name String @db.VarChar(255) description String? @db.Text supplierId Int @map("supplier_id") category String? @db.VarChar(100) unit String @db.VarChar(20) // kg, un, lt, etc minStock Decimal @default(0) @map("min_stock") @db.Decimal(10, 2) active Boolean @default(true) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") // Relations supplier Supplier @relation(fields: [supplierId], references: [id]) stock Stock? stockMovements StockMovement[] orderItems OrderItem[] @@map("products") @@index([sku]) @@index([supplierId]) @@index([active]) @@index([category]) }[ ] Criar model
Stock:model Stock { id Int @id @default(autoincrement()) productId Int @unique @map("product_id") quantity Decimal @default(0) @db.Decimal(10, 2) reservedQty Decimal @default(0) @map("reserved_qty") @db.Decimal(10, 2) availableQty Decimal @default(0) @map("available_qty") @db.Decimal(10, 2) lastEntry DateTime? @map("last_entry") lastExit DateTime? @map("last_exit") updatedAt DateTime @updatedAt @map("updated_at") // Relations product Product @relation(fields: [productId], references: [id]) @@map("stock") @@index([productId]) }[ ] Criar model
StockMovement:enum MovementType { ENTRY EXIT ADJUSTMENT RETURN } model StockMovement { id Int @id @default(autoincrement()) productId Int @map("product_id") type MovementType quantity Decimal @db.Decimal(10, 2) reason String? @db.Text referenceId Int? @map("reference_id") // ID do pedido, se aplicável createdBy Int @map("created_by") createdAt DateTime @default(now()) @map("created_at") // Relations product Product @relation(fields: [productId], references: [id]) creator User @relation(fields: [createdBy], references: [id]) @@map("stock_movements") @@index([productId]) @@index([type]) @@index([createdAt]) @@index([referenceId]) }[ ] Criar model
Order(Delivery):enum OrderStatus { PENDING CONFIRMED PREPARING IN_TRANSIT DELIVERED CANCELLED } model Order { id Int @id @default(autoincrement()) orderNumber String @unique @map("order_number") @db.VarChar(50) customerName String @map("customer_name") @db.VarChar(255) customerEmail String? @map("customer_email") @db.VarChar(255) customerPhone String @map("customer_phone") @db.VarChar(20) deliveryAddress String @map("delivery_address") @db.Text deliveryCity String @map("delivery_city") @db.VarChar(100) deliveryState String @map("delivery_state") @db.VarChar(2) deliveryZipCode String @map("delivery_zip_code") @db.VarChar(10) status OrderStatus @default(PENDING) totalAmount Decimal @map("total_amount") @db.Decimal(10, 2) notes String? @db.Text createdBy Int @map("created_by") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") deliveredAt DateTime? @map("delivered_at") // Relations items OrderItem[] creator User @relation(fields: [createdBy], references: [id]) @@map("orders") @@index([orderNumber]) @@index([status]) @@index([createdAt]) @@index([customerEmail]) }[ ] Criar model
OrderItem:model OrderItem { id Int @id @default(autoincrement()) orderId Int @map("order_id") productId Int @map("product_id") quantity Decimal @db.Decimal(10, 2) unitPrice Decimal @map("unit_price") @db.Decimal(10, 2) subtotal Decimal @db.Decimal(10, 2) // Relations order Order @relation(fields: [orderId], references: [id]) product Product @relation(fields: [productId], references: [id]) @@map("order_items") @@index([orderId]) @@index([productId]) }[ ] Criar migration para todas as tabelas:
npx prisma migrate dev --name add_complete_delivery_schema[ ] Atualizar
src/index.tspara exportar enums:export { prisma, UserRole, MovementType, OrderStatus, Prisma } from '@prisma/client'; export type * from '@prisma/client';[ ] Documentar relacionamentos no README:
- Criar diagrama de entidades (Entity Relationship Diagram)
- Explicar fluxos principais (entrada de estoque, pedido, baixa)
Entity Relationship Diagram
┌─────────────┐
│ User │
│ (ADMIN, │
│ OPERATOR, │
│ VIEWER) │
└──────┬──────┘
│ created_by
│
├─────────────────┐
│ │
┌──────▼────────┐ ┌──────▼───────────┐
│ Order │ │ StockMovement │
│ (Delivery) │ │ (ENTRY/EXIT/ │
│ │ │ ADJUSTMENT) │
└──────┬────────┘ └──────┬───────────┘
│ │
│ items │ product_id
│ │
┌──────▼────────┐ ┌──────▼───────────┐
│ OrderItem ├─┤ Product │
└───────────────┘ │ (SKU, name) │
└──────┬───────────┘
│
┌──────▼───────────┐
│ Stock │
│ (quantity, │
│ available) │
└──────────────────┘
│
┌──────▼───────────┐
│ Supplier │
│ (CNPJ, name) │
└──────────────────┘🧪 Phase 6 — Testing, Seeds & Validation
Objetivo: garantir qualidade e facilitar desenvolvimento com dados de teste.
Checklist
[ ] Criar seed script
prisma/seed.ts:import { PrismaClient, UserRole, MovementType, OrderStatus } from '@prisma/client'; const prisma = new PrismaClient(); async function main() { console.log('🌱 Starting seed...'); // Clear existing data (dev only) await prisma.orderItem.deleteMany(); await prisma.order.deleteMany(); await prisma.stockMovement.deleteMany(); await prisma.stock.deleteMany(); await prisma.product.deleteMany(); await prisma.supplier.deleteMany(); await prisma.user.deleteMany(); // Create users const admin = await prisma.user.create({ data: { name: 'Admin User', email: '[email protected]', role: UserRole.ADMIN, }, }); const operator = await prisma.user.create({ data: { name: 'Operator User', email: '[email protected]', role: UserRole.OPERATOR, }, }); console.log('✅ Users created'); // Create suppliers const supplier1 = await prisma.supplier.create({ data: { name: 'Distribuidora ABC Ltda', tradeName: 'ABC Distribuição', document: '12.345.678/0001-90', email: '[email protected]', phone: '(11) 98765-4321', city: 'São Paulo', state: 'SP', zipCode: '01234-567', }, }); console.log('✅ Suppliers created'); // Create products const product1 = await prisma.product.create({ data: { sku: 'PROD-001', name: 'Arroz Branco 5kg', category: 'Alimentos', unit: 'un', minStock: 10, supplierId: supplier1.id, }, }); const product2 = await prisma.product.create({ data: { sku: 'PROD-002', name: 'Feijão Preto 1kg', category: 'Alimentos', unit: 'un', minStock: 20, supplierId: supplier1.id, }, }); console.log('✅ Products created'); // Create stock await prisma.stock.create({ data: { productId: product1.id, quantity: 100, availableQty: 100, reservedQty: 0, }, }); await prisma.stock.create({ data: { productId: product2.id, quantity: 150, availableQty: 150, reservedQty: 0, }, }); console.log('✅ Stock created'); // Create stock movements await prisma.stockMovement.create({ data: { productId: product1.id, type: MovementType.ENTRY, quantity: 100, reason: 'Initial stock', createdBy: admin.id, }, }); console.log('✅ Stock movements created'); // Create order const order = await prisma.order.create({ data: { orderNumber: 'ORD-2025-0001', customerName: 'João Silva', customerEmail: '[email protected]', customerPhone: '(11) 91234-5678', deliveryAddress: 'Rua das Flores, 123', deliveryCity: 'São Paulo', deliveryState: 'SP', deliveryZipCode: '01234-567', status: OrderStatus.PENDING, totalAmount: 75.00, createdBy: operator.id, items: { create: [ { productId: product1.id, quantity: 2, unitPrice: 25.00, subtotal: 50.00, }, { productId: product2.id, quantity: 5, unitPrice: 5.00, subtotal: 25.00, }, ], }, }, }); console.log('✅ Orders created'); console.log('🌱 Seed completed successfully!'); } main() .catch((e) => { console.error('❌ Seed failed:', e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });[ ] Adicionar script no
package.json:"prisma": { "seed": "tsx prisma/seed.ts" }, "scripts": { "seed": "tsx prisma/seed.ts" }[ ] Instalar dependência para seed:
npm install tsx --save-dev[ ] Rodar seed:
npm run seed[ ] Criar script de backup
scripts/backup.sh:#!/bin/bash # Database backup script TIMESTAMP=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="backups" BACKUP_FILE="$BACKUP_DIR/delivery_backup_$TIMESTAMP.sql" mkdir -p $BACKUP_DIR echo "Creating backup: $BACKUP_FILE" docker exec delivery_db mysqldump \ -u delivery \ -pdelivery \ delivery > $BACKUP_FILE echo "Backup completed: $BACKUP_FILE" # Keep only last 7 backups ls -t $BACKUP_DIR/delivery_backup_*.sql | tail -n +8 | xargs -r rm echo "Old backups cleaned"[ ] Criar script de restore
scripts/restore.sh:#!/bin/bash # Database restore script if [ -z "$1" ]; then echo "Usage: ./scripts/restore.sh <backup_file>" exit 1 fi BACKUP_FILE=$1 if [ ! -f "$BACKUP_FILE" ]; then echo "Error: Backup file not found: $BACKUP_FILE" exit 1 fi echo "Restoring from: $BACKUP_FILE" docker exec -i delivery_db mysql \ -u delivery \ -pdelivery \ delivery < $BACKUP_FILE echo "Restore completed"[ ] Documentar estratégia de testes no README:
- Testes de migration em CI
- Seed para desenvolvimento local
- Backup e restore para produção
[ ] Criar guia de troubleshooting no README:
- Problemas comuns de connection pool
- Erros de migration
- Como reverter migrations
🏗️ Arquitetura do Sistema
┌─────────────────────────────────────────────────────────┐
│ @delivery/db-shared │
│ (Prisma Client + MySQL Schema) │
│ Users | Suppliers | Products | Stock | Orders │
└────────────────────┬────────────────────────────────────┘
│
npm private registry
(npmjs.com/@delivery)
│
┌────────────┴────────────┐
│ │
┌───────▼────────┐ ┌─────────▼─────────┐
│ API Service │ │ Frontend App │
│ (Hono.js) │◄─────┤ (Next.js/React) │
│ │ │ │
│ - Auth │ │ - Dashboard │
│ - Stock CRUD │ │ - Stock Mgmt │
│ - Orders API │ │ - Orders UI │
│ - Reports │ │ - Reports │
└────────────────┘ └───────────────────┘
│
│ import { prisma }
│ from '@delivery/db-shared'
│
┌───────▼────────────────────────────────────┐
│ MySQL Database (Docker) │
│ Tables: users, suppliers, products, │
│ stock, stock_movements, orders │
└────────────────────────────────────────────┘Fluxo de Dados Principal
Entry Flow (Entrada de Estoque):
- Operator registra entrada de produtos
- StockMovement (ENTRY) é criado
- Stock.quantity é atualizado
- Stock.lastEntry é atualizado
Order Flow (Pedido de Delivery):
- Operator cria Order com OrderItems
- Stock.reservedQty é incrementado
- Stock.availableQty = quantity - reservedQty
- Order.status: PENDING → CONFIRMED → PREPARING → IN_TRANSIT → DELIVERED
- Ao confirmar entrega: StockMovement (EXIT) é criado
Stock Alert Flow:
- Sistema monitora Stock.availableQty
- Se availableQty < Product.minStock: alerta é gerado
- Notification para admin/operator
📦 Final Summary
| Item | Decisão |
|------|----------|
| Package Name | @delivery/db-shared |
| Registry | npmjs.com (private, scoped) |
| Database | MySQL 8.0 (Docker local) |
| ORM | Prisma |
| Auth/Security | NPM restricted tokens |
| CI/CD | GitHub Actions (lint, build, publish on tag) |
| Export Pattern | Prisma singleton + types |
| Code Quality | ESLint + Prettier + Husky |
| Testing | Seed scripts + migration validation |
| Status Atual | 🚧 Em planejamento - repo vazio |
🎯 Next Phases (Future Roadmap)
Phase 7 — API Microservice (Hono + Node.js)
- Criar
@delivery/apicom Hono.js - Implementar CRUD para todas entidades
- Auth com JWT
- Validação com Zod
- Rate limiting e security headers
- OpenAPI/Swagger documentation
Phase 8 — Frontend Application (Next.js/React)
- Criar
@delivery/frontendcom Next.js 14+ - Dashboard com métricas de estoque
- Interface de gestão de produtos
- Sistema de pedidos
- Relatórios e gráficos
- Autenticação e autorização
Phase 9 — Monitoring & Observability
- Logs estruturados
- Métricas de performance
- Alertas de estoque baixo
- Dashboard de saúde do sistema
📚 Additional Resources
Best Practices
- Prisma Production Checklist - Guia para produção
- MySQL Performance Tuning - Otimização de queries
- Semantic Versioning - Versionamento de pacotes
- Conventional Commits - Padrão de commits
Tools
- Prisma Studio - GUI para database
- MySQL Workbench - Client visual para MySQL
- Postman - Testar API (fase 7)
🤝 Contributing
Este é um repositório de infraestrutura compartilhada. Mudanças no schema devem ser:
- Discutidas em issue antes de implementar
- Testadas localmente com migrations
- Documentadas no CHANGELOG
- Versionadas seguindo semver (breaking changes = major version)
📝 License
UNLICENSED - Proprietary software for internal use only.
