- Document Editorial Fresh design system (fonts, colors, classes) - Add basePath gotchas for middleware and email redirect - Update phase 1 status with design system note Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
263 lines
8.2 KiB
Markdown
263 lines
8.2 KiB
Markdown
# Leopost - Note di Progetto
|
||
|
||
## Panoramica
|
||
Social media manager potenziato dall'AI. Gestisce post su multiple piattaforme social.
|
||
|
||
**URL Live:** https://lab.mlhub.it/leopost/
|
||
**Repository:** https://git.mlhub.it/Michele/leopost
|
||
**Supabase Project:** `cizyzbdylxxjjhgnvyub`
|
||
|
||
## Stack Tecnico
|
||
- **Frontend:** Next.js 16 con App Router
|
||
- **Auth:** Supabase Auth (Email/Password + Google OAuth)
|
||
- **Database:** Supabase Cloud PostgreSQL
|
||
- **Deployment:** Docker su VPS con nginx reverse proxy
|
||
|
||
## Configurazione Critica
|
||
|
||
### Next.js per Subpath Deployment
|
||
```typescript
|
||
// next.config.ts
|
||
const nextConfig: NextConfig = {
|
||
basePath: '/leopost',
|
||
trailingSlash: true,
|
||
};
|
||
```
|
||
|
||
### Variabili Ambiente (.env su VPS)
|
||
```
|
||
SUPABASE_URL=https://cizyzbdylxxjjhgnvyub.supabase.co
|
||
SUPABASE_ANON_KEY=...
|
||
SUPABASE_SERVICE_ROLE_KEY=...
|
||
APP_URL=https://lab.mlhub.it/leopost
|
||
```
|
||
|
||
---
|
||
|
||
## Problemi Riscontrati e Soluzioni
|
||
|
||
### 1. Build OOM (Out of Memory)
|
||
**Problema:** Build Next.js killed durante `npm run build` con 512MB RAM limit.
|
||
**Soluzione:** Aumentare memory limit in docker-compose.yml a 1024MB.
|
||
|
||
### 2. Redirect Loop HTTP/HTTPS
|
||
**Problema:** `/leopost` senza trailing slash causava loop redirect e downgrade a HTTP.
|
||
**Soluzione:**
|
||
- Aggiungere `trailingSlash: true` in next.config.ts
|
||
- Aggiungere location esplicita in nginx:
|
||
```nginx
|
||
location = /leopost {
|
||
return 301 https://$host/leopost/;
|
||
}
|
||
```
|
||
|
||
### 3. Middleware Intercetta Tutte le Route
|
||
**Problema:** Homepage bianca perché il middleware Next.js intercettava anche le pagine statiche.
|
||
**Soluzione:** Limitare il matcher del middleware solo alle route che richiedono auth check:
|
||
```typescript
|
||
export const config = {
|
||
matcher: [
|
||
'/dashboard/:path*',
|
||
'/settings/:path*',
|
||
'/subscription/:path*',
|
||
'/login',
|
||
'/login/',
|
||
'/register',
|
||
'/register/',
|
||
],
|
||
}
|
||
```
|
||
**NON includere:** `/`, `/auth/:path*`, pagine statiche pubbliche.
|
||
|
||
### 4. OAuth 502 Bad Gateway - Header Troppo Grandi (CRITICO)
|
||
**Problema:** Google OAuth callback restituiva 502 Bad Gateway.
|
||
**Causa:** Supabase Auth setta cookie JWT molto grandi (~4KB) nella risposta. I buffer nginx di default sono troppo piccoli.
|
||
|
||
**Soluzione - ENTRAMBI i livelli nginx richiedono configurazione:**
|
||
|
||
**A) lab-router** (`/opt/lab-router/projects/leopost.conf`):
|
||
```nginx
|
||
location /leopost/ {
|
||
proxy_pass http://lab-leopost-app:3000;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto https;
|
||
proxy_set_header Connection "";
|
||
|
||
# CRITICO per Supabase Auth
|
||
proxy_buffer_size 256k;
|
||
proxy_buffers 8 256k;
|
||
proxy_busy_buffers_size 512k;
|
||
}
|
||
```
|
||
|
||
**B) NPM (Nginx Proxy Manager)** - file `/data/nginx/custom/server_proxy.conf`:
|
||
```nginx
|
||
# Large buffer sizes for Supabase Auth JWT cookies
|
||
proxy_buffer_size 256k;
|
||
proxy_buffers 8 256k;
|
||
proxy_busy_buffers_size 512k;
|
||
```
|
||
|
||
**Importante:** Il 502 può venire da ENTRAMBI i nginx nella catena:
|
||
```
|
||
Browser → NPM → lab-router → app
|
||
```
|
||
Se solo lab-router ha i buffer grandi ma NPM no, il 502 viene da NPM.
|
||
|
||
### 5. OAuth Redirect URL Errati
|
||
**Problema:** Dopo Google auth, redirect a localhost o URL senza basePath.
|
||
**Soluzione:** Usare `NEXT_PUBLIC_APP_URL` per costruire redirect URL dinamici:
|
||
```typescript
|
||
// src/app/auth/callback/route.ts
|
||
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://lab.mlhub.it/leopost'
|
||
return NextResponse.redirect(`${baseUrl}${next}`)
|
||
```
|
||
|
||
### 6. Middleware Redirect Senza basePath
|
||
**Problema:** Middleware redirect a `/login/` invece di `/leopost/login/` → 404.
|
||
**Causa:** `new URL('/login/', request.url)` non include il basePath.
|
||
**Soluzione:** Usare `request.nextUrl.clone()`:
|
||
```typescript
|
||
// middleware.ts
|
||
// ❌ SBAGLIATO
|
||
const redirectUrl = new URL('/login/', request.url)
|
||
|
||
// ✅ CORRETTO
|
||
const redirectUrl = request.nextUrl.clone()
|
||
redirectUrl.pathname = '/login/'
|
||
return NextResponse.redirect(redirectUrl)
|
||
```
|
||
|
||
### 7. Email Conferma Redirect Errato
|
||
**Problema:** Link conferma email reindirizza a `lab.mlhub.it/auth/callback` senza basePath.
|
||
**Causa:** `window.location.origin` non include basePath.
|
||
**Soluzione:** Usare `NEXT_PUBLIC_APP_URL`:
|
||
```typescript
|
||
// src/components/auth/register-form.tsx
|
||
const appUrl = process.env.NEXT_PUBLIC_APP_URL || window.location.origin
|
||
|
||
await supabase.auth.signUp({
|
||
email, password,
|
||
options: {
|
||
emailRedirectTo: `${appUrl}/auth/callback/`,
|
||
}
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
## Configurazione Supabase Dashboard
|
||
|
||
### Authentication > URL Configuration
|
||
- **Site URL:** `https://lab.mlhub.it/leopost`
|
||
- **Redirect URLs:**
|
||
- `https://lab.mlhub.it/leopost/auth/callback`
|
||
- `https://lab.mlhub.it/leopost/auth/callback/`
|
||
|
||
### Authentication > Providers > Google
|
||
- Abilitare Google provider
|
||
- Configurare Client ID e Client Secret da Google Cloud Console
|
||
- Authorized redirect URI in Google: `https://cizyzbdylxxjjhgnvyub.supabase.co/auth/v1/callback`
|
||
|
||
---
|
||
|
||
## Comandi Utili
|
||
|
||
```bash
|
||
# Deploy aggiornamenti
|
||
cd "D:\Michele\Progetti\Claude\VPS echosystem\lab\leopost"
|
||
git add . && git commit -m "Update" && git push origin main
|
||
ssh mic@72.62.49.98 "cd /opt/lab-leopost && git pull && docker compose restart"
|
||
|
||
# Verificare log container
|
||
ssh mic@72.62.49.98 "docker logs --tail 50 lab-leopost-app"
|
||
|
||
# Verificare log nginx lab-router
|
||
ssh mic@72.62.49.98 "docker logs --tail 50 lab-router"
|
||
|
||
# Verificare log NPM (per errori 502)
|
||
ssh mic@72.62.49.98 "docker exec nginx-proxy-app-1 tail -30 /data/logs/proxy-host-8_error.log"
|
||
```
|
||
|
||
---
|
||
|
||
## Design System: "Editorial Fresh"
|
||
|
||
Il progetto usa un design system personalizzato chiamato "Editorial Fresh" - ispirato al design editoriale/magazine con tipografia forte e layout distintivo.
|
||
|
||
### Font
|
||
| Tipo | Font | Uso |
|
||
|------|------|-----|
|
||
| Display | **Fraunces** | Titoli, heading (serif con carattere) |
|
||
| Body | **DM Sans** | Testo, paragrafi, UI |
|
||
|
||
```css
|
||
.font-display { font-family: var(--font-display); }
|
||
.font-body { font-family: var(--font-body); }
|
||
```
|
||
|
||
### Palette Colori
|
||
| Nome | Valore | CSS Variable | Uso |
|
||
|------|--------|--------------|-----|
|
||
| Cream | `#FFFBF5` | `--color-cream` | Background principale |
|
||
| Cream Dark | `#F5F0E8` | `--color-cream-dark` | Background secondario |
|
||
| Ink | `#1A1A1A` | `--color-ink` | Testo principale, bottoni |
|
||
| Ink Light | `#4A4A4A` | `--color-ink-light` | Testo secondario |
|
||
| Ink Muted | `#7A7A7A` | `--color-ink-muted` | Testo disabilitato |
|
||
| Accent | `#E85A4F` | `--color-accent` | CTA, elementi distintivi (corallo) |
|
||
| Success | `#2D7A4F` | `--color-success` | Conferme |
|
||
| Error | `#C53030` | `--color-error` | Errori |
|
||
|
||
### Classi Utility Custom
|
||
```css
|
||
/* Testi */
|
||
.text-accent /* Corallo */
|
||
.text-muted /* Grigio chiaro */
|
||
.text-ink /* Nero */
|
||
.text-ink-light /* Grigio scuro */
|
||
|
||
/* Background */
|
||
.bg-cream /* Sfondo principale */
|
||
.bg-cream-dark /* Sfondo alternativo */
|
||
.bg-accent-light /* Sfondo accent leggero */
|
||
|
||
/* Elementi editoriali */
|
||
.editorial-tag /* Tag uppercase corallo (SOCIAL MEDIA MANAGER) */
|
||
.editorial-line /* Linea decorativa 60px × 3px corallo */
|
||
.card-editorial /* Card con barra accent in cima */
|
||
```
|
||
|
||
### Componenti
|
||
| Componente | File | Note |
|
||
|------------|------|------|
|
||
| Button | `src/components/ui/button.tsx` | Varianti: default, outline, ghost, accent |
|
||
| Input | `src/components/ui/input.tsx` | Bordi quadrati, focus nero |
|
||
| Card Editorial | CSS class | Bordo top accent, padding 2rem |
|
||
|
||
### Principi di Design
|
||
1. **Niente bordi arrotondati** - Stile editoriale con angoli vivi
|
||
2. **Tipografia forte** - Fraunces per impatto, DM Sans per leggibilità
|
||
3. **Spazio generoso** - Padding abbondante, respiro tra elementi
|
||
4. **Accent limitato** - Corallo usato con parsimonia per CTA e emphasis
|
||
5. **Animazioni sottili** - fade-up on load, transizioni 200ms
|
||
|
||
### Come Mantenere Coerenza
|
||
Quando crei nuove pagine/componenti:
|
||
1. Usa `font-display` per tutti i titoli
|
||
2. Usa le classi `text-*` e `bg-*` del design system
|
||
3. Bottoni principali con `variant="default"` (nero → accent on hover)
|
||
4. Form inputs senza border-radius
|
||
5. Ogni sezione inizia con `editorial-tag` + titolo `font-display`
|
||
|
||
---
|
||
|
||
## Stato Fasi
|
||
|
||
- [x] **Fase 1:** Autenticazione (Email/Password + Google OAuth) + Design System
|
||
- [ ] **Fase 2:** Dashboard e gestione account social
|
||
- [ ] **Fase 3:** Creazione e scheduling post
|
||
- [ ] **Fase 4:** Integrazione AI per generazione contenuti
|