Skip to content

Commit 3463877

Browse files
author
Sebastian BURGIN-FIX (ext)
committed
wip
1 parent ba2a061 commit 3463877

2 files changed

Lines changed: 87 additions & 258 deletions

File tree

README.md

Lines changed: 85 additions & 258 deletions
Original file line numberDiff line numberDiff line change
@@ -1,306 +1,133 @@
11
<p align="center">
2-
<a href="https://github.com/codebar-ag/laravel-template.git" target="_blank">
3-
<img src="https://banners.beyondco.de/Laravel%20Template.png?theme=dark&pattern=architect&style=style_1&description=codebar+Solutions+AG&md=1&showWatermark=0&fontSize=100px&images=https%3A%2F%2Flaravel.com%2Fimg%2Flogomark.min.svg" alt="Laravel Logo">
4-
</a>
2+
<img src="public/images/logos/codebar-logo-colored.svg" alt="codebar Solutions AG" width="260">
53
</p>
64

7-
## About Laravel Template
5+
<h1 align="center">www.codebar.ch</h1>
86

9-
Laravel Template is a project template for all Codebar Solutions AG Laravel applications.
10-
It is a starting point for new Laravel projects.
11-
It includes a basic setup for a Laravel application with some common packages and configurations.:
12-
13-
- Auth
14-
- Support for Microsoft Office 365 Authentication
15-
- Enums
16-
- [Laravel Nova](https://nova.laravel.com).
17-
- [Flysystem Cloudinary](https://github.com/codebar-ag/laravel-flysystem-cloudinary).
18-
- [Flysystem Cloudinary Nova](https://github.com/codebar-ag/laravel-flysystem-cloudinary-nova).
19-
- [Spatie Activity Log](https://github.com/spatie/laravel-activitylog).
20-
- [Spatie Health](https://github.com/spatie/laravel-health).
21-
- [Spatie Permission](https://github.com/spatie/laravel-permission).
22-
23-
## Installation
24-
25-
You can use this template by clicking on the `Use this template` button on the top of this github repository page.
26-
27-
**INSERT IMAGE HERE* *
28-
29-
Once you have created a new repository from this template, you can clone it to your local machine and install the dependencies:
30-
31-
```bash
32-
composer install
33-
34-
cp .env.example .env
35-
cp vite.config-example.js vite.config.js
36-
37-
php artisan key:generate
7+
<p align="center">
8+
The public marketing website of <a href="https://www.codebar.ch">codebar Solutions AG</a> — a small software company based in the Basel region, Switzerland. Laravel, Blade and Tailwind, bilingual (DE/EN), content managed as version-controlled files rather than through an admin panel.
9+
</p>
3810

39-
php artisan migrate --seed
11+
## Contents
4012

41-
npm install
42-
npm run build
43-
```
13+
- [Content architecture](#content-architecture)
14+
- [Localization](#localization)
15+
- [SEO](#seo)
16+
- [LLM usage analytics](#llm-usage-analytics)
17+
- [Local development](#local-development)
18+
- [Testing & code quality](#testing--code-quality)
19+
- [Deployment](#deployment-laravel-cloud)
20+
- [Key packages](#key-packages)
4421

45-
If you want to use Valet to serve your application, you can run the following command:
22+
## Content architecture
4623

47-
```bash
48-
valet link
49-
50-
valet secure
24+
Almost everything editorial — pages, news articles, team members, services, products, technologies, network partners, the AI model catalogue — lives as YAML or Markdown files under `database/files/`, not as data entered through a CMS. The files are the source of truth; the database is a rebuildable cache of them.
5125

52-
valet open
5326
```
54-
55-
If you want to user Herd to serve your application, you can run the following command:
56-
57-
```bash
58-
herd link
59-
60-
herd secure
61-
62-
herd open
27+
database/files/
28+
├── ai_models/ one YAML file per model
29+
├── networks/ one YAML file per partner
30+
├── news/{locale}/ one Markdown file per article, per language
31+
├── pages/ one YAML file per page (SEO metadata: title, description, robots, image)
32+
├── products/{locale}/
33+
├── services/{locale}/
34+
├── team/ one YAML file per person
35+
└── technologies/{locale}/
6336
```
6437

65-
You can run the development asset server with the following command:
38+
Each content type has a matching import command that reads its files and upserts the database, and is safe to run repeatedly:
6639

67-
```bash
68-
npm run dev
69-
````
40+
| Command | Reads |
41+
|---|---|
42+
| `php artisan pages:import` | `database/files/pages/*.yaml` |
43+
| `php artisan news:import` | `database/files/news/{locale}/*.md` |
44+
| `php artisan team:import` | `database/files/team/*.yaml` |
45+
| `php artisan services:import` | `database/files/services/{locale}/*.md` |
46+
| `php artisan products:import` | `database/files/products/{locale}/*.md` |
47+
| `php artisan technologies:import` | `database/files/technologies/{locale}/*.md` |
48+
| `php artisan networks:import` | `database/files/networks/*.yaml` |
49+
| `php artisan ai-models:import` | `database/files/ai_models/*.yaml` |
50+
| `php artisan sync:repositories` | live GitHub repositories (open-source content) |
7051

71-
> Note: You should set `valetTls: 'your-domain.test',` below `refresh: true,` in your `vite.config.js` file if you use `valet secure` or `herd secure`.
52+
`database/seeders/DatabaseSeeder.php` calls every one of these on `db:seed` — including in production. That is intentional: these seeders don't generate test fixtures, they publish the real content the same way running the command by hand would. The one exception is `AiModelDailyUsagesTableSeeder`, which loads a static local-dev fixture rather than real usage data (see [LLM usage analytics](#llm-usage-analytics)).
7253

73-
## Assets
54+
A file that disappears from `database/files/` removes the matching row on the next import — the importers are the single source of truth in both directions.
7455

75-
Assets should be set in the following directories:
56+
## Localization
7657

77-
- `resources/js` for JavaScript files.
78-
- `resources/css` for CSS files.
79-
- `resources/fonts` for Font files.
80-
- `resources/images` for Image files.
58+
The site ships in German (`de_CH`) and English (`en_CH`) under distinct, fully translated URL prefixes rather than a shared `/en/…` segment — e.g. `/dienstleistungen` and `/services`, `/aktuelles` and `/news`, `/ueber-uns` and `/about-us`. Every localized route pair cross-references the other via `hreflang`, including on detail pages where the slug itself is translated (`routes/web.php`, `resources/views/layouts/_partials/_seo.blade.php`).
8159

82-
After you have added your assets, you can run the following command to compile them:
83-
```bash
84-
npm run build
85-
```
60+
## SEO
8661

87-
To include your assets in your blade files, you can use the following:
62+
- **Structured data** — a single `@graph` JSON-LD payload (`App\Seo\SchemaGraph` / `App\Seo\SchemaNodes`) built from `config/company.php`, the one source of truth for the company's name, addresses, phone and `sameAs` profiles. Every page ships `Organization`, `WebSite`, `WebPage` and `BreadcrumbList` nodes; content pages add `Service`, `Person`, `BlogPosting`, etc.
63+
- **Sitemap**`App\Sitemap\SitemapBuilder` + `App\Http\Controllers\Sitemap\SitemapController` build `/sitemap.xml` from the same models the site renders, cached 24h via `Cache::remember`.
64+
- **Response cache**`spatie/laravel-responsecache` caches full HTTP responses for up to 7 days. `App\Observers\SitemapCacheObserver` drops the sitemap's own data cache on every relevant model save, and `responsecache:clear` runs hourly via the scheduler (`routes/console.php`) as a backstop for the full-page cache layer — these are two independent caches and both need clearing after a bulk content change (`php artisan responsecache:clear` after a fresh `db:seed`, for instance).
65+
- **Social images** — article heroes that are local SVG placeholders (no real photography yet) are not usable as `og:image` — social crawlers don't render SVG. `App\Support\NewsImage::ogImage()` falls back to a same-named `.png` rendered from the SVG when one exists, or the site's default share image otherwise.
66+
- **Tests**`tests/Feature/Seo/` asserts on the actual rendered JSON-LD and meta tags (not just "does it look right"), and `tests/lighthouse/` audits real Lighthouse scores against the built (`npm run build`) output, not the Vite dev server.
8867

89-
```blade
90-
{{ Vite::asset('resources/images/your-image.png') }}
91-
```
68+
## LLM usage analytics
9269

93-
## Auth
70+
`/ki` (`/ai`) publishes aggregate usage figures for the AI models codebar runs internally via a self-hosted [LiteLLM](https://www.litellm.ai/) proxy. `php artisan llm:fetch-analytics` pulls per-day usage from the proxy's `/spend/logs` endpoint and stores it in `ai_model_daily_usages`; it's scheduled hourly but only backfills the last 3 days by default — use `--full` (syncs from 2026-01-01) or `--from`/`--to` to backfill a specific range. Spend figures are stored but must never be displayed publicly. The dashboard intentionally shows monthly/yearly aggregates only, never a daily breakdown.
9471

95-
Auth is enabled by default.
72+
## Local development
9673

97-
You can configure auth settings in the `config/laravel-auth.php` file.
74+
```bash
75+
composer install
76+
cp .env.example .env
77+
php artisan key:generate
9878

99-
### 🔐 Verify
100-
If you wish to use email verification, you can use the following middleware to protect your routes:
79+
php artisan migrate --seed # imports real content — see "Content architecture" above
10180

102-
```php
103-
Route::middleware(['laravel-auth-middleware'])->group(function () {
104-
...
105-
});
106-
```
107-
To use verification in nova, add the middleware into in your `nova.php` config:
108-
109-
```php
110-
/*
111-
|--------------------------------------------------------------------------
112-
| Nova Route Middleware
113-
|--------------------------------------------------------------------------
114-
|
115-
| These middleware will be assigned to every Nova route, giving you the
116-
| chance to add your own middleware to this stack or override any of
117-
| the existing middleware. Or, you can just stick with this stack.
118-
|
119-
*/
120-
121-
'middleware' => [
122-
'web',
123-
'laravel-auth-middleware',
124-
HandleInertiaRequests::class,
125-
DispatchServingNovaEvent::class,
126-
BootTools::class,
127-
],
81+
npm install
82+
npm run build # or `npm run dev` for the Vite dev server
12883
```
12984

130-
### Microsoft Office 365 Authentication
131-
132-
⚠️ When using Office 365 you need to provide a publicly accessible URL for the `MICROSOFT_REDIRECT_URI` environment variable. You can use [expose](https://expose.dev/) or [ngrok](https://ngrok.com/) for local development.
133-
134-
```bash
135-
APP_URL=https://your-expose-or-ngrok-url.com
85+
If you use [Herd](https://herd.laravel.com):
13686

137-
# ✅ This is recommended for production as well:
138-
MICROSOFT_REDIRECT_URI="${APP_URL}/auth/service/microsoft/redirect"
87+
```bash
88+
herd link
89+
herd secure
90+
herd open
13991
```
14092

141-
## Permissions
142-
143-
Please refer to the [Spatie Permission](https://github.com/spatie/laravel-permission) documentation for more information on how to use permissions.
144-
145-
## Enums
146-
147-
Enums are included in PHP's core functionality but we have some additional functionality to make them easier to use.
148-
149-
You can create an enum in the `app/Enums` directory:
150-
151-
```php
152-
<?php
153-
154-
namespace App\Enums;
155-
156-
use App\Interfaces\LabelEnumInterface;use App\Traits\HasLabels;
157-
158-
enum EnvironmentEnum: string implements LabelEnumInterface
159-
{
160-
use HasLabels;
161-
162-
case PRODUCTION = 'production';
163-
case STAGING = 'staging';
164-
case LOCAL = 'local';
93+
If you use [Valet](https://laravel.com/docs/valet):
16594

166-
public function label(): string
167-
{
168-
return match ($this) {
169-
EnvironmentEnum::PRODUCTION => __('Production'),
170-
EnvironmentEnum::STAGING => __('Staging'),
171-
EnvironmentEnum::LOCAL => __('Local'),
172-
};
173-
}
174-
}
95+
```bash
96+
valet link
97+
valet secure
98+
valet open
17599
```
176100

177-
You should use the `HasLabels` trait to add a `label` method to your enum.
178-
You should also implement the `LabelEnumInterface` interface to ensure that the `label` method is implemented.
179-
180-
The `label` method should return the label for the enum value.
181-
182-
You can use the enum in your code like this:
183-
184-
```php
185-
// Native PHP Enum
186-
$enum = EnvironmentEnum::PRODUCTION; // Enum Object
187-
$name = EnvironmentEnum::PRODUCTION->name; // Enum Name (PRODUCTION)
188-
$value = EnvironmentEnum::PRODUCTION->value; // Enum Value (production)
101+
> Set `valetTls: 'your-domain.test'` below `refresh: true` in `vite.config.js` if you use `valet secure` / `herd secure`.
189102
190-
// Label
191-
$label = EnvironmentEnum::PRODUCTION->label(); // Enum Label using Laravels Translation (Production)
103+
## Testing & code quality
192104

193-
// Labels
194-
$labels = EnvironmentEnum::labels(); // Array of Enum Labels with Enum value as Key (['production' => 'Production', 'staging' => 'Staging', 'local' => 'Local'])
105+
```bash
106+
./vendor/bin/pest # test suite (Pest)
107+
./vendor/bin/phpstan analyse # static analysis (Larastan, see phpstan.neon.dist)
108+
./vendor/bin/pint # code style
109+
./vendor/bin/pint --blade # blade formatting (beta)
195110
```
196111

197-
## Health
198-
199-
Please refer to the [Spatie Health](https://github.com/spatie/laravel-health) documentation for more information on how to use health checks.
200-
201-
We have added two health checks which are located in the `app/Checks` directory:
202-
203-
- `FailedJobsCheck`
204-
- `JobsCheck`
205-
206-
## Helpers
207-
208-
We have added some helper functions which are located in the `app/Helpers` directory
209-
210-
You should the Facades for the helpers which are located in the `app/Helpers/Facades` directory:
211-
212-
- `HelperBank`
213-
- `HelperDate`
214-
- `HelperDevice`
215-
- `HelperFile`
216-
- `HelperMarkdown`
217-
- `HelperMoney`
218-
- `HelperNumber`
219-
- `HelperPhone`
220-
221-
## Feature Policy
222-
223-
We have added feature policy which is located in the `app/FeaturePolicy` directory.
224-
225-
It is enabled by default and you can configure it in the `config/feature-policy.php` and `config/default.php` file.
226-
227-
The Feature Policy Middleware is installed and enabled by default in the `bootstrap/app.php` file.
228-
229-
## Traits
230-
231-
We have added some traits which are located in the `app/Traits` directory.
232-
233-
- `HassUuid`
234-
235-
We also have some traits which are located in the `app/Traits/Nova` directory which are intended for use only in Laravel Nova.
236-
237-
- `NovaCustomOrderTrait`
238-
- `NovaIdentificationPanelTrait`
239-
- `NovaLanguageTrait`
240-
- `NovaTimestampsPanelTrait`
241-
242-
## Blade Components
243-
244-
We have added some blade components which are located in the `resources/views/components` directory.
112+
## Deployment (Laravel Cloud)
245113

246-
- `fathom.blade.php`
247-
- `favicons.blade.php`
248-
249-
You should include both the blade components in your blade layout files
250-
251-
## Laravel Cloud deployment
252-
253-
When deploying to Laravel Cloud, ensure these environment variables are set for Lighthouse Best Practices (security headers):
114+
The site runs on [Laravel Cloud](https://cloud.laravel.com), behind Cloudflare. Required environment variables for security headers:
254115

255116
- `CSP_ENABLED=true` — enables Content-Security-Policy enforcement via Spatie CSP middleware
256117
- `FPH_ENABLED=true` — enables Permissions-Policy headers
257118

258-
Security headers (HSTS, COOP, `X-Content-Type-Options`, `Referrer-Policy`, `X-Frame-Options`) are applied automatically by `SecurityHeaders` middleware on all web responses.
259-
260-
**Lighthouse note:** Deprecated API warnings for `/cdn-cgi/challenge-platform/scripts/jsd/main.js` come from Cloudflare bot protection injected by Laravel Cloud, not from application code. Run Lighthouse in incognito without browser extensions for accurate scores.
261-
262-
## Cloudinary
263-
264-
Please refer to the respective documentation for the Cloudinary and Cloudinary Nova packages.
265-
266-
- [Flysystem Cloudinary](https://github.com/codebar-ag/laravel-flysystem-cloudinary).
267-
- [Flysystem Cloudinary Nova](https://github.com/codebar-ag/laravel-flysystem-cloudinary-nova).
119+
HSTS, COOP, `X-Content-Type-Options`, `Referrer-Policy` and `X-Frame-Options` are applied automatically by the `SecurityHeaders` middleware on every web response.
268120

269-
## Notifications
121+
**Lighthouse note:** deprecated-API warnings for `/cdn-cgi/challenge-platform/scripts/jsd/main.js` come from Cloudflare's bot protection, injected at the edge — not from application code. Run Lighthouse in incognito without extensions for an accurate score, and prefer `tests/lighthouse/` (which audits the built output) over ad-hoc runs against the dev server.
270122

271-
We use Filament for notifications. Please refer to the [Filament](https://filamentphp.com/docs/3.x/notifications/sending-notifications) documentation for more information on how to use notifications.
272-
273-
## Pint
274-
275-
We use Laravel Pint to format code.
276-
277-
You can run the following command to format your code:
278-
279-
```bash
280-
./vendor/bin/pint
281-
```
282-
283-
You can run the following command to format your blade files:
284-
285-
```bash
286-
./vendor/bin/pint --blade
287-
```
288-
289-
> The blade formatter is still in beta and may not work as expected. if you wish to not use this update your `composer.json` to use the latest version of `laravel/pint` instead of the dev branch.
290-
291-
292-
## Testing
293-
294-
We use PestPHP for testing.
295-
296-
You can run the following command to run your tests:
297-
298-
```bash
299-
./vendor/bin/pest
300-
```
123+
## Key packages
301124

302-
Please refer to the [PestPHP](https://pestphp.com) documentation for more information on how to use PestPHP.
125+
- **Content & storage**`spatie/laravel-translatable`, `codebar-ag/laravel-flysystem-cloudinary` (editorial images), `league/flysystem-aws-s3-v3` (DigitalOcean Spaces for other assets), `symfony/yaml`
126+
- **SEO**`spatie/laravel-sitemap`, `spatie/laravel-responsecache`
127+
- **Security & health**`spatie/laravel-csp`, `spatie/laravel-honeypot`, `spatie/laravel-permission`, `spatie/laravel-health`, `spatie/security-advisories-health-check`, `mazedlx/laravel-feature-policy`
128+
- **Ops**`laravel/nightwatch` (observability), `symfony/postmark-mailer`
129+
- **Analytics**[Fathom](https://usefathom.com) (privacy-friendly, no cookie banner)
303130

304131
## License
305132

306-
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
133+
The application code is proprietary to codebar Solutions AG. The underlying Laravel framework is open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT).

0 commit comments

Comments
 (0)