✨ feat: enhance admin UI configuration and SSR handling
- Add support for number chip arrays and JSON editor in admin UI config. - Introduce pagebuilder block registry for Svelte components in admin previews. - Implement custom role names and a 3-layer cascade model for field-level permissions. - Add CORS configuration hierarchy for better API security. - Update project setup instructions for admin token and config management. - Improve SSR 404 signaling with proper context handling in NotFound component. - Refactor routing structure to separate NotFound page into its own route.
This commit is contained in:
@@ -4,226 +4,135 @@ Tibi CMS starter template — Svelte 5 SPA with esbuild, SSR via goja, and Playw
|
||||
|
||||
## Project overview
|
||||
|
||||
- **Frontend**: Svelte 5 SPA in `frontend/src/`, bundled with esbuild, styled with Tailwind CSS 4.
|
||||
- **Backend**: tibi-server with API hooks in `api/hooks/`, collections in `api/collections/`.
|
||||
- **SSR**: Server-side rendering via goja (Go JS runtime) in `api/hooks/ssr/`.
|
||||
- **Tests**: Playwright for E2E, API, mobile, and visual regression tests in `tests/`.
|
||||
- **Types**: Shared TypeScript types in `types/global.d.ts`. Keep `tibi-types/` read-only.
|
||||
- **Frontend**: Svelte 5 SPA in `frontend/src/`, esbuild, Tailwind CSS 4.
|
||||
- **Backend**: tibi-server with hooks in `api/hooks/`, collections in `api/collections/`.
|
||||
- **SSR**: goja (Go JS runtime) in `api/hooks/ssr/`.
|
||||
- **Tests**: Playwright in `tests/` (API, E2E, mobile, visual).
|
||||
- **Types**: `types/global.d.ts` (project), `tibi-types/` (read-only, from sibling repo).
|
||||
|
||||
## Project bootstrap
|
||||
## Key constraints
|
||||
|
||||
Before treating this repo as a real project, replace the starter placeholders and initial project values.
|
||||
- **Dev servers always run in Docker** — never `yarn dev` or `yarn start` locally.
|
||||
- `yarn` is for standalone tasks: `build`, `build:server`, `validate`.
|
||||
- Bootstrap details (placeholder replacement, docker setup) → `tibi-project-setup` skill.
|
||||
- Build checklist for full website projects → `.agents/BUILD_CHECKLIST.md`.
|
||||
|
||||
Derive these values from the real repo path `gitbase.de/ORG/REPO`:
|
||||
## Quick reference
|
||||
|
||||
- `PROJECT_NAME`: use the repo name in kebab-case.
|
||||
- `TIBI_NAMESPACE`: set it equal to `PROJECT_NAME`, i.e. use the same repo name in kebab-case.
|
||||
- `STAGING_PATH`: use the real repo org and repo name, i.e. `/staging/ORG/REPO/dev`.
|
||||
| Action | Command |
|
||||
|--------|---------|
|
||||
| Start dev stack | `make docker-up` or `make docker-start` |
|
||||
| Restart frontend | `make docker-restart-frontend` |
|
||||
| Logs | `make docker-logs` |
|
||||
| Build frontend | `yarn build` |
|
||||
| Build SSR | `yarn build:server` |
|
||||
| Validate | `yarn validate` |
|
||||
| Run all tests | `yarn test` |
|
||||
| Run E2E tests | `yarn test:e2e` |
|
||||
| Run API tests | `yarn test:api` |
|
||||
|
||||
- `.env`: replace `PROJECT_NAME=__PROJECT_NAME__`, `TIBI_NAMESPACE=__TIBI_NAMESPACE__`, `STAGING_PATH=/staging/__ORG__/__PROJECT__/dev`, `STAGING_URL=https://dev-__PROJECT_NAME__.staging.testversion.online`, and `CODING_URL=https://__PROJECT_NAME__.code.testversion.online`.
|
||||
- `api/config.yml`: replace `namespace: __TIBI_NAMESPACE__`.
|
||||
- `frontend/.htaccess`: replace both `__TIBI_NAMESPACE__` proxy targets.
|
||||
- `api/hooks/config-client.js`: replace `https://__PROJECT__.code.testversion.online` with the real origin URL.
|
||||
- `package.json`: adapt starter metadata like `name` and `repository` when creating the real project repo.
|
||||
- Docker and local URLs derive from `.env`, so `PROJECT_NAME` and `TIBI_NAMESPACE` must be correct before `make docker-up`.
|
||||
- Playwright seed/API tests read `CODING_URL` from `.env` first. Use the configured host from `.env` whenever it serves both `/` and `/api/...`, even in starter-style local bootstrap setups.
|
||||
- Recommended check: search for remaining starter placeholders with `rg '__[A-Z0-9_]+__' .`.
|
||||
## Testing notes
|
||||
|
||||
## Setup commands
|
||||
|
||||
- Install deps: `yarn install`
|
||||
- Start dev: `make docker-up` or `make docker-start`
|
||||
- Restart frontend watcher/dev-server: `make docker-restart-frontend`
|
||||
- View logs: `make docker-logs` or `make docker-logs-X`
|
||||
- Start with mock data: set `MOCK=1` in `.env`, then use the normal Docker start command
|
||||
- Build frontend/admin bundle: `yarn build`
|
||||
- Build SSR bundle: `yarn build:server`
|
||||
- Validate types: `yarn validate`
|
||||
|
||||
## Development workflow
|
||||
|
||||
- **Dev servers always run in Docker** — never use `yarn dev` or `yarn start` locally; web access only works through the Docker reverse proxy.
|
||||
- Local `yarn` is only for standalone tasks: `yarn build`, `yarn build:server`, `yarn validate`.
|
||||
- **Mock mode**: Set `MOCK=1` to run the frontend without a tibi-server. API calls are served from JSON files in `frontend/mocking/`. Missing mock endpoints return 404.
|
||||
- Frontend code is automatically rebuilt by the watcher/BrowserSync stack; backend hooks reload on change.
|
||||
- Read `.env` for environment URLs and secrets.
|
||||
- `webserver/` is for staging/ops only; use BrowserSync/esbuild for day-to-day dev.
|
||||
- If development environment is running, access the website at: `https://${PROJECT_NAME}.code.testversion.online/`.
|
||||
- For a11y testing use MCP a11y tools if available.
|
||||
- For quick interactive browser testing, ask the user to connect Playwright MCP (preferred) or Browser MCP (only in non-autonomous/chat mode).
|
||||
|
||||
## Testing
|
||||
|
||||
- Run all tests: `yarn test`
|
||||
- E2E tests: `yarn test:e2e`
|
||||
- API tests: `yarn test:api`
|
||||
- Visual regression: `yarn test:visual`
|
||||
- Before running Playwright, ensure the `CODING_URL` from `.env` actually serves both `/` and `/api/...` for this repo.
|
||||
- After code changes, run only affected spec files: `npx playwright test tests/e2e/filename.spec.ts`.
|
||||
- Write unit tests for new functionality and ensure existing tests pass.
|
||||
|
||||
## Video tours
|
||||
|
||||
- Video tours are Playwright-based screen recordings (not tests) in `video-tours/`.
|
||||
- Run all tours (desktop): `yarn tour`
|
||||
- Run all tours (mobile): `yarn tour:mobile`
|
||||
- Videos are saved to `video-tours/output/` (git-ignored).
|
||||
- Tour files use `.tour.ts` suffix in `video-tours/tours/`.
|
||||
- Helpers: `injectVisibleCursor()`, `moveThenClick()`, `moveThenType()`, `smoothScroll()` in `video-tours/helpers.ts`.
|
||||
- Fixtures provide a `tourPage` with visible cursor overlay via `video-tours/tours/fixtures.ts`.
|
||||
- Tests read `CODING_URL` from `.env`. Ensure it serves both `/` and `/api/...`.
|
||||
- After changes, run only affected specs: `npx playwright test tests/e2e/filename.spec.ts`.
|
||||
- CI runs `yarn validate` but not Playwright (needs MongoDB + tibi-server).
|
||||
|
||||
## API access
|
||||
|
||||
- API access to collections uses the reverse proxy: `CODING_URL/api/<collection>` (e.g. `CODING_URL/api/content`).
|
||||
- Auth via `Token` header with `ADMIN_TOKEN` from `api/config.yml.env` when a configured token with the required permissions is needed.
|
||||
- Collection permissions for `user:` apply to JWT-authenticated users (`X-Auth-Token`), not to the static `Token:` header.
|
||||
- If a collection should allow writes via `ADMIN_TOKEN`, define an explicit permission block like `"token:${ADMIN_TOKEN}":` with the required methods.
|
||||
- `Token` header with `ADMIN_TOKEN` from `api/config.yml.env`.
|
||||
- Collection `user:` permissions apply to JWT auth (`X-Auth-Token`), not static `Token:`.
|
||||
- For write access via `ADMIN_TOKEN`, add `"token:${ADMIN_TOKEN}": { methods: { post: true, put: true } }` to the collection permissions.
|
||||
|
||||
## Required secrets and credentials
|
||||
## Required secrets
|
||||
|
||||
| Secret | Location | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `ADMIN_TOKEN` | `api/config.yml.env` | Access token for configured API/admin permissions |
|
||||
| `SENTRY_AUTH_TOKEN` | Gitea repo secrets | Sourcemap upload to Sentry (CI only) |
|
||||
| `.basic-auth-web` | project root (git-ignored) | Basic auth for BrowserSync dev server |
|
||||
| `.basic-auth-code` | project root (git-ignored) | Basic auth for Code-Server / admin |
|
||||
| `RSYNC_PASS` | Gitea secrets (`github.token`) | rsync deployment password (CI only) |
|
||||
| `ADMIN_TOKEN` | `api/config.yml.env` | API/admin access token |
|
||||
| `ADMIN_ASSET_VERSION` | `api/config.yml.env` | Cache-busting for admin bundle (auto-generated) |
|
||||
| `.basic-auth-web` | project root (git-ignored) | BrowserSync basic auth |
|
||||
| `.basic-auth-code` | project root (git-ignored) | Code-Server basic auth |
|
||||
|
||||
## Infrastructure prerequisites
|
||||
Generated dev defaults in `api/config.yml.env` may be committed. Production values are overwritten in CI/CD via secrets.
|
||||
|
||||
- **Code-Server environment** — This project is designed for development on a Code-Server instance at `*.code.testversion.online` with a **Traefik reverse proxy** managing HTTPS and auto-routing via Docker labels.
|
||||
- **Without Code-Server/Traefik** — The Docker stack starts but the website is not reachable via hostname. Workaround: access BrowserSync directly via `http://localhost:3000` (requires exposing the port in `docker-compose-local.yml`).
|
||||
- **Docker + Docker Compose** — Required for all development. Never run `yarn dev` or `yarn start` locally.
|
||||
- **MongoDB** — Runs as a Docker service (`mongo`). Data persists in `tmp/mongo-data/`.
|
||||
- **Production** — Deployed via rsync to an existing server running tibi-server + MongoDB. The frontend is a static SPA served by a Node.js webserver (`webserver/webserver.js`) or directly by tibi-server.
|
||||
- **Staging** — Docker Compose builds a `www` container that connects to an external tibi-server at `dev-tibi-server.staging.testversion.online`.
|
||||
## Reference repositories (sibling repos)
|
||||
|
||||
## Reference repositories
|
||||
|
||||
These sibling repos in the workspace provide documentation, types, and reference implementations:
|
||||
|
||||
| Repository | Path | Purpose |
|
||||
| --- | --- | --- |
|
||||
| **tibi-types** | `../../cms/tibi-types` | TypeScript type definitions for hooks, collections, permissions, etc. Included via `tsconfig.json` — **read-only, do not modify**. Key file: `index.d.ts`. JSON schemas in `schemas/api-config/`. |
|
||||
| **tibi-server** | `../../cms/tibi-server` | Go source code of the server. `docs/` has detailed documentation (16 files), `examples/` has sample projects. |
|
||||
| **tibi-admin-nova** | `../../cms/tibi-admin-nova` | Admin UI reference project. Key file: `types/admin.d.ts` (1147 lines — all admin types: `AdminCollection`, `AdminCollectionField`, `AdminCollectionMeta`, `AdminDashboard`, etc.). Use as reference for collection field configs, dashboard setup, and fieldLists. |
|
||||
| Repo | Path | Key file |
|
||||
|------|------|----------|
|
||||
| **tibi-types** | `../../cms/tibi-types` | `index.d.ts` (context types), `schemas/config/collection.schema.json` |
|
||||
| **tibi-server** | `../../cms/tibi-server` | `docs/` (19 files: collections, hooks, auth, actions, SSE, jobs, etc.) |
|
||||
| **tibi-admin-nova** | `../../cms/tibi-admin-nova` | `types/admin.d.ts` (all admin config types) |
|
||||
|
||||
### When to consult which repo
|
||||
|
||||
- **Write collection YAML** → `tibi-server/docs/04-collections.md` + `tibi-types/schemas/api-config/collection.json` (JSON schema)
|
||||
- **Write/debug hooks** → `tibi-server/docs/06-hooks.md` + `tibi-types/index.d.ts` (context types)
|
||||
- **Configure admin UI** → `tibi-admin-nova/types/admin.d.ts` (field types, meta, dashboard) + `tibi-admin-nova/api/collections/` (real examples)
|
||||
- **Collection YAML** → `tibi-server/docs/04-collections.md` + `tibi-types/schemas/config/collection.schema.json`
|
||||
- **Hooks** → `tibi-server/docs/06-hooks.md` + `tibi-types/index.d.ts`
|
||||
- **Admin UI config** → `tibi-admin-nova/types/admin.d.ts` + `tibi-admin-nova/api/collections/` (examples)
|
||||
- **Permissions** → `tibi-server/docs/05-authentication.md`
|
||||
- **Actions/forms** → `tibi-server/docs/19-actions.md`
|
||||
- **Realtime/SSE** → `tibi-server/docs/07-realtime.md`
|
||||
- **Images/uploads** → `tibi-server/docs/08-file-upload-images.md`
|
||||
- **LLM integration** → `tibi-server/docs/09-llm-integration.md`
|
||||
- **Field-level permissions** → `tibi-server/docs/17-field-level-permissions.md`
|
||||
|
||||
### TypeScript types
|
||||
|
||||
`tibi-types` is included via `tsconfig.json`:
|
||||
## TypeScript
|
||||
|
||||
```json
|
||||
"include": ["frontend/src/**/*", "types/**/*", "./../../cms/tibi-types", "api/**/*"]
|
||||
```
|
||||
|
||||
Project-specific types (e.g. `Ssr`, `ApiOptions`, `ContentEntry`) live in `types/global.d.ts`.
|
||||
- Domain types (entities, block props, API responses) be strict. `any`/`[key: string]: any` OK for inherently dynamic data (MongoDB filters, CMS fields, hook payloads).
|
||||
- No `@ts-ignore` — use `/** @type {…} */` cast instead.
|
||||
- **Zero warnings policy**: always run `yarn validate` after changes; fix all warnings.
|
||||
- Svelte 5 with Runes: `$props()`, `$state()`, `$derived()`, `$effect()`.
|
||||
|
||||
## Code style
|
||||
## Tailwind CSS 4
|
||||
|
||||
- Follow the existing code style and conventions used in the project.
|
||||
- Write clear and concise comments where necessary to explain complex logic.
|
||||
- Ensure code is modular and reusable where possible.
|
||||
- Avoid introducing new dependencies unless absolutely necessary.
|
||||
- Respect a11y and localization best practices; optimize for WCAG AA standards.
|
||||
- Check the problems tab for any errors or warnings in the code.
|
||||
- **Zero warnings policy**: After making changes, always run `yarn validate` and check the IDE problems tab. Fix all TypeScript, Svelte, and Tailwind warnings — the codebase must stay warning-free.
|
||||
- When Tailwind `suggestCanonicalClasses` warnings appear, always fix the **source** `.svelte`/`.ts`/`.css` file — never the compiled output.
|
||||
Canonical v4 syntax — no v3 legacy classes:
|
||||
|
||||
### Architecture skills (loaded on demand)
|
||||
| v3 | v4 |
|
||||
|----|----|
|
||||
| `bg-gradient-to-*` | `bg-linear-to-*` |
|
||||
| `aspect-[4/3]` | `aspect-4/3` |
|
||||
| `!bg-brand-600` | `bg-brand-600!` |
|
||||
| `hover:!bg-brand-700` | `hover:bg-brand-700!` |
|
||||
|
||||
These skills provide deep-dive documentation. Use them by phase instead of treating them as an unsorted reference list.
|
||||
## Architecture skills (loaded on demand)
|
||||
|
||||
#### 1. Project start and solution design
|
||||
Use these tables as the lookup index. Each skill is a deep-dive for its domain.
|
||||
|
||||
| Skill | When to use |
|
||||
| --- | --- |
|
||||
| `tibi-project-setup` | Setting up a new project from scratch |
|
||||
| `website-solution-architecture` | Translating website requirements into a complete solution across content, admin, SSR, and workflows |
|
||||
| `security-hardening-and-token-strategy` | Applying secure token, secret, permission, and hook-capability decisions |
|
||||
### 1. Project start and solution design
|
||||
|
||||
#### 2. Content model and editor UX
|
||||
| Skill | When |
|
||||
|-------|------|
|
||||
| `tibi-project-setup` | Bootstrap a new project from scratch |
|
||||
| `website-solution-architecture` | Translate requirements into collections, blocks, SSR, workflows |
|
||||
| `security-hardening-and-token-strategy` | Token strategy, secrets, hook risk surfaces, CORS |
|
||||
|
||||
| Skill | When to use |
|
||||
| --- | --- |
|
||||
| `content-authoring` | Adding new pages, content blocks, or collections |
|
||||
| `nova-pagebuilder-modeling` | Designing editor-friendly block systems, nested block schemas, and pagebuilder UX |
|
||||
| `nova-navigation-modeling` | Modeling multilingual header/footer/navigation trees with current Nova navigation features |
|
||||
| `admin-ui-config` | Configuring collection admin views, field widgets, layouts |
|
||||
| `media-seo-publishing` | Modeling media, SEO, and publication workflows for website projects |
|
||||
| `permissions-and-editor-workflows` | Designing safe editorial permissions, field rules, and role-aware admin workflows |
|
||||
| `nova-ai-editor-features` | Applying AI and LLM capabilities in editor workflows and media authoring responsibly |
|
||||
### 2. Content model and editor UX
|
||||
|
||||
#### 3. Backend behavior and integrations
|
||||
| Skill | When |
|
||||
|-------|------|
|
||||
| `content-authoring` | Add pages, block types, collections |
|
||||
| `nova-pagebuilder-modeling` | Block schemas, preview, drillDown, dependsOn |
|
||||
| `nova-navigation-modeling` | Header/footer trees, viewHint.navigation, declaredTrees |
|
||||
| `admin-ui-config` | Field widgets, sidebar, layout, choices, foreign refs |
|
||||
| `media-seo-publishing` | Image fields, alt/caption, SEO, publication model |
|
||||
| `permissions-and-editor-workflows` | Field-level readonly/hidden, 3-layer cascade, custom roles |
|
||||
| `nova-ai-editor-features` | AI-assisted alt text, LLM actions, token budgets |
|
||||
|
||||
| Skill | When to use |
|
||||
| --- | --- |
|
||||
| `tibi-hook-authoring` | Writing or debugging server-side hooks |
|
||||
| `tibi-actions-and-forms` | Building contact forms, workflow endpoints, and other action-based website features |
|
||||
| `scheduled-jobs-and-automation` | Building cron-based background tasks, cleanups, reports, and sync workflows |
|
||||
| `realtime-and-live-workflows` | Designing SSE-based live updates, notifications, previews, and status workflows |
|
||||
### 3. Backend behavior
|
||||
|
||||
#### 4. Frontend runtime and delivery
|
||||
| Skill | When |
|
||||
|-------|------|
|
||||
| `tibi-hook-authoring` | Write/debug server-side hooks (goja) |
|
||||
| `tibi-actions-and-forms` | Contact forms, newsletter, webhooks, action endpoints |
|
||||
| `scheduled-jobs-and-automation` | Cron tasks, cleanup, reports, sync |
|
||||
| `realtime-and-live-workflows` | SSE channels, live notifications, preview refresh |
|
||||
|
||||
| Skill | When to use |
|
||||
| --- | --- |
|
||||
| `frontend-architecture` | Routing, state management, Svelte 5 patterns, API layer, error handling |
|
||||
| `tibi-ssr-caching` | SSR rendering and cache invalidation |
|
||||
| `playwright-testing` | Extending or debugging seeded Playwright API, desktop, mobile, or visual tests |
|
||||
### 4. Frontend and delivery
|
||||
|
||||
### Quickstart roadmap for a new website
|
||||
|
||||
Use this order when building a project from scratch on this starter:
|
||||
|
||||
1. Foundation.
|
||||
Start with `tibi-project-setup` until Docker, URLs, build, and validate are green.
|
||||
|
||||
2. Solution design.
|
||||
Use `website-solution-architecture` first, then `security-hardening-and-token-strategy`, before writing components or hooks.
|
||||
|
||||
3. Content and admin model.
|
||||
Use the skills from **Content model and editor UX** to shape `api/collections/content.yml`, `api/collections/navigation.yml`, reusable domain collections, and Nova authoring UX.
|
||||
|
||||
4. Frontend and runtime.
|
||||
Use `frontend-architecture` plus `nova-pagebuilder-modeling` when wiring routing, i18n, content loading, `frontend/src/blocks/BlockRenderer.svelte`, and shared types.
|
||||
|
||||
5. Backend behavior.
|
||||
Use the skills from **Backend behavior and integrations** for hooks, forms/actions, jobs, and realtime only where the project actually needs them.
|
||||
|
||||
6. SSR and publishing.
|
||||
Use `tibi-ssr-caching` once routes, navigation, and page-critical data are defined, and use `media-seo-publishing` plus `permissions-and-editor-workflows` where publication, SEO, and editorial restrictions matter.
|
||||
|
||||
7. Optional AI editor features.
|
||||
Use `nova-ai-editor-features` only when there is a concrete editorial workflow for it.
|
||||
|
||||
8. Final verification.
|
||||
Use `playwright-testing` for deterministic API/E2E coverage, confirm public site, admin authoring, pagebuilder rendering, navigation/media resolution, forms/actions, and SSR all work, then run `yarn build`, `yarn build:server`, and `yarn validate`.
|
||||
|
||||
For one-off tasks, use the phase tables above as the lookup index instead of maintaining a second skill matrix here.
|
||||
|
||||
### Tailwind CSS 4 canonical classes
|
||||
|
||||
This project uses Tailwind CSS 4. Always use the canonical v4 syntax:
|
||||
|
||||
| Legacy (v3) | Canonical (v4) |
|
||||
| ---------------------- | ---------------------- |
|
||||
| `bg-gradient-to-*` | `bg-linear-to-*` |
|
||||
| `aspect-[4/3]` | `aspect-4/3` |
|
||||
| `!bg-brand-600` | `bg-brand-600!` |
|
||||
| `hover:!bg-brand-700` | `hover:bg-brand-700!` |
|
||||
| `!rounded-xl` | `rounded-xl!` |
|
||||
|
||||
Rules:
|
||||
|
||||
- Gradient directions use `bg-linear-to-{direction}` instead of `bg-gradient-to-{direction}`.
|
||||
- Bare-ratio aspect values like `aspect-4/3` replace arbitrary `aspect-[4/3]`.
|
||||
- The `!important` modifier is a **suffix** (`class!`) instead of a **prefix** (`!class`).
|
||||
| Skill | When |
|
||||
|-------|------|
|
||||
| `frontend-architecture` | SPA router, stores, Svelte 5 patterns, API layer |
|
||||
| `tibi-ssr-caching` | SSR rendering, cache invalidation, 404 signaling |
|
||||
| `playwright-testing` | Deterministic seed data, API/E2E/admin/visual tests |
|
||||
|
||||
Reference in New Issue
Block a user