--- name: Projeto QFila description: Sistema SaaS de filas digitais — 2 apps Flutter (Gestor + Cliente), backend CodeIgniter 4 em qfila.com.br, multi-tenant type: project originSessionId: d63a7891-0622-4f67-8342-41e4ba10ac6e --- QFila — sistema de filas inteligentes e organização para clínicas, barbearias, restaurantes, etc. Multi-tenant: cada estabelecimento isolado por `establishment_id`. **Dois comércios diferentes nunca se cruzam.** ## Estrutura dos apps - **QFila Gestor** — `D:\xampp\htdocs\PROJETOS FLUTTER\QFila` - Package `com.qfila.qfila` | label "QFila Gestor" - ~14 telas: dashboard, gestão de filas, relatórios, usuários internos - Integrado com API real (AuthProvider, QueueProvider, EstablishmentProvider, UsersProvider) - **QFila Cliente** — `D:\xampp\htdocs\PROJETOS FLUTTER\QFilaCliente` - Package `com.qfila.qfila_cliente` | label "QFila" - App dedicado a 1 estabelecimento (sem busca/marketplace) - Login persistente (SharedPreferences), notificações locais (`flutter_local_notifications`), Lottie integrado, simulação de fila em tempo real (demo) - Ainda 100% mockado — **NÃO integrado com API** - APKs: `C:\Users\Jesiel\Desktop\APP - QFila\` - Logo oficial: `C:\Users\Jesiel\Desktop\APP - QFila\Design sem nome.png` (também copiada em `QFila\assets\images\logo.png`) - QR demo (2026-04-17): `C:\Users\Jesiel\Desktop\QFila-QRCode-QFILA01.png` → `https://qfila.com.br/e/QFILA01` ## Identidade visual - Cores da marca: Azul `#1B5E8A`, Laranja `#F5921B`, Verde `#7CB342` - Splash: fundo branco, logo grande centralizada - Bottom nav: estilo app de banco, ícones grandes - Cada estabelecimento terá seu PRÓPRIO app do cliente (não é marketplace) ## Hospedagem - Domínio: `qfila.com.br` (aliases: `www.qfila.com.br`, `mail.qfila.com.br`) - Servidor: `server.whmservidor.com` (IP 107.150.43.90) - cPanel user: `qfila` / homedir `/home/qfila` — **sem shell access** (usar root via plink) - DocumentRoot: `/home/qfila/public_html` - PHP: 8.1.33 (com ionCube Loader 13.3.1) | Composer: `/opt/cpanel/composer/bin/composer` - CodeIgniter 4.6.5 em `/home/qfila/ci4/` (core fora do docroot) - Front controller em `/home/qfila/public_html/index.php` → `/home/qfila/ci4/app/Config/Paths.php` - Página pública `/`: "em construção" (`App\Controllers\Home::index` → view `em_construcao.php`) ## Banco MySQL - DB: `qfila_qfiladb` | User: `qfila_api` | Senha: `GzHXNGoLSzVROiBkExPKGe31` - Host: localhost | DBDriver: MySQLi - **Tabelas:** `establishments`, `users`, `queues`, `queue_entries`, `api_tokens`, `subscriptions`, `invoices`, `migrations` - `establishments.code` (UNIQUE, VARCHAR 12) — identifica empresa pro cliente entrar via QR. Admin demo: `code='QFILA01'` - `queues.attendant_label` (default 'Atendente') e `segment` — tipo de atendimento configurável: Atendente, Guichê, Profissional, Sala, Mesa, Consultório, Posto, Cabine ou personalizado - `queue_entries.customer_photo_url` — URL opcional pra foto do cliente - `subscriptions` — plano mensal por estabelecimento (default "Essencial" R$ 49,90). Admin demo tem assinatura ativa - `invoices` — faturas (pending/paid), vinculadas a subscription ## API REST — `https://qfila.com.br/api/*` - Auth Bearer (tabela `api_tokens`, TTL 30 dias, SHA-256 do token armazenado) - `.htaccess` com `CGIPassAuth On` para passar `Authorization` header (shared hosting) - CORS liberado (filter `cors`) - **Endpoints protegidos (filter `apiauth`):** - `POST /auth/login` | `POST /auth/logout` | `GET /auth/me` - `GET|PUT /establishment` - `GET|POST /users` | `GET|PUT|DELETE /users/{id}` - `GET|POST /queues` | `GET|PUT|DELETE /queues/{id}` - `GET|POST /queues/{id}/entries` - `GET|PUT /entries/{id}` | `PUT /entries/{id}/call|serve|absent` - `GET /dashboard` | `GET /reports/daily?date=YYYY-MM-DD` - **Admin inicial:** `admin@qfila.com.br` / `Qfila@2026` (trocar em produção) - Isolamento: todos os controllers filtram por `$this->authEstab()` (vem do token, nunca do client). `queues.establishment_id` com FK CASCADE. ### Endpoints públicos (pro app cliente — sem auth) — adicionados 2026-04-23 - `GET /api/public/establishment/{code}` — busca empresa pelo QR code - `GET /api/public/queues?code={code}` — lista filas ativas de uma empresa - `POST /api/public/clients/register` — body: `{establishment_code, name, phone, password, email?}` → `{token, client, establishment}` - `POST /api/public/clients/login` — body: `{establishment_code, phone, password}` → `{token, client, establishment}` ### Endpoints do cliente (filter `clientauth` — Bearer do client_token) - `POST /api/client/auth/logout` — revoga token - `GET /api/client/me` — dados do cliente + estabelecimento - `PUT /api/client/me` — atualiza name/email/password - `POST /api/client/me/photo` — multipart (field `photo`) → salva em `/uploads/clients/{id}/` e retorna client com `photo_url` - `GET /api/client/queues` — filas ativas da empresa do cliente (com `waiting_count`) - `POST /api/client/queues/{id}/entries` — cria entry com client_id, copia name/phone/photo do client - `GET /api/client/my-ticket` — ticket ativo + `people_ahead` + queue - `DELETE /api/client/my-ticket` — cancela ### Tabelas adicionadas - `clients` (escopo por establishment_id, UNIQUE (establishment_id, phone)) - `client_tokens` (bearer SHA256, TTL 90 dias, FK client_id CASCADE) - `queue_entries.client_id` — FK nullable, SET NULL on delete ### Arquivos CI4 - `app/Models/ClientModel.php`, `ClientTokenModel.php`, `EstablishmentModel.php` (+ `code` em allowedFields) - `app/Filters/ClientAuthFilter.php` (alias `clientauth`) - `app/Controllers/Api/PublicController.php`, `ClientAuthController.php` - `app/Database/Migrations/2026-04-23-160000_CreateClients.php` - `/home/qfila/public_html/uploads/clients/` — dir criado, owner qfila:qfila, 755 ## Estado atual do app gestor (2026-04-17) - `AppConstants.baseUrl = 'https://qfila.com.br/api'` - **INTERNET permission no main manifest** (bug já documentado — ver `feedback_flutter_android_internet`) - Models robustos ao parse de string/int do MySQL (helper `asInt` nos fromJson) - `HomeScreen.initState` chama `loadQueues()` + `EstablishmentProvider.load()` - `QueueDetailScreen.initState` chama `refreshQueue(queueId)` - UI listagem fila: avatares circulares (foto ou iniciais), textos completos ("Tempo estimado", "Aguardando há X"), status/priority badges legíveis - Criação de fila: seletor "Tipo de atendimento" com chips + opção personalizada (grava em `attendant_label`) - Dialog de chamar cliente: usa `queue.attendantLabel` dinamicamente - Removido botão "Rechamar" da aba Em atendimento (cliente já está sendo atendido) - FAB "+" com bottom padding 140 ## Pendências - **Tela "Minha Assinatura"** no gestor (pagamento PIX / Mercado Pago / Asaas) - **Endpoint público** `GET /api/public/establishment/{code}` para cliente buscar empresa pelo código - **App QFilaCliente** — ✅ integrado com API real (2026-04-23); deep link do QR pendente - **Trocar senha admin** em produção - **Notificações push com app fechado** — requer Firebase Cloud Messaging + backend - **Lottie de pessoas na fila** — precisa de assets profissionais do LottieFiles.com **How to apply:** Ao trabalhar no QFila, partir destas informações. PHP 8.1 server-side, device física `RQCT6049QXE` (Samsung A53) para testes Android.