Monorepo full-stack com TypeScript para operação de redes de cinema, com arquitetura multi-tenant, API REST versionada, dashboard web e landing page.
Projeto acadêmico em equipe, desenvolvido para Banco de Dados na UNEB Campus 2. O repositório reúne uma API NestJS, aplicações Next.js e uma camada de dados PostgreSQL/Prisma em um monorepo TypeScript.
Para conhecer a implementação:
- Comece em
apps/api/src/modulespara os recursos de negócio e empackages/dbpara a modelagem de dados. - Consulte
apps/webeapps/adminpara os fluxos de interface. - Veja
apps/api/src/workerspara o processamento assíncrono de auditoria. - Use o Quick Start abaixo para preparar o ambiente e o histórico de commits para identificar as contribuições de cada integrante.
O escopo reúne módulos em diferentes estágios. Integrações externas e recursos planejados devem ser avaliados conforme as limitações documentadas; a presença de um módulo não comprova operação em produção.
- Visão Geral
- Arquitetura do Monorepo
- Stack Tecnológica
- Pré-requisitos
- Quick Start
- Scripts do Projeto
- Serviços e Portas
- Banco de Dados e Schemas
- Autenticação
- Multi-Tenancy
- Troubleshooting
- Documentação Complementar
- Contribuição
- Licença
O Frame-24 é um sistema para gestão integrada de operações de cinema, incluindo catálogo, sessões, vendas, fiscal, CRM e processos administrativos.
- Gestão de complexos, salas e assentos.
- Programação de sessões com validação de conflitos.
- Venda de ingressos e produtos de concessão.
- Módulos fiscal e financeiro com apurações e repasses.
- CRM com fidelidade e histórico de relacionamento.
- Base multi-tenant com isolamento de dados por empresa.
O repositório utiliza Turborepo + pnpm workspaces, organizado em apps e packages reutilizáveis.
| App | Descrição | Porta | Stack |
|---|---|---|---|
api |
Backend REST API versionada (/v1) com Swagger/Scalar |
4000 |
NestJS |
web |
Aplicação web principal para operações | 3000 |
Next.js + React |
admin |
Dashboard administrativo com componentes compartilhados | 3004 |
Next.js + React |
landing-page |
Site institucional e fluxo de aquisição | 3003 |
Next.js + React |
| Package | Responsabilidade |
|---|---|
@repo/db |
Prisma schema, migrations e client compartilhado |
@repo/ui |
Biblioteca de componentes UI reutilizáveis |
@repo/eslint-config |
Configurações de lint padronizadas |
@repo/tailwind-config |
Configurações compartilhadas de estilo |
@repo/typescript-config |
Bases TypeScript reutilizáveis |
- Node.js
>= 18 - TypeScript
6.0.2 - pnpm
10.33.0 - Turborepo
2.x
- NestJS
11 - Prisma ORM
- JWT para autenticação/autorização
- RabbitMQ para mensageria assíncrona
- Next.js
16 - React
19 - Tailwind CSS
4
- PostgreSQL
- RabbitMQ
- MinIO
- MailHog
| Ferramenta | Versão mínima |
|---|---|
| Node.js | >= 18 |
| pnpm | 10.33.0 |
| Docker / Docker Compose | latest |
| Git | latest |
Via npm:
npm install -g pnpm@10.33.0Via Homebrew (macOS/Linux):
brew install pnpmVia Chocolatey (Windows):
choco install pnpmVerificação:
pnpm --versiongit clone https://github.com/Lawtrel/frame-24.git
cd frame-24docker compose up -dEsse comando sobe PostgreSQL, Redis, RabbitMQ, MinIO e Mailpit. A API e os apps web rodam localmente com pnpm dev.
Para conferir:
docker compose psPara parar:
docker compose downcp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env
cp apps/admin/.env.example apps/admin/.env
cp apps/landing-page/.env.example apps/landing-page/.envOpcional para sobrescrever localmente sem versionar:
touch apps/web/.env.local
touch apps/admin/.env.localpnpm installcd packages/db
pnpm db:generate
pnpm db:migrate:dev
pnpm build
cd ../..Todos os serviços de desenvolvimento:
pnpm devApenas API:
pnpm dev:apiApenas aplicação web:
pnpm dev:webApenas dashboard admin:
pnpm dev:adminComandos na raiz:
pnpm dev
pnpm build
pnpm lint
pnpm check-types
pnpm formatExecução por app com Turbo:
turbo dev --filter=api
turbo dev --filter=web
turbo dev --filter=admin
turbo dev --filter=landing-pageComandos úteis de banco (em packages/db):
pnpm db:generate
pnpm db:migrate:dev --name nome-da-migration
pnpm db:studio
pnpm db:reset| Serviço | URL | Credenciais |
|---|---|---|
| API (Swagger) | http://localhost:4000/api/docs | - |
| Web App | http://localhost:3000 | - |
| Admin App | http://localhost:3004 | - |
| Landing Page | http://localhost:3003 | - |
| RabbitMQ Management | http://localhost:15672 | frame24 / frame24pass |
| MailHog | http://localhost:8025 | - |
Se alguma porta estiver em uso, sobrescreva ao subir:
POSTGRES_HOST_PORT=15432 \
REDIS_HOST_PORT=16379 \
RABBITMQ_HOST_PORT=15673 \
RABBITMQ_UI_HOST_PORT=15674 \
MINIO_HOST_PORT=19000 \
MINIO_CONSOLE_HOST_PORT=19001 \
MAILPIT_SMTP_HOST_PORT=11025 \
MAILPIT_UI_HOST_PORT=18025 \
docker compose up -dPrisma Studio:
cd packages/db
pnpm db:studioO sistema usa modelagem multi-schema com isolamento por domínio.
Schemas principais:
identity(usuários, empresas, autenticação, permissões)hr(recursos humanos)finance(contabilidade e lançamentos)crm(clientes e fidelidade)sales(ingressos, concessão e transações)inventory(fornecedores, produtos, estoque)marketing(campanhas, cupons, descontos)operations(complexos, salas, sessões, assentos)projects(projetos RECINE)stock(movimentação de estoque)tax(tributos e apurações fiscais)catalog(filmes, produtos, combos)contracts(contratos com distribuidoras)
Contrato de autenticação (padrão do projeto):
- Cadastro admin legado:
POST /v1/auth/register - Cadastro cliente legado:
POST /v1/customer/auth/register - Login/cadastro oficial: Better Auth em
/api/auth/*(email/senha, sessão e recuperação de sessão). - Endpoints legados de login (
/v1/auth/logine/v1/customer/auth/login) foram removidos.
Headers aceitos na API:
Authorization: Bearer <access-token>Variáveis principais da API:
JWT_SECRET=change-me-to-a-long-random-secret
JWT_AUDIENCE=frame24-api
JWT_ISSUER=frame24-api
JWT_EXPIRES_IN=8h
BETTER_AUTH_SECRET=change-me-to-a-long-random-secret
BETTER_AUTH_SECRETS=change-me-old-secret,change-me-new-secret
BETTER_AUTH_URL=http://localhost:4000Arquitetura multi-tenant com separação lógica de dados por empresa:
- Cada empresa possui
tenant_slugúnico. - Requisições são filtradas por
company_iddo usuário autenticado. - Controle de acesso por papéis e permissões granulares.
- Isolamento de dados entre tenants.
Há arquivos versionados com sufixo :Zone.Identifier dentro de mlops_project-main, que podem impedir o checkout em sistemas de arquivos Windows. A limpeza desses metadados é uma pendência de portabilidade; enquanto ela não for concluída, um checkout em sistema de arquivos Linux evita essa restrição de nomes.
docker compose psSe necessário, ajuste portas no docker-compose.yaml e arquivos .env.
docker compose ps postgres
docker compose restart postgresdocker compose ps rabbitmq
docker compose logs -f rabbitmqcd packages/db
pnpm db:generate
pnpm builddockerfile: imagem de produção da API (apps/api) com build NestJS.scripts/docker/api-entrypoint.sh: aplicaprisma migrate deployantes de iniciar a API.docker-compose.coolify.yml: stack de produção comapi+postgres+minio..env.coolify.example: template de variáveis para produção.
cp .env.coolify.example .env.coolify
# ajuste os secrets e domínios no arquivo .env.coolify
docker compose --env-file .env.coolify -f docker-compose.coolify.yml up -d --buildPortas publicadas no host podem ser ajustadas no .env.coolify:
API_HOST_PORT(default:4000)POSTGRES_HOST_PORT(default:5432)MINIO_HOST_PORT(default:9000)MINIO_CONSOLE_HOST_PORT(default:9001)
Topologia de produção recomendada:
- Coolify/VPS:
api+postgres+minio. - Redis: serviço externo gerenciado.
- RabbitMQ: serviço externo gerenciado.
- Frontends (
web,admin,landing-page): hospedados na Vercel.
Atualização após novo push no main:
git pull origin main
docker compose --env-file .env.coolify -f docker-compose.coolify.yml pull api postgres minio
docker compose --env-file .env.coolify -f docker-compose.coolify.yml up -d --remove-orphansO workflow .github/workflows/deploy.yml publica a imagem em ghcr.io/<owner>/frame-24-api e suporta dois modos:
- Coolify por webhook (
COOLIFY_DEPLOY_WEBHOOK_URL). - VPS por SSH + Docker Compose (
VPS_HOST,VPS_USER,VPS_SSH_KEY,GHCR_USERNAME,GHCR_TOKEN).
No modo VPS, o limite de 1GB fica definido diretamente no docker-compose.coolify.yml via limites de memória dos serviços, distribuido entre api + postgres + minio.
Secrets recomendados no GitHub:
COOLIFY_DEPLOY_WEBHOOK_URL(opcional, para deploy automático no Coolify)VPS_HOSTVPS_USERVPS_SSH_KEYGHCR_USERNAMEGHCR_TOKEN(PAT comread:packages)N8N_WEBHOOK_URL(opcional para notificação de falha)
No mínimo:
JWT_SECRETBETTER_AUTH_SECRETBETTER_AUTH_URLouAPI_URLDATABASE_URLDIRECT_URLFRONTEND_URL(domínios Vercel permitidos por CORS, separados por vírgula)REDIS_URL+REDIS_HOST+REDIS_PORT(externos)RABBITMQ_URI+RABBITMQ_HOST+RABBITMQ_PORT+RABBITMQ_USER+RABBITMQ_PASSWORD(externos)MINIO_ACCESS_KEY+MINIO_SECRET_KEY+ (STORAGE_PUBLIC_URLouMINIO_PUBLIC_URL) (MinIO no VPS)
Em produção, use secrets fortes (>= 32 caracteres para JWT_SECRET e BETTER_AUTH_SECRET).
A fase atual fecha somente quando não houver brecha crítica conhecida, os riscos médios mais perigosos tiverem owner funcional, a documentação OpenAPI refletir o comportamento real, e os fluxos críticos tiverem testes e observabilidade mínima.
Status de fechamento:
| Área | Owner funcional | Status |
|---|---|---|
| Identity/Auth/CRM/Public | Backend/API Security + Privacy/Compliance | Segredo interno obrigatório, throttling, payload público mínimo e validação de tenant endereçados. Direitos do titular, retenção e descarte seguem como plano de compliance, sem implementação completa nesta fase. |
| Sales/Public/Operations | Backend/Sales + Infra/Ops | Idempotência pública, seat locking forte, cancelamento por regra temporal e throttling endereçados. Fluxos críticos precisam permanecer cobertos por testes focados. |
| Finance/Payments | Finance/Payments | Fora da fase atual: PIX real, webhook PSP, ledger interno, refund e chargeback não devem ser declarados como corrigidos. |
| Tax/Fiscal/Catalog/Stock/Contracts | Fiscal/Tax + Backend | Validação de tenant em filtros e coerência de contratos/fiscal endereçadas. Pipeline de atualização normativa e revisão fiscal completa seguem como plano fiscal. |
| Storage/Email/Audit/Workers | Infra/Ops + Privacy/Compliance | Auditoria com retry e DLQ endereçada. Storage por prefixo/contexto, redaction de logs e alarmes operacionais seguem como plano de observabilidade/incidente. |
| Marketing/Recommendations | Backend/Sales + Privacy/Compliance | Finalização de campanha/cupom sob lock transacional endereçada. Separação completa entre dados operacionais e promocionais segue como plano de privacidade. |
API_ENDPOINTS.mdQUICK_START.mdFRONTEND_DEVELOPMENT.mdFRONTEND_FILES_SUMMARY.mdFRONTEND_FINAL_SUMMARY.md
- Crie uma branch para sua feature ou correção.
- Faça commits pequenos e descritivos.
- Rode lint e checagem de tipos antes de abrir PR.
- Abra um Pull Request com contexto técnico claro.
Fluxo sugerido:
git checkout -b feature/nova-feature
git commit -m "feat: adiciona nova feature"
git push origin feature/nova-featureProjeto privado sob licença UNLICENSED.
Desenvolvido para o projeto de Banco de Dados da UNEB Campus 2.