Add project documentation, license and gitignore

This commit is contained in:
2026-08-25 10:17:53 +02:00
commit 8e0a33b4fd
4 changed files with 223 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
# dependencies
node_modules/
.pnp/
.pnp.js
# env / secrets
.env
.env.*
!.env.example
*.pem
*.key
# nuxt
frontend/.nuxt/
frontend/.output/
frontend/.data/
frontend/dist/
.nitro/
.cache/
# strapi
cms/.strapi/
cms/dist/
cms/build/
cms/.tmp/
cms/public/uploads/*
!cms/public/uploads/.gitkeep
cms/.strapi-updater.json
# caddy runtime
caddy/data/
caddy/config/
# logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# editors / os
.vscode/
!.vscode/extensions.json
.idea/
.DS_Store
Thumbs.db
# misc
coverage/
*.tsbuildinfo
+114
View File
@@ -0,0 +1,114 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Interazione
- L'utente scrive in italiano. **Rispondi in italiano.**
- Codice, commenti, nomi di variabili, commit message, log e documentazione tecnica: **in inglese.**
- Nei commit **non aggiungere `Co-Authored-By: Claude`** né altri trailer di attribuzione.
## Stato
Repository a **stato bootstrap**: contiene solo questo file. Tutto ciò che segue descrive il
target, non l'esistente. Verifica sempre cosa esiste prima di assumere.
Ordine di costruzione:
1. `frontend/` — Nuxt 4 (`npx nuxi@latest init frontend --package-manager npm --no-install-git`)
2. `cms/` — Strapi 5 (`npx create-strapi@latest cms --typescript --dbclient=postgres --no-example --no-git-init`)
3. `docker-compose.yml` + `.env.example` — Postgres, cms, frontend
4. Content types Strapi + permessi ruolo Public (solo `find`/`findOne`)
5. Client Strapi in Nuxt + pagine blog
6. `caddy/Caddyfile` + hardening
## Architettura
```text
Browser → Caddy ─┬─ dominio pubblico → Nuxt 4 (SSR) → REST Strapi
└─ sottodominio CMS → Strapi 5 → PostgreSQL
```
- Strapi è la **sola** fonte di verità editoriale. Niente altro backend (no Express/Nest/Fastify):
se serve logica server, sta in Nitro (`frontend/server/`) o in un controller Strapi.
- I visitatori pubblici non si autenticano mai. Solo editor/admin usano l'auth Strapi.
- Nuxt parla con Strapi **server-side** (`STRAPI_URL` interno Docker). Il token privilegiato non
raggiunge mai il browser: se serve, sta in `runtimeConfig` (non `public`).
- Postgres non è esposto pubblicamente. Media su volume persistente, mai binari nel DB.
## Comandi
Package manager: quello del lockfile. Se non esiste ancora → `npm`.
```bash
# frontend/
npm run dev # dev server
npm run build # build produzione
npm run typecheck # nuxi typecheck — obbligatorio prima di dichiarare fatto
npm run lint
# cms/
npm run develop # Strapi con content-type builder attivo
npm run build # admin panel
npm run start # produzione
# stack
docker compose up -d --build
docker compose logs -f cms
```
Nessun test framework è ancora configurato. Se ne aggiungi uno, documenta qui il comando per
lanciare **un singolo test**.
## Modelli di contenuto
| Type | Campi |
|---|---|
| Article | title, slug (UID da title), excerpt, content (rich text), cover, author (rel), category (rel), tags (rel n:n), publishedDate, seoTitle, seoDescription, seoImage |
| Category | name, slug |
| Tag | name, slug |
| Author | name, biography, image |
Draft & Publish attivo su Article. Le URL pubbliche usano lo **slug**, mai l'id numerico.
## Frontend
Rotte: `/`, `/blog`, `/blog/[slug]`, `/category/[slug]`.
- SSR o prerender per tutto ciò che è indicizzabile. Mai pagine blog client-only senza motivo scritto.
- `<script setup lang="ts">`, Composition API. Convenzioni Nuxt standard (`pages/`, `components/`,
`composables/`, `layouts/`, `server/`).
- Un solo punto di accesso a Strapi: un composable/util tipizzato. Non sparpagliare `$fetch` nelle pagine.
- Tipizza esplicitamente il confine API. Niente `any``unknown` + narrowing.
- Query Strapi: richiedi solo i campi e le relazioni che servono (`fields`, `populate` mirati).
Gestisci sempre 404, lista vuota, errore API.
- Ogni articolo indicizzabile: title unico, meta description, canonical, Open Graph, JSON-LD
`BlogPosting`, gerarchia heading semantica. Il contenuto deve esistere nell'HTML server-rendered.
- Accessibilità non negoziabile: focus visibile, input etichettati, alt significativi, link
descrittivi, navigazione da tastiera.
Il riferimento Hostinger è solo ispirazione visiva. Non copiare codice o asset.
## Priorità
Correttezza e integrità dati → sicurezza → semplicità → SEO/a11y → performance.
Nessuna dipendenza, astrazione o servizio senza un bisogno concreto e attuale. Preferisci i
built-in Strapi al reimplementare funzioni CMS in Nuxt.
## Vincoli
- Mai committare `.env`, segreti, token, credenziali, chiavi. Mantieni `.env.example` sanificato.
- Mai hard-codare domini di produzione, URL privilegiati o credenziali. Vanno in env var.
- Non indebolire auth, CORS, TLS o security header per comodità. Least privilege sui ruoli Strapi.
- Richiedono **approvazione esplicita**: operazioni distruttive, migrazioni irreversibili, modifiche
a dati o configurazione di produzione, cambi di credenziali.
- Non riformattare file non correlati, non fare refactor collaterali, non riscrivere la history,
non force-push.
- Le decisioni architetturali di questo file non si cambiano in silenzio: spiega il trade-off prima.
## Prima di dichiarare completo
Lint → test → typecheck → build dell'app toccata, con gli script del `package.json` relativo.
Non affermare che un check è passato se non l'hai eseguito. Chiudi riassumendo cosa è cambiato e
quali rischi restano aperti.
+23
View File
@@ -0,0 +1,23 @@
PROPRIETARY SOFTWARE LICENSE
Copyright (c) 2026 Davide Grilli. All rights reserved.
This software and its source code, assets, configuration and documentation
(the "Software") are the exclusive property of Davide Grilli and are
confidential and proprietary.
No permission is granted to any person to use, copy, modify, merge, publish,
distribute, sublicense, sell, reverse engineer or create derivative works of
the Software, in whole or in part, by any means, without the prior written
consent of the copyright holder.
Any authorized use is limited to the scope expressly stated in a separate
written agreement with the copyright holder. Unauthorized use, reproduction or
disclosure is prohibited and may result in civil and criminal liability.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+36
View File
@@ -0,0 +1,36 @@
# Blog
Blog platform: a public website built with Nuxt, and a private Strapi CMS where
editors write the articles. Everything runs behind Caddy via Docker Compose.
```text
Browser → Caddy ─┬─ public domain → Nuxt (website)
└─ cms subdomain → Strapi (CMS) → PostgreSQL
```
> Status: bootstrap. The application code is not in place yet.
## Getting started
Requires Docker and Node.js 20+.
```bash
cp .env.example .env # fill in the secrets, never commit this file
docker compose up -d --build
```
Then open the CMS URL to create the first admin account and start publishing.
The public site picks up published articles automatically.
## Working on it
```bash
cd frontend && npm run dev # website
cd cms && npm run develop # CMS
```
Architecture, conventions and constraints are documented in [CLAUDE.md](CLAUDE.md).
## License
Proprietary — Copyright (c) 2026 Davide Grilli. All rights reserved. See [LICENSE](LICENSE).