Files
petlink_final/docs/09-estrutura-projecto.md
2026-05-04 09:43:36 +01:00

12 KiB

9. Estrutura do Projecto

9.1 Organização de Directórios

pawlink/
│
├── app/                                    # Next.js App Router
│   │
│   ├── (auth)/                             # Grupo: sem layout principal
│   │   ├── login/
│   │   │   └── page.tsx                    # Página de login
│   │   ├── register/
│   │   │   └── page.tsx                    # Página de registo
│   │   └── forgot-password/
│   │       └── page.tsx                    # Recuperação de palavra-passe
│   │
│   ├── (main)/                             # Grupo: com header/footer
│   │   ├── layout.tsx                      # Layout principal — Header, SideMenu, Footer
│   │   ├── page.tsx                        # Homepage — listagem de todos os animais (SSR)
│   │   │
│   │   ├── animals/
│   │   │   ├── page.tsx                    # Listagem completa com filtros
│   │   │   └── [id]/
│   │   │       └── page.tsx                # Ficha detalhada do animal
│   │   │
│   │   ├── shelters/
│   │   │   ├── page.tsx                    # Lista de canis
│   │   │   └── [id]/
│   │   │       └── page.tsx                # Perfil do canil + horários + animais
│   │   │
│   │   ├── donate/
│   │   │   ├── page.tsx                    # Escolha do tipo de doação
│   │   │   ├── monetary/
│   │   │   │   └── page.tsx                # Fluxo doação monetária
│   │   │   ├── food/
│   │   │   │   └── page.tsx                # Fluxo doação de ração
│   │   │   └── toys/
│   │   │       └── page.tsx                # Fluxo doação de brinquedos
│   │   │
│   │   └── account/
│   │       ├── layout.tsx                  # Layout da área de conta (sidebar)
│   │       ├── settings/
│   │       │   └── page.tsx                # Dados da conta, palavra-passe, tema
│   │       ├── adoptions/
│   │       │   └── page.tsx                # Histórico e estado das adopções
│   │       └── donations/
│   │           └── page.tsx                # Histórico de doações
│   │
│   ├── (shelter)/                          # Grupo: painel dos canis
│   │   ├── layout.tsx                      # Layout do dashboard
│   │   └── dashboard/
│   │       ├── page.tsx                    # Resumo + estatísticas
│   │       ├── animals/
│   │       │   ├── page.tsx                # Listar e gerir animais
│   │       │   ├── new/page.tsx            # Adicionar novo animal
│   │       │   └── [id]/edit/page.tsx      # Editar animal
│   │       ├── reservations/
│   │       │   └── page.tsx                # Ver e confirmar reservas
│   │       ├── donations/
│   │       │   └── page.tsx                # Ver doações recebidas
│   │       └── needs/
│   │           └── page.tsx                # Gerir necessidades actuais
│   │
│   └── api/                                # API Routes (endpoints REST)
│       ├── auth/
│       │   └── [...nextauth]/
│       │       └── route.ts                # NextAuth handler
│       │
│       ├── animals/
│       │   ├── route.ts                    # GET (listar com filtros) + POST (criar)
│       │   └── [id]/
│       │       └── route.ts                # GET (detalhe) + PATCH (actualizar) + DELETE
│       │
│       ├── shelters/
│       │   ├── route.ts                    # GET (listar) + POST (registar canil)
│       │   └── [id]/
│       │       └── route.ts                # GET + PATCH
│       │
│       ├── reservations/
│       │   ├── route.ts                    # GET (minhas reservas) + POST (criar)
│       │   └── [id]/
│       │       └── route.ts                # PATCH (confirmar/cancelar)
│       │
│       ├── donations/
│       │   ├── route.ts                    # GET + POST
│       │   └── intent/
│       │       └── route.ts                # POST — cria Stripe PaymentIntent
│       │
│       ├── payments/
│       │   └── webhook/
│       │       └── route.ts                # POST — Stripe webhook
│       │
│       ├── users/
│       │   └── me/
│       │       └── route.ts                # GET (perfil) + PATCH (actualizar) + DELETE
│       │
│       └── chat/
│           └── route.ts                    # POST — chatbot IA (streaming)
│
├── components/                             # Componentes React reutilizáveis
│   │
│   ├── ui/                                 # shadcn/ui base components
│   │   ├── button.tsx
│   │   ├── card.tsx
│   │   ├── dialog.tsx
│   │   ├── input.tsx
│   │   ├── select.tsx
│   │   ├── badge.tsx
│   │   └── ...
│   │
│   ├── animals/
│   │   ├── AnimalCard.tsx                  # Card da listagem
│   │   ├── AnimalGrid.tsx                  # Grid responsivo de cards
│   │   ├── AnimalFilters.tsx               # Painel de filtros
│   │   ├── AnimalProfile.tsx               # Ficha completa do animal
│   │   ├── AnimalGallery.tsx               # Galeria de fotos
│   │   ├── AnimalStatusBadge.tsx           # Badge: Disponível/Reservado/Adoptado
│   │   └── UrgentBadge.tsx                 # Destaque para animais urgentes
│   │
│   ├── shelters/
│   │   ├── ShelterCard.tsx
│   │   ├── ShelterProfile.tsx
│   │   └── ShelterHours.tsx                # Tabela de horários formatada
│   │
│   ├── donations/
│   │   ├── DonationTypeSelector.tsx        # Escolha Monetária/Ração/Brinquedos
│   │   ├── ShelterSelector.tsx             # Escolha do canil destinatário
│   │   ├── PaymentForm.tsx                 # Stripe Payment Element wrapper
│   │   ├── FoodDonationForm.tsx            # Formulário ração
│   │   ├── ToysDonationForm.tsx            # Formulário brinquedos
│   │   └── DeliveryMethodSelector.tsx      # Levar / Recolha em casa
│   │
│   ├── reservations/
│   │   ├── ReservationCalendar.tsx         # Calendário de datas disponíveis
│   │   ├── ReservationSummary.tsx          # Resumo antes de confirmar
│   │   └── ReservationCard.tsx             # Card no histórico
│   │
│   ├── ai/
│   │   ├── AnimalMatchWidget.tsx           # Widget de match inteligente
│   │   └── SupportChat.tsx                 # Chatbot de suporte
│   │
│   └── layout/
│       ├── Header.tsx                      # Cabeçalho com logo e navegação
│       ├── SideMenu.tsx                    # Menu lateral (3 traços)
│       ├── Footer.tsx
│       └── ThemeToggle.tsx                 # Toggle modo claro/escuro
│
├── lib/                                    # Lógica partilhada e utilitários
│   │
│   ├── db/
│   │   ├── prisma.ts                       # Singleton do Prisma Client
│   │   ├── animals.ts                      # Queries reutilizáveis de animais
│   │   ├── shelters.ts                     # Queries de canis
│   │   ├── reservations.ts                 # Queries de reservas
│   │   └── donations.ts                    # Queries de doações
│   │
│   ├── auth/
│   │   ├── config.ts                       # Configuração NextAuth
│   │   ├── age-validation.ts               # Validação de +18 anos
│   │   └── password.ts                     # bcrypt helpers
│   │
│   ├── email/
│   │   ├── send.ts                         # Wrapper Resend
│   │   └── templates/
│   │       ├── ReservationConfirmation.tsx # Template email de reserva
│   │       ├── DonationReceipt.tsx         # Template recibo de doação
│   │       └── PasswordReset.tsx           # Template recuperação de palavra-passe
│   │
│   ├── payments/
│   │   └── stripe.ts                       # Stripe client + helpers
│   │
│   ├── ai/
│   │   ├── match.ts                        # Lógica de match inteligente
│   │   ├── descriptions.ts                 # Geração de descrições
│   │   └── prompts.ts                      # System prompts centralizados
│   │
│   ├── utils/
│   │   ├── format.ts                       # Formatação de datas, moeda, idade
│   │   ├── districts.ts                    # Lista de distritos de Portugal
│   │   └── cn.ts                           # Utility para merge de classes Tailwind
│   │
│   └── validations/
│       ├── auth.ts                         # Schemas Zod para auth
│       ├── animals.ts                      # Schemas para animais
│       ├── donations.ts                    # Schemas para doações
│       └── reservations.ts                 # Schemas para reservas
│
├── prisma/
│   ├── schema.prisma                       # Esquema da base de dados
│   ├── seed.ts                             # Dados iniciais para desenvolvimento
│   └── migrations/                         # Histórico de migrações (gerado automaticamente)
│
├── public/
│   ├── images/
│   │   ├── logo.svg
│   │   ├── logo-dark.svg
│   │   └── placeholders/                   # Imagens placeholder para animais
│   └── icons/
│       └── favicon.ico
│
├── docs/                                   # Esta documentação
│   ├── 01-visao-geral.md
│   ├── 02-requisitos.md
│   ├── 03-arquitectura.md
│   ├── 04-base-de-dados.md
│   ├── 05-fluxos-utilizador.md
│   ├── 06-stack-tecnologica.md
│   ├── 07-seguranca.md
│   ├── 08-ia.md
│   ├── 09-estrutura-projecto.md
│   ├── 10-orientacoes-desenvolvimento.md
│   ├── 11-roadmap.md
│   └── 12-glossario.md
│
├── .env.local                              # Variáveis de ambiente (não commitado)
├── .env.example                            # Template de variáveis (commitado)
├── .gitignore
├── .eslintrc.json
├── .prettierrc
├── middleware.ts                           # Next.js middleware (auth + rate limiting)
├── next.config.ts
├── tailwind.config.ts
├── tsconfig.json
└── package.json

9.2 Convenções de Nomenclatura de Ficheiros

Tipo Convenção Exemplo
Componentes React PascalCase AnimalCard.tsx, ShelterProfile.tsx
Hooks personalizados camelCase com prefixo use useAnimals.ts, useDonation.ts
Utilitários e helpers camelCase format.ts, age-validation.ts
Constantes kebab-case districts.ts, animal-species.ts
Páginas Next.js lowercase (page.tsx) page.tsx, layout.tsx, loading.tsx
API Routes lowercase (route.ts) route.ts

9.3 Padrão de Exportação de Componentes

// ✅ CORRECTO — export default para componentes de página e principais
export default function AnimalCard({ animal }: AnimalCardProps) { ... }

// ✅ CORRECTO — named exports para utilitários e múltiplos exports
export function formatAge(ageMonths: number): string { ... }
export function formatPrice(cents: number): string { ... }

// ✅ CORRECTO — tipos exportados separadamente
export type { AnimalCardProps };